async def send_messages(self): """ Send messages in the queue to the sensor. """ await self._ready.wait() while not self.transport.is_closing(): instruction, args = await self.write_queue.get() if instruction == "ping": hm.send(self.transport, hm.make_ping()) elif instruction == "subscribe": uid, delay, params = args hm.send( self.transport, hm.make_subscription_request(hm.uid_to_device_id(uid), params, delay)) elif instruction == "read": uid, params = args hm.send(self.transport, hm.make_device_read(hm.uid_to_device_id(uid), params)) elif instruction == "write": uid, params_and_values = args hm.send( self.transport, hm.make_device_write(hm.uid_to_device_id(uid), params_and_values)) elif instruction == "disable": hm.send(self.transport, hm.make_disable()) elif instruction == "heartResp": uid = args[0] hm.send(self.transport, hm.make_heartbeat_response(self.read_queue.qsize()))
def device_write_thread(ser, instr_queue): """ Send packets to SER based on instructions from INSTR_QUEUE. """ try: while True: instruction, args = instr_queue.get() if instruction == "ping": hm.send(ser, hm.make_ping()) elif instruction == "subscribe": uid, delay, params = args hm.send( ser, hm.make_subscription_request(hm.uid_to_device_id(uid), params, delay)) elif instruction == "read": uid, params = args hm.send(ser, hm.make_device_read(hm.uid_to_device_id(uid), params)) elif instruction == "write": uid, params_and_values = args hm.send( ser, hm.make_device_write(hm.uid_to_device_id(uid), params_and_values)) elif instruction == "disable": hm.send(ser, hm.make_disable()) elif instruction == "heartResp": uid = args[0] hm.send(ser, hm.make_heartbeat_response()) except serial.SerialException: # Device has disconnected pass
async def register_sensor(self, event_loop, devices, pending): """ Try to get our UID from the sensor and register it with `hibike_process`. """ await self._ready.wait() hm.send(self.transport, hm.make_ping()) await asyncio.sleep(IDENTIFY_TIMEOUT, loop=event_loop) if self.uid is None: self.quit() else: hm.send(self.transport, hm.make_ping()) hm.send( self.transport, hm.make_subscription_request(hm.uid_to_device_id(self.uid), [], 0)) devices[self.uid] = self pending.remove(self.transport.serial.name)
def identify_smart_sensors(serial_conns): """ Given a list of serial port connections, figure out which contain smart sensors. Returns: A map of serial port names to UIDs. """ def recv_subscription_response(conn, uid_queue, stop_event): """ Place received subscription response UIDs from CONN into UID_QUEUE, stopping when STOP_EVENT is set. """ try: for packet in hm.blocking_read_generator(conn, stop_event): msg_type = packet.get_message_id() if msg_type == hm.MESSAGE_TYPES["SubscriptionResponse"]: _, _, uid = hm.parse_subscription_response(packet) uid_queue.put(uid) except serial.SerialException: pass device_map = {} candidates = [] for conn in serial_conns: old_timeout = conn.write_timeout conn.write_timeout = IDENTIFY_TIMEOUT try: hm.send(conn, hm.make_ping()) except serial.SerialTimeoutException: continue finally: conn.write_timeout = old_timeout maybe_device = namedtuple("MaybeDevice", ["serial_conn", "queue", "event", "thread"]) maybe_device.queue = queue.Queue() maybe_device.event = threading.Event() maybe_device.serial_conn = conn maybe_device.thread = threading.Thread( target=recv_subscription_response, args=(conn, maybe_device.queue, maybe_device.event)) candidates.append(maybe_device) for cand in candidates: cand.thread.start() for cand in candidates: try: uid = cand.queue.get(block=True, timeout=IDENTIFY_TIMEOUT) device_map[cand.serial_conn.name] = uid # Shut device up hm.send(cand.serial_conn, hm.make_subscription_request(uid, [], 0)) except queue.Empty: pass for cand in candidates: cand.event.set() cand.thread.join() return device_map
def device_write_thread(ser, queue): while True: instruction, args = queue.get() if instruction == "ping": hm.send(ser, hm.make_ping()) elif instruction == "subscribe": uid, delay, params = args hm.send( ser, hm.make_subscription_request(hm.uid_to_device_id(uid), params, delay)) elif instruction == "read": uid, params = args hm.send(ser, hm.make_device_read(hm.uid_to_device_id(uid), params)) elif instruction == "write": uid, params_and_values = args hm.send( ser, hm.make_device_write(hm.uid_to_device_id(uid), params_and_values))
def _enumerateSerialPorts(self): """Enumerates all devices that have a Smart Device attached. Correct ports are identified by matching to port descriptors contained in smartDeviceBoards. Sub responses will be caught by HibikeThread If devices are dropping and reconnecting too often, consider sending the sub request and sub response messages multiple times. #TODO any device that is no longer enumerated should be assumed unplugged, and either removed from self.serialPorts, or a flag set to denote that said device is no longer valid. """ portInfo = serialtools.grep('ttyACM') for ser, desc, hwid in portInfo: try: delay = 0 if ser in self.serialToUID.keys(): uid = self.serialToUID[ser][0] if uid in self.context.keys(): delay = self.context[uid].delay else: self.serialToUID[ser] = (None, serial.Serial(ser, 115200)) #msg = hm.make_sub_request(delay) #print("enumerating something") try: self.sendBuffer.put( (self.serialToUID[ser][1], hm.make_ping()), block=False) except Full: print("QUEUE FULL!!! FLUSHING") self.sendBuffer.queue.clear() #hm.send(self.serialToUID[ser][1], msg) except (serial.serialutil.SerialException, OSError): pass except: print("Unexpected error", sys.exc_info()[0]) t = Timer(self.timeout, self._enumerateSerialPorts) t.start()
def ping(self, uid): msg = hm.make_ping() self._addToBuffer(uid, msg)
def __repr__(self): res = "" res += hm.uid_to_device_name(self.uid) res += ":\n" res += " %d" % self.uid res += " %s\n" % self.serial_port.port res += " %s\n" % self.data return res SERIALS = [serial.Serial(port, 115200) for port in PORTS] DEVICES = [] for s in SERIALS: hm.send(s, hm.make_ping()) while SERIALS: remaining = [] for s in SERIALS: reading = hm.blocking_read(s) if reading: params, delay, device_type, year, id = struct.unpack( "<HHHBQ", reading.get_payload()) uid = (device_type << 72) | (year << 64) | id DEVICES.append(HibikeDevice(s, params, delay, uid)) else: remaining.append(s) SERIALS = remaining print("devices:", DEVICES)