예제 #1
0
 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()))
예제 #2
0
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
예제 #3
0
 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)
예제 #4
0
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
예제 #5
0
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))
예제 #6
0
    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()
예제 #7
0
 def ping(self, uid):
     msg = hm.make_ping()
     self._addToBuffer(uid, msg)
예제 #8
0
    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)