def test_receive_appmessage_string(): pebble = Mock() calls = [0] def handle_result(txid, uuid, result): assert uuid == UUID(int=128) assert txid == 42 assert result == { 14: "hello!", 15: "éclair", # null terminated -> 'foo' should be omitted. 16: "hello\uFFFDworld", # invalid unicode -> U+FFFD REPLACEMENT CHARACTER } calls[0] += 1 service = AppMessageService(pebble) service.register_handler("appmessage", handle_result) assert pebble.register_endpoint.call_args is not None callback = pebble.register_endpoint.call_args[0][1] callback( AppMessage( transaction_id=42, data=AppMessagePush( uuid=UUID(int=128), dictionary=[ AppMessageTuple(key=14, type=AppMessageTuple.Type.CString, data=b"hello!\x00"), AppMessageTuple(key=15, type=AppMessageTuple.Type.CString, data="éclair".encode('utf-8') + b'\x00foo',), AppMessageTuple(key=16, type=AppMessageTuple.Type.CString, data=b"hello\xffworld"), ] ) ) ) pebble.send_packet.assert_called_once_with(AppMessage(transaction_id=42, data=AppMessageACK())) assert calls[0] == 1
class PebbleManager(object): def __init__(self, qemu): self.qemu = qemu.split(":") print self.qemu self.pebble = PebbleConnection(QemuTransport(*self.qemu), log_packet_level=logging.DEBUG) self.handle_start = None self.handle_stop = None self.blobdb = None self.launcher = None def connect(self): self.pebble.connect() greenlet = gevent.spawn(self.pebble.run_sync) self.pebble.fetch_watch_info() self.register_endpoints() self.pebble.transport.send_packet(QemuBluetoothConnection(connected=True), target=MessageTargetQemu()) self.blobdb = BlobDBClient(self.pebble) self.request_running_app() logger.info("connected to %s", self.qemu) return greenlet def disconnect(self): if self.launcher is not None: self.launcher.shutdown() def register_endpoints(self): self.pebble.register_endpoint(AppRunState, self.handle_lifecycle) self.launcher = AppMessageService(self.pebble, message_type=LegacyAppLaunchMessage) self.launcher.register_handler("appmessage", self.handle_launcher) def request_running_app(self): if self.pebble.firmware_version.major >= 3: self.pebble.send_packet(AppRunState(data=AppRunStateRequest())) else: self.launcher.send_message(uuid.UUID(int=0), {LegacyAppLaunchMessage.Keys.StateFetch: Uint8(1)}) def handle_lifecycle(self, packet): if isinstance(packet.data, AppRunStateStart): if callable(self.handle_start): self.handle_start(packet.data.uuid) elif isinstance(packet.data, AppRunStateStop): if callable(self.handle_stop): self.handle_stop(packet.data.uuid) def handle_launcher(self, txid, uuid, message): state = message[LegacyAppLaunchMessage.Keys.RunState] if state == LegacyAppLaunchMessage.States.Running: if callable(self.handle_start): self.handle_start(uuid) elif state == LegacyAppLaunchMessage.States.NotRunning: if callable(self.handle_stop): self.handle_stop(uuid) @property def timeline_is_supported(self): return self.pebble.firmware_version.major >= 3
def __init__(self, qemu, pbws, persist_dir=None, oauth_token=None, layout_file=None, block_private_addresses=False): self.qemu = qemu self.pebble = PebbleManager(qemu) self.persist_dir = persist_dir self.oauth_token = oauth_token self.pebble.handle_start = self.handle_start self.pebble.handle_stop = self.handle_stop # PBL-26034: Due to PBL-24009 we must be sure to respond to appmessages received with no JS running. # However, libpebble2 presently provides no way of NACKing. Making sure this exists is sufficient for # ACKs, so we just create it and pass it off. We should add NACKs later, though. self.appmessage = AppMessageService(self.pebble.pebble) self.pbws = {} self.logger = logging.getLogger("pypkjs") self.running_uuid = None self.js = None self.urls = URLManager() self.timeline = PebbleTimeline(self, persist=persist_dir, oauth=oauth_token, layout_file=layout_file) self.block_private_addresses = block_private_addresses self.load_cached_pbws() self.load_pbws(pbws)
def main(settings): """ Main function for the communicatior, loops here """ if settings.transport == "websocket": pebble = PebbleConnection(WebsocketTransport(settings.device), log_packet_level=logging.DEBUG) else: # No elif, for compatibility with older configs pebble = PebbleConnection(SerialTransport(settings.device), log_packet_level=logging.DEBUG) pebble.connect() # For some reason it seems to timeout for the first time, with "somebody is eating our input" error, # replying seems to help. for loop in range(5): try: pebble.run_async() break except libpebble2.exceptions.TimeoutError: logging.info("Pebble timeouted, retrying..") continue # Register service for app messages appservice = AppMessageService(pebble) handler = CommandHandler(settings) commwatch = CommunicationKeeper(settings, appservice) appservice.register_handler("nack", commwatch.nack_received) appservice.register_handler("ack", commwatch.ack_received) # Start the watchapp pebble.send_packet(AppRunState(command = 0x01, data=AppRunStateStart(uuid = uuid.UUID(settings.uuid)))) # Send our current config for (id_key, id_type) in get_button_ids(): id_full = id_key[0] + "," + id_type[0] if id_full in settings.key_mappings: status = "T" else: status = "F" data = id_key[0] + id_type[0] + status commwatch.send_message({COMMUNICATION_KEY_CONFIG: CString(data)}) # Wait for all for loop in range(10): if len(commwatch.pending) == 0: break if commwatch.error: raise PebbleConnectionException("Commwatch:" + commwatch.error) time.sleep(0.1) else: raise PebbleConnectionException("Pebble not respoding to config") logging.info("Connection ok, entering to active state..") appservice.register_handler("appmessage", handler.message_received_event) while True: commwatch.send_message({COMMUNICATION_KEY_PING: Uint8(0)}) time.sleep(10)
def meminiSense(startDateTime,hostIP,BASE_PORT,streaming=True,logging=True): global meminifilename #logging.basicConfig(level=logging.INFO) #file_path = "/media/card/memini/" #if file_path is None: # print("DID NOT FIND PEBBLE_DATA_LOC") # #print(os.environ) # exit(1) #if not os.path.exists(file_path): # os.mkdir(file_path) # #filename = str(file_path) + "memini_data.csv" running = True #pebble = PebbleConnection(SerialTransport("/dev/rfcomm0")) #pebble.connect() while True: try: pebble = PebbleConnection(SerialTransport("/dev/rfcomm0")) pebble.connect() #print "connection try 0!" appUUID = APP_UUID[:] while running: try: print "Attempt to Connect" #logging.info("Attempting to connect to pebble") pebble.run_async() print "Connection Success" #logging.info("Pebble connection success") break except libpebble2.exceptions.TimeoutError: print "Pebble timeouted, retrying.." continue #print "Opening file!" #with open(meminifilename,'a') as dataFile: # dataFile.write("message,timestamp,button_id,click_type,battery_charge\n") if pebble.connected: restart_app_on_watch(pebble,appUUID) with open(meminifilename,'a') as dataFile: dataFile.write("message,timestamp,button_id,click_type,battery_charge\n") # Register service for app messages mainMsgService = AppMessageService(pebble) mainCommHandler = CommunicationKeeper(appUUID, mainMsgService) mainMsgService.register_handler("nack", mainCommHandler.nack_received) mainMsgService.register_handler("ack", mainCommHandler.ack_received) mainMsgHandler = AppMsgHandler(appUUID) mainMsgService.register_handler("appmessage", mainMsgHandler.message_received_event) while pebble.connected: # time.sleep(10) memini_main(mainMsgService,mainCommHandler,mainMsgHandler) except SerialException: print("Error: Pebble Disconnected!") time.sleep(30) exit(2)
def _install_legacy2(self): metadata = self._bundle.get_app_metadata() app_uuid = metadata['uuid'] self._pebble.send_packet(LegacyAppInstallRequest(data=LegacyUpgradeAppUUID(uuid=app_uuid))) # We don't really care if this worked; we're just waiting for it. self._pebble.read_from_endpoint(LegacyAppInstallResponse) # Find somewhere to install to. self._pebble.send_packet(LegacyAppInstallRequest(data=LegacyBankInfoRequest())) result = self._pebble.read_from_endpoint(LegacyAppInstallResponse).data assert isinstance(result, LegacyBankInfoResponse) first_free = 0 for app in result.apps: assert isinstance(app, LegacyBankEntry) if app.bank_number == first_free: first_free += 1 if first_free == result.bank_count: raise AppInstallError("No app banks free.") # Send the app over binary = self._bundle.zip.read(self._bundle.get_app_path()) self._send_part_legacy2(PutBytesType.Binary, binary, first_free) if self._bundle.has_resources: resources = self._bundle.zip.read(self._bundle.get_resource_path()) self._send_part_legacy2(PutBytesType.Resources, resources, first_free) if self._bundle.has_worker: worker = self._bundle.zip.read(self._bundle.get_worker_path()) self._send_part_legacy2(PutBytesType.Worker, worker, first_free) # Mark it as available self._pebble.send_packet(LegacyAppInstallRequest(data=LegacyAppAvailable(bank=first_free, vibrate=True))) self._pebble.read_from_endpoint(LegacyAppInstallResponse) # Launch it (which is painful on 2.x). appmessage = AppMessageService(self._pebble, message_type=LegacyAppLaunchMessage) appmessage.send_message(app_uuid, { LegacyAppLaunchMessage.Keys.RunState: AMUint8(LegacyAppLaunchMessage.States.Running) }) appmessage.shutdown()
def test_receive_appmessage_string(): pebble = Mock() calls = [0] def handle_result(txid, uuid, result): assert uuid == UUID(int=128) assert txid == 42 assert result == { 14: "hello!", 15: "éclair", # null terminated -> 'foo' should be omitted. 16: "hello\uFFFDworld", # invalid unicode -> U+FFFD REPLACEMENT CHARACTER } calls[0] += 1 service = AppMessageService(pebble) service.register_handler("appmessage", handle_result) assert pebble.register_endpoint.call_args is not None callback = pebble.register_endpoint.call_args[0][1] callback( AppMessage(transaction_id=42, data=AppMessagePush( uuid=UUID(int=128), dictionary=[ AppMessageTuple(key=14, type=AppMessageTuple.Type.CString, data=b"hello!\x00"), AppMessageTuple( key=15, type=AppMessageTuple.Type.CString, data="éclair".encode('utf-8') + b'\x00foo', ), AppMessageTuple(key=16, type=AppMessageTuple.Type.CString, data=b"hello\xffworld"), ]))) pebble.send_packet.assert_called_once_with( AppMessage(transaction_id=42, data=AppMessageACK())) assert calls[0] == 1
def openApp(self, pebbleConnection, uuid): AppStartService = AppMessageService( pebbleConnection, message_type=LegacyAppLaunchMessage) AppStartService.send_message( uuid, { LegacyAppLaunchMessage.Keys.RunState: Uint8(LegacyAppLaunchMessage.States.Running) }) AppStartService.shutdown()
def _install_legacy2(self): metadata = self._bundle.get_app_metadata() app_uuid = metadata['uuid'] # We don't really care if this worked; we're just waiting for it. self._pebble.send_and_read( LegacyAppInstallRequest(data=LegacyUpgradeAppUUID(uuid=app_uuid)), LegacyAppInstallResponse) # Find somewhere to install to. result = self._pebble.send_and_read( LegacyAppInstallRequest(data=LegacyBankInfoRequest()), LegacyAppInstallResponse).data assert isinstance(result, LegacyBankInfoResponse) first_free = 0 for app in result.apps: assert isinstance(app, LegacyBankEntry) if app.bank_number == first_free: first_free += 1 if first_free == result.bank_count: raise AppInstallError("No app banks free.") # Send the app over binary = self._bundle.zip.read(self._bundle.get_app_path()) self._send_part_legacy2(PutBytesType.Binary, binary, first_free) if self._bundle.has_resources: resources = self._bundle.zip.read(self._bundle.get_resource_path()) self._send_part_legacy2(PutBytesType.Resources, resources, first_free) if self._bundle.has_worker: worker = self._bundle.zip.read(self._bundle.get_worker_path()) self._send_part_legacy2(PutBytesType.Worker, worker, first_free) # Mark it as available self._pebble.send_and_read( LegacyAppInstallRequest( data=LegacyAppAvailable(bank=first_free, vibrate=True)), LegacyAppInstallResponse) # Launch it (which is painful on 2.x). appmessage = AppMessageService(self._pebble, message_type=LegacyAppLaunchMessage) appmessage.send_message( app_uuid, { LegacyAppLaunchMessage.Keys.RunState: AMUint8(LegacyAppLaunchMessage.States.Running) }) appmessage.shutdown()
def meminiSense(startDateTime,hostIP,BASE_PORT,streaming=True,logging=True): global meminifilename global agiType global agiIndx global agiStatus global server_address server_address = (hostIP, BASE_PORT) startTimeDT = rNTPTime.stripDateTime(startDateTime) #logging.basicConfig(level=logging.INFO) #file_path = "/media/card/memini/" #if file_path is None: # print("DID NOT FIND PEBBLE_DATA_LOC") # #print(os.environ) # exit(1) #if not os.path.exists(file_path): # os.mkdir(file_path) # #filename = str(file_path) + "memini_data.csv" running = True #pebble = PebbleConnection(SerialTransport("/dev/rfcomm0")) #pebble.connect() while True: try: pebble = PebbleConnection(SerialTransport("/dev/rfcomm0")) pebble.connect() pebble.pump_reader() #print "connection try 0!" appUUID = APP_UUID[:] print "initializing Pebble connection.." # print pebble.send_and_read(AppRunState(data=AppRunStateRequest()), AppRunState).data.uuid while running: try: print "Attempt to Connect" #logging.info("Attempting to connect to pebble") pebble.run_async() print "Connection Success" #logging.info("Pebble connection success") break except libpebble2.exceptions.TimeoutError: print "Pebble timeouted, retrying.." continue while pebble.connected: try: print "Pebble Connected.." restart_app_on_watch(pebble,appUUID) with open(meminifilename,'a') as dataFile: dataFile.write("message,timestamp,button_id,click_type,battery_charge\n") # Register service for app messages print "initializing Services..." mainMsgService = AppMessageService(pebble) mainCommHandler = CommunicationKeeper(appUUID, mainMsgService) mainMsgService.register_handler("nack", mainCommHandler.nack_received) mainMsgService.register_handler("ack", mainCommHandler.ack_received) mainMsgHandler = AppMsgHandler(appUUID) mainMsgService.register_handler("appmessage", mainMsgHandler.message_received_event) break except Exception as err: print err print "Error Initializing Services, retrying.." pebble.run_async() continue while pebble.connected: # time.sleep(10) is_app_on(pebble,appUUID) pebbleMessage = [] pebbleMessage.append("checkNoti") #check for notiFlag from basestation pebbleMessage.append(str(BASE_PORT)) temp = rNTPTime.checkNoti(hostIP, pebbleMessage, 5) # if True: #for testing if int(rNTPTime.notiFlag) == 1: memini_main(mainMsgService,mainCommHandler,mainMsgHandler) # print("sending Message") else: #print "NO NOTIFICATION" time.sleep(NOTI_CHECK_DELAY) except SerialException: print("Pebble Disconnected!") time.sleep(30) continue except Exception as err: print err pass
def produceAppMessageService(pebbleConnection): return AppMessageService(pebbleConnection)
def register_endpoints(self): self.pebble.register_endpoint(AppRunState, self.handle_lifecycle) self.launcher = AppMessageService(self.pebble, message_type=LegacyAppLaunchMessage) self.launcher.register_handler("appmessage", self.handle_launcher)
class PebbleManager(object): def __init__(self, qemu): self.qemu = qemu.split(':') print self.qemu self.pebble = PebbleConnection(QemuTransport(*self.qemu), log_packet_level=logging.DEBUG) self.handle_start = None self.handle_stop = None self.blobdb = None self.launcher = None def connect(self): self.pebble.connect() greenlet = gevent.spawn(self.pebble.run_sync) self.pebble.fetch_watch_info() self.register_endpoints() self.pebble.transport.send_packet( QemuBluetoothConnection(connected=True), target=MessageTargetQemu()) self.blobdb = BlobDBClient(self.pebble) self.request_running_app() logger.info('connected to %s', self.qemu) return greenlet def disconnect(self): if self.launcher is not None: self.launcher.shutdown() def register_endpoints(self): self.pebble.register_endpoint(AppRunState, self.handle_lifecycle) self.launcher = AppMessageService(self.pebble, message_type=LegacyAppLaunchMessage) self.launcher.register_handler("appmessage", self.handle_launcher) def request_running_app(self): if self.pebble.firmware_version.major >= 3: self.pebble.send_packet(AppRunState(data=AppRunStateRequest())) else: self.launcher.send_message( uuid.UUID(int=0), {LegacyAppLaunchMessage.Keys.StateFetch: Uint8(1)}) def handle_lifecycle(self, packet): if isinstance(packet.data, AppRunStateStart): if callable(self.handle_start): self.handle_start(packet.data.uuid) elif isinstance(packet.data, AppRunStateStop): if callable(self.handle_stop): self.handle_stop(packet.data.uuid) def handle_launcher(self, txid, uuid, message): state = message[LegacyAppLaunchMessage.Keys.RunState] if state == LegacyAppLaunchMessage.States.Running: if callable(self.handle_start): self.handle_start(uuid) elif state == LegacyAppLaunchMessage.States.NotRunning: if callable(self.handle_stop): self.handle_stop(uuid) @property def timeline_is_supported(self): return self.pebble.firmware_version.major >= 3
def perform(self, pebble, args, app): json_message = json.loads(open(args.formatted_data).read()) app_message = dict((i, TYPE_CAST[key](json_message[key])) for i, key in enumerate(APP_KEYS)) AppMessageService(pebble).send_message(URCHIN_UUID, app_message) return {'received': True}