Class: Pebble::Watch

Inherits:
Object
  • Object
show all
Defined in:
lib/pebble/watch.rb,
lib/pebble/watch/event.rb,
lib/pebble/watch/log_event.rb,
lib/pebble/watch/app_message_event.rb,
lib/pebble/watch/media_control_event.rb,
lib/pebble/watch/system_message_event.rb

Defined Under Namespace

Modules: Errors Classes: AppMessageEvent, Event, LogEvent, MediaControlEvent, SystemMessageEvent

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, port) ⇒ Watch

Returns a new instance of Watch.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/pebble/watch.rb', line 42

def initialize(id, port)
  @id = id

  @protocol       = Protocol.new(port)
  @event_handlers = Hash.new { |hash, key| hash[key] = [] }

  # We're mirroring Android here.
  @session_capabilities = Capabilities::Session::GAMMA_RAY
  @client_capabilities  = Capabilities::Client::TELEPHONY | Capabilities::Client::SMS | Capabilities::Client::ANDROID

  answer_phone_version_message
  receive_event_messages
  log_log_events
end

Instance Attribute Details

#client_capabilitiesObject

Returns the value of attribute client_capabilities.



40
41
42
# File 'lib/pebble/watch.rb', line 40

def client_capabilities
  @client_capabilities
end

#event_handlersObject (readonly)

Returns the value of attribute event_handlers.



38
39
40
# File 'lib/pebble/watch.rb', line 38

def event_handlers
  @event_handlers
end

#idObject (readonly)

Returns the value of attribute id.



36
37
38
# File 'lib/pebble/watch.rb', line 36

def id
  @id
end

#protocolObject (readonly)

Returns the value of attribute protocol.



37
38
39
# File 'lib/pebble/watch.rb', line 37

def protocol
  @protocol
end

#session_capabilitiesObject

Returns the value of attribute session_capabilities.



39
40
41
# File 'lib/pebble/watch.rb', line 39

def session_capabilities
  @session_capabilities
end

Class Method Details

.autodetectObject



9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/pebble/watch.rb', line 9

def self.autodetect
  return nil unless RUBY_PLATFORM =~ /darwin/

  watches = Dir.glob("/dev/tty.Pebble????-SerialPortSe")

  raise Errors::NoWatchesFound if watches.length == 0
  Pebble.logger.debug "Found multiple watches: #{watches}" if watches.length > 1

  port = watches.first
  id = port[15, 4]
  Pebble.logger.debug "Detected watch with ID #{id}"

  return new(id, port)
end

.open(id, port) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/pebble/watch.rb', line 24

def self.open(id, port)
  watch = new(id, port)

  begin
    watch.connect
    yield watch
  ensure
    watch.disconnect
  end
  nil
end

Instance Method Details

#connectObject



57
58
59
# File 'lib/pebble/watch.rb', line 57

def connect
  @protocol.connect
end

#disconnectObject



61
62
63
# File 'lib/pebble/watch.rb', line 61

def disconnect
  @protocol.disconnect
end

#get_installed_apps(&async_response_handler) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/pebble/watch.rb', line 137

def get_installed_apps(&async_response_handler)
  @protocol.send_message(Endpoints::APP_INSTALL_MANAGER, "\x01", async_response_handler) do |message|
    response = {}

    response[:banks_count], apps_count = message[1, 8].unpack("L>L>")
    response[:apps] = []

    size = 78
    apps_count.times do |index|
      offset = index * size + 9

      app = {}

      app[:id], app[:index], app[:name], app[:author], app[:flags], app[:version] = 
        message[offset, size].unpack("L>L>A32A32L>S>")

      response[:apps] << app
    end

    response
  end
end

#get_time(&async_response_handler) ⇒ Object



166
167
168
169
170
171
# File 'lib/pebble/watch.rb', line 166

def get_time(&async_response_handler)
  @protocol.send_message(Endpoints::TIME, "\x00", async_response_handler) do |message|
    restype, timestamp = message.unpack("CL>")
    Time.at(timestamp)
  end
end

#get_versions(&async_response_handler) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/pebble/watch.rb', line 107

def get_versions(&async_response_handler)
  @protocol.send_message(Endpoints::VERSION, "\x00", async_response_handler) do |message|
    response = {}

    response[:firmwares] = {}

    size = 47
    [:normal, :recovery].each_with_index do |type, index|
      offset = index * size + 1

      fw = {}

      fw[:timestamp], fw[:version], fw[:commit], fw[:is_recovery], 
        fw[:hardware_platform], fw[:metadata_version] =
        message[offset, size].unpack("L>A32A8ccc")

      fw[:is_recovery] = (fw[:is_recovery] == 1)

      response[:firmwares][type] = fw
    end

    response[:bootloader_timestamp], response[:hardware_version], response[:serial] =
      message[95, 25].unpack("L>A9A12")

    response[:btmac] = message[120, 6].unpack("H*").first.scan(/../).reverse.map { |c| c.upcase }.join(":")

    response
  end
end

#listen_for_events(sync = true) ⇒ Object



65
66
67
# File 'lib/pebble/watch.rb', line 65

def listen_for_events(sync=true)
  @protocol.listen_for_messages(sync)
end

#notification_email(sender, subject, body) ⇒ Object



96
97
98
# File 'lib/pebble/watch.rb', line 96

def notification_email(sender, subject, body)
  notification(:email, sender, body, subject)
end

#notification_sms(sender, body) ⇒ Object



92
93
94
# File 'lib/pebble/watch.rb', line 92

def notification_sms(sender, body)
  notification(:sms, sender, body)
end

#on_event(event = :any, &handler) ⇒ Object



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

def on_event(event = :any, &handler)
  Pebble.logger.info "adding handler for #{event}"
  @event_handlers[event] << handler
  handler
end

#ping(cookie = 0xDEADBEEF, &async_response_handler) ⇒ Object



83
84
85
86
87
88
89
90
# File 'lib/pebble/watch.rb', line 83

def ping(cookie = 0xDEADBEEF, &async_response_handler)
  message = [0, cookie].pack("CL>")

  @protocol.send_message(Endpoints::PING, message, async_response_handler) do |message|
    restype, cookie = message.unpack("CL>")
    cookie
  end
end

#remove_app(app_id, app_index) ⇒ Object



160
161
162
163
164
# File 'lib/pebble/watch.rb', line 160

def remove_app(app_id, app_index)
  message = [2, app_id, app_index].pack("cL>L>")

  @protocol.send_message(Endpoints::APP_INSTALL_MANAGER, message)
end

#resetObject



188
189
190
# File 'lib/pebble/watch.rb', line 188

def reset
  @protocol.send_message(Endpoints::RESET, "\x00")
end

#set_nowplaying_metadata(artist, album, track) ⇒ Object



100
101
102
103
104
105
# File 'lib/pebble/watch.rb', line 100

def (artist, album, track)
  message = [16].pack("C")
  message << package_strings(artist, album, track, 30)

  @protocol.send_message(Endpoints::MUSIC_CONTROL, message)
end

#set_time(time) ⇒ Object



173
174
175
176
177
178
# File 'lib/pebble/watch.rb', line 173

def set_time(time)
  timestamp = time.to_i
  message = [2, timestamp].pack("CL>")

  @protocol.send_message(Endpoints::TIME, message)
end

#stop_listening(*params) ⇒ Object



75
76
77
78
79
80
# File 'lib/pebble/watch.rb', line 75

def stop_listening(*params)
  handler = params.pop
  event   = params.pop || :any

  @event_handlers[event].delete(handler)
end

#system_message(code) ⇒ Object



180
181
182
183
184
185
186
# File 'lib/pebble/watch.rb', line 180

def system_message(code)
  Pebble.logger.debug "Sending system message #{SystemMessages.for_code(code)}"

  message = [code].pack("S>")

  @protocol.send_message(Endpoints::SYSTEM_MESSAGE, message)
end