def _notify(self, handle, data): orig = data if handle != MOVE_HUB_HARDWARE_HANDLE: log.warning("Unsupported notification handle: 0x%s", handle) return log.debug("Notification on %s: %s", handle, str2hex(orig)) msg_type = usbyte(data, 2) if msg_type == MSG_PORT_INFO: self._handle_port_info(data) elif msg_type == MSG_PORT_STATUS: self._handle_port_status(data) elif msg_type == MSG_SENSOR_DATA: self._handle_sensor_data(data) elif msg_type == MSG_SENSOR_SUBSCRIBE_ACK: port = usbyte(data, 3) log.debug("Sensor subscribe ack on port %s", PORTS[port]) self.devices[port].finished() elif msg_type == MSG_PORT_CMD_ERROR: log.warning("Command error: %s", str2hex(data[3:])) port = usbyte(data, 3) self.devices[port].finished() elif msg_type == MSG_DEVICE_SHUTDOWN: log.warning("Device reported shutdown: %s", str2hex(data)) raise KeyboardInterrupt("Device shutdown") elif msg_type == MSG_DEVICE_INFO: self._handle_device_info(data) else: log.warning("Unhandled msg type 0x%x: %s", msg_type, str2hex(orig))
def _dispatch_notifications(self): while True: handle, data = self._notify_queue.get() data = data[3:] # for some reason, there are extra bytes if self.notification_sink: try: self.notification_sink(handle, data) except BaseException: log.warning("Data was: %s", str2hex(data)) log.warning("Failed to dispatch notification: %s", traceback.format_exc()) else: log.warning("Dropped notification %s: %s", handle, str2hex(data))
def write(self, handle, data): payload = { "type": "write", "handle": handle, "data": str2hex(data) } self._send(payload)
def __repr__(self): # assert self.bytes() # to trigger any field changes data = self.__dict__ data = {x: (str2hex(y) if isinstance(y, bytes) else y) for x, y in data.items() if x not in ('hub_id',)} return self.__class__.__name__ + "(%s)" % data
def __repr__(self): data = self.__dict__ data = { x: (str2hex(y) if isinstance(y, bytes) else y) for x, y in data.items() if x not in ('hub_id', 'needs_reply') } return self.__class__.__name__ + "(%s)" % data
def _handle_device_info(self, data): kind = usbyte(data, 3) if kind == 2: self.button.handle_port_data(data) if usbyte(data, 4) == 0x06: self.info[kind] = data[5:] else: log.warning("Unhandled device info: %s", str2hex(data))
def _queue_reader(self): while True: data = self._incoming_port_data.get() try: self.handle_port_data(data) except BaseException: log.warning("%s", traceback.format_exc()) log.warning("Failed to handle port data by %s: %s", self, str2hex(data))
def _notify(self, conn, handle, data): payload = {"type": "notification", "handle": handle, "data": str2hex(data)} log.debug("Send notification: %s", payload) try: conn.send(json.dumps(payload) + "\n") except KeyboardInterrupt: raise except BaseException: log.error("Problem sending notification: %s", traceback.format_exc()) self._check_shutdown(data)
def _report_status(self): # maybe add firmware version name = self.send(MsgHubProperties(MsgHubProperties.ADVERTISE_NAME, MsgHubProperties.UPD_REQUEST)) mac = self.send(MsgHubProperties(MsgHubProperties.PRIMARY_MAC, MsgHubProperties.UPD_REQUEST)) log.info("%s on %s", name.payload, str2hex(mac.payload)) voltage = self.send(MsgHubProperties(MsgHubProperties.VOLTAGE_PERC, MsgHubProperties.UPD_REQUEST)) assert isinstance(voltage, MsgHubProperties) log.info("Voltage: %s%%", usbyte(voltage.parameters, 0)) voltage = self.send(MsgHubAlert(MsgHubAlert.LOW_VOLTAGE, MsgHubAlert.UPD_REQUEST)) assert isinstance(voltage, MsgHubAlert) if not voltage.is_ok(): log.warning("Low voltage, check power source (maybe replace battery)")
def _notify(self, handle, data): log.debug("Notification on %s: %s", handle, str2hex(data)) msg = self._get_upstream_msg(data) with self._sync_lock: if self._sync_request: if self._sync_request.is_reply(msg): log.debug("Found matching upstream msg: %r", msg) self._sync_replies.put(msg) self._sync_request = None for msg_class, handler in self._msg_handlers: if isinstance(msg, msg_class): log.debug("Handling msg with %s: %r", handler, msg) handler(msg)
def _decode_port_data(self, msg): data = msg.payload if self._port_mode.mode == self.COLOR_INDEX: color = usbyte(data, 0) return (color, ) elif self._port_mode.mode == self.COLOR_DISTANCE_FLOAT: color = usbyte(data, 0) val = usbyte(data, 1) partial = usbyte(data, 3) if partial: val += 1.0 / partial return (color, float(val)) elif self._port_mode.mode == self.DISTANCE_INCHES: val = usbyte(data, 0) return (val, ) elif self._port_mode.mode == self.DISTANCE_REFLECTED: val = usbyte(data, 0) / 100.0 return (val, ) elif self._port_mode.mode == self.AMBIENT_LIGHT: val = usbyte(data, 0) / 100.0 return (val, ) elif self._port_mode.mode == self.COUNT_2INCH: count = usint(data, 0) return (count, ) elif self._port_mode.mode == self.COLOR_RGB: val1 = int(255 * ushort(data, 0) / 1023.0) val2 = int(255 * ushort(data, 2) / 1023.0) val3 = int(255 * ushort(data, 4) / 1023.0) return (val1, val2, val3) elif self._port_mode.mode == self.DEBUG: val1 = 10 * ushort(data, 0) / 1023.0 val2 = 10 * ushort(data, 2) / 1023.0 return (val1, val2) elif self._port_mode.mode == self.CALIBRATE: return [ushort(data, x * 2) for x in range(8)] else: log.debug("Unhandled data in mode %s: %s", self._port_mode.mode, str2hex(data)) return ()
def handle_port_data(self, data): if self._port_subscription_mode == self.COLOR_DISTANCE_FLOAT: color = usbyte(data, 4) distance = usbyte(data, 5) partial = usbyte(data, 7) if partial: distance += 1.0 / partial self._notify_subscribers(color, float(distance)) elif self._port_subscription_mode == self.COLOR_ONLY: color = usbyte(data, 4) self._notify_subscribers(color) elif self._port_subscription_mode == self.DISTANCE_INCHES: distance = usbyte(data, 4) self._notify_subscribers(distance) elif self._port_subscription_mode == self.DISTANCE_HOW_CLOSE: distance = usbyte(data, 4) self._notify_subscribers(distance) elif self._port_subscription_mode == self.DISTANCE_SUBINCH_HOW_CLOSE: distance = usbyte(data, 4) self._notify_subscribers(distance) elif self._port_subscription_mode == self.OFF1 or self._port_subscription_mode == self.OFF2: log.info("Turned off led on %s", self) elif self._port_subscription_mode == self.COUNT_2INCH: count = unpack("<L", data[4:8])[0] # is it all 4 bytes or just 2? self._notify_subscribers(count) elif self._port_subscription_mode == self.STREAM_3_VALUES: # TODO: understand better meaning of these 3 values val1 = ushort(data, 4) val2 = ushort(data, 6) val3 = ushort(data, 8) self._notify_subscribers(val1, val2, val3) elif self._port_subscription_mode == self.LUMINOSITY: luminosity = ushort(data, 4) / 1023.0 self._notify_subscribers(luminosity) else: # TODO: support whatever we forgot log.debug("Unhandled data in mode %s: %s", self._port_subscription_mode, str2hex(data))
def _notify(self, handle, data): log.debug("Notification on %s: %s", handle, str2hex(data)) msg = self._get_upstream_msg(data) # Cludge to stop it crashing if hasattr(msg, 'status'): if msg.status == 44: msg.status = 10 log.debug("Set status to 10") with self._sync_lock: if self._sync_request: if self._sync_request.is_reply(msg): log.debug("Found matching upstream msg: %r", msg) self._sync_replies.put(msg) self._sync_request = None else: log.debug("Message did not match") for msg_class, handler in self._msg_handlers: if isinstance(msg, msg_class): log.debug("Handling msg with %s: %r", handler, msg) handler(msg)
def characteristic_value_updated(self, characteristic, value): value = self._fix_weird_bug(value) log.debug('Notification in GattDevice: %s', str2hex(value)) self._notify_callback(MOVE_HUB_HARDWARE_HANDLE, value)
def write(self, handle, data): log.debug("Writing to handle %s: %s", handle, str2hex(data)) return self._conn_hnd.char_write_handle(handle, bytearray(data))
def write(self, handle, data): log.debug("Writing to handle %s: %s", handle, str2hex(data)) self._peripheral.write(handle, data)
def write(self, handle, data): log.debug("Writing to %s: %s", handle, str2hex(data)) return self.requester.write_by_handle(handle, data)
def handle_port_data(self, data): log.warning("Unhandled device notification for %s: %s", self, str2hex(data[4:])) self._notify_subscribers(data[4:])
def on_indication(self, handle, data): log.debug("Indication on handle %s: %s", handle, str2hex(data))
def write(self, data): log.debug("Writing to handle: %s", str2hex(data)) return self._handle.write_value(data)