class Pebble::Protocol
Attributes
connected[R]
message_handlers[R]
Public Class Methods
new(port)
click to toggle source
# File lib/pebble/protocol.rb, line 26 def initialize(port) @port = port @connected = false @send_message_mutex = Mutex.new @message_handlers = Hash.new { |hash, key| hash[key] = [] } end
open(port) { |protocol| ... }
click to toggle source
# File lib/pebble/protocol.rb, line 14 def self.open(port) protocol = new(port) begin protocol.connect yield protocol ensure protocol.disconnect end nil end
Public Instance Methods
connect()
click to toggle source
# File lib/pebble/protocol.rb, line 34 def connect @serial_port = SerialPort.new(@port, baudrate: 115200) @serial_port.read_timeout = 500 @connected = true Pebble.logger.debug "Connected to port #{@port}" @receive_messages_thread = Thread.new(&method(:receive_messages)) true end
disconnect()
click to toggle source
# File lib/pebble/protocol.rb, line 46 def disconnect raise Errors::NotConnected unless @connected @connected = false @serial_port.close() @serial_port = nil true end
listen_for_messages()
click to toggle source
# File lib/pebble/protocol.rb, line 57 def listen_for_messages raise Errors::NotConnected unless @connected @receive_messages_thread.join end
on_receive(endpoint = :any, &handler)
click to toggle source
# File lib/pebble/protocol.rb, line 63 def on_receive(endpoint = :any, &handler) @message_handlers[endpoint] << handler handler end
send_message(endpoint, message, async_response_handler = nil, &response_parser)
click to toggle source
# File lib/pebble/protocol.rb, line 75 def send_message(endpoint, message, async_response_handler = nil, &response_parser) raise Errors::NotConnected unless @connected message ||= "" Pebble.logger.debug "Sending #{Endpoints.for_code(endpoint)}: #{message.inspect}" data = [message.size, endpoint].pack("S>S>") + message @send_message_mutex.synchronize do @serial_port.write data if response_parser if async_response_handler identifier = on_receive(endpoint) do |response_message| stop_receiving(endpoint, identifier) parsed_response = response_parser.call(response_message) async_response_handler.call(parsed_response) end true else received = false parsed_response = nil identifier = on_receive(endpoint) do |response_message| stop_receiving(endpoint, identifier) parsed_response = response_parser.call(response_message) received = true end sleep 0.015 until received parsed_response end else true end end end
stop_receiving(*params)
click to toggle source
# File lib/pebble/protocol.rb, line 68 def stop_receiving(*params) handler = params.pop endpoint = params.pop || :any @message_handlers[endpoint].delete(handler) end
Private Instance Methods
receive_messages()
click to toggle source
# File lib/pebble/protocol.rb, line 119 def receive_messages Pebble.logger.debug "Waiting for messages" while @connected header = @serial_port.read(4) next unless header raise Errors::MalformedResponse if header.length < 4 size, endpoint = header.unpack("S>S>") message = @serial_port.read(size) Pebble.logger.debug "Received #{Endpoints.for_code(endpoint)}: #{message.inspect}" trigger_received(endpoint, message) end rescue IOError => e if @connected Pebble.logger.debug "Lost connection" @connected = false raise Errors::LostConnection end ensure Pebble.logger.debug "Finished waiting for messages" end
trigger_received(endpoint, message)
click to toggle source
# File lib/pebble/protocol.rb, line 144 def trigger_received(endpoint, message) @message_handlers[:any].each do |handler| Thread.new(handler) do |handler| handler.call(endpoint, message) end end @message_handlers[endpoint].each do |handler| Thread.new(handler) do |handler| handler.call(message) end end end