class Pebble::Watch
Attributes
client_capabilities[RW]
event_handlers[R]
id[R]
protocol[R]
session_capabilities[RW]
Public Class Methods
autodetect()
click to toggle source
# 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
new(id, port)
click to toggle source
# 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
open(id, port) { |watch| ... }
click to toggle source
# 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
Public Instance Methods
connect()
click to toggle source
# File lib/pebble/watch.rb, line 57 def connect @protocol.connect end
disconnect()
click to toggle source
# File lib/pebble/watch.rb, line 61 def disconnect @protocol.disconnect end
get_installed_apps(&async_response_handler)
click to toggle source
# File lib/pebble/watch.rb, line 136 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)
click to toggle source
# File lib/pebble/watch.rb, line 165 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)
click to toggle source
# File lib/pebble/watch.rb, line 106 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()
click to toggle source
# File lib/pebble/watch.rb, line 65 def listen_for_events @protocol.listen_for_messages end
notification_email(sender, subject, body)
click to toggle source
# File lib/pebble/watch.rb, line 95 def notification_email(sender, subject, body) notification(:email, sender, body, subject) end
notification_sms(sender, body)
click to toggle source
# File lib/pebble/watch.rb, line 91 def notification_sms(sender, body) notification(:sms, sender, body) end
on_event(event = :any, &handler)
click to toggle source
# File lib/pebble/watch.rb, line 69 def on_event(event = :any, &handler) @event_handlers[event] << handler handler end
ping(cookie = 0xDEADBEEF, &async_response_handler)
click to toggle source
# File lib/pebble/watch.rb, line 82 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)
click to toggle source
# File lib/pebble/watch.rb, line 159 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
reset()
click to toggle source
# File lib/pebble/watch.rb, line 187 def reset @protocol.send_message(Endpoints::RESET, "\x00") end
set_nowplaying_metadata(artist, album, track)
click to toggle source
# File lib/pebble/watch.rb, line 99 def set_nowplaying_metadata(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)
click to toggle source
# File lib/pebble/watch.rb, line 172 def set_time(time) timestamp = time.to_i message = [2, timestamp].pack("CL>") @protocol.send_message(Endpoints::TIME, message) end
stop_listening(*params)
click to toggle source
# File lib/pebble/watch.rb, line 74 def stop_listening(*params) handler = params.pop event = params.pop || :any @event_handlers[event].delete(handler) end
system_message(code)
click to toggle source
# File lib/pebble/watch.rb, line 179 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
Private Instance Methods
answer_phone_version_message()
click to toggle source
# File lib/pebble/watch.rb, line 192 def answer_phone_version_message @protocol.on_receive(Endpoints::PHONE_VERSION) do |message| response_message = [1, -1].pack("Cl>") response_message << [@session_capabilities, @client_capabilities].pack("L>L>") @protocol.send_message(Endpoints::PHONE_VERSION, response_message) end end
log_log_events()
click to toggle source
# File lib/pebble/watch.rb, line 216 def log_log_events on_event(:log) do |event| case event.level when :error Pebble.logger.error event.message when :warning Pebble.logger.warn event.message when :info Pebble.logger.info event.message when :debug, :verbose Pebble.logger.debug event.message else Pebble.logger.info event.message end end end
notification(type, *params)
click to toggle source
# File lib/pebble/watch.rb, line 249 def notification(type, *params) types = { email: 0, sms: 1 } timestamp = Time.now.to_i params.insert(2, timestamp.to_s) message = [types[type]].pack("C") message << package_strings(*params) @protocol.send_message(Endpoints::NOTIFICATION, message) end
package_strings(*parts)
click to toggle source
# File lib/pebble/watch.rb, line 264 def package_strings(*parts) max_part_length = 255 max_part_length = parts.pop if parts.last.is_a?(Integer) message = "" parts.each do |part| part ||= "" part = part[0, max_part_length] if part.length > max_part_length message << [part.length].pack("C") + part end message end
receive_event_messages()
click to toggle source
# File lib/pebble/watch.rb, line 201 def receive_event_messages events = [ [:log, Endpoints::LOGS, LogEvent], [:system_message, Endpoints::SYSTEM_MESSAGE, SystemMessageEvent], [:media_control, Endpoints::MUSIC_CONTROL, MediaControlEvent] ] events.each do |(name, endpoint, event_klass)| @protocol.on_receive(endpoint) do |message| event = event_klass.parse(message) trigger_event(name, event) if event end end end
trigger_event(name, event)
click to toggle source
# File lib/pebble/watch.rb, line 233 def trigger_event(name, event) Pebble.logger.debug "Triggering event '#{name}': #{event.inspect}" @event_handlers[:any].each do |handler| Thread.new(handler) do |handler| handler.call(name, event) end end @event_handlers[name].each do |handler| Thread.new(handler) do |handler| handler.call(event) end end end