Class: Pebble::Protocol

Inherits:
Object
  • Object
show all
Defined in:
lib/pebble/protocol.rb

Defined Under Namespace

Modules: Errors

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(port) ⇒ Protocol

Returns a new instance of Protocol.



26
27
28
29
30
31
32
# 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

Instance Attribute Details

#connectedObject (readonly)

Returns the value of attribute connected.



11
12
13
# File 'lib/pebble/protocol.rb', line 11

def connected
  @connected
end

#message_handlersObject (readonly)

Returns the value of attribute message_handlers.



12
13
14
# File 'lib/pebble/protocol.rb', line 12

def message_handlers
  @message_handlers
end

Class Method Details

.open(port) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
# 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

Instance Method Details

#connectObject



34
35
36
37
38
39
40
41
42
43
44
# 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

#disconnectObject

Raises:



46
47
48
49
50
51
52
53
54
55
# 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_messagesObject

Raises:



57
58
59
60
61
# 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) ⇒ Object



63
64
65
66
# 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) ⇒ Object

Raises:



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# 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) ⇒ Object



68
69
70
71
72
73
# File 'lib/pebble/protocol.rb', line 68

def stop_receiving(*params)
  handler   = params.pop
  endpoint  = params.pop || :any

  @message_handlers[endpoint].delete(handler)
end