Esempio n. 1
0
class Node:
    def __init__(self):

        self._responses_cond = threading.Condition()
        self._responses = collections.deque()
        self._event_cond = threading.Condition()
        self._events = collections.deque()

        self._datas = queue.Queue()

        self.channels = {}

        self.ant = Ant()

        self._running = True

        self._worker_thread = threading.Thread(target=self._worker, name="ant.easy")
        self._worker_thread.start()

    def new_channel(self, ctype, network_number=0x00, ext_assign=None):
        size = len(self.channels)
        channel = Channel(size, self, self.ant)
        self.channels[size] = channel
        channel._assign(ctype, network_number, ext_assign)
        return channel

    def delete_channel(self):
        if len(self.channels) > 0:
            c = self.channels.pop(len(self.channels)-1)
            self.ant.unassign_channel(c.id)
            c.get_channel_status()
            del c

    def request_message(self, messageId):
        _logger.debug("requesting message %#02x", messageId)
        self.ant.request_message(0, messageId)
        _logger.debug("done requesting message %#02x", messageId)
        return self.wait_for_special(messageId)

    def set_network_key(self, network, key):
        self.ant.set_network_key(network, key)
        return self.wait_for_response(Message.ID.SET_NETWORK_KEY)

    def set_lib_config(self, value):
      # 0: Disabled
      # 0x20: Enables Rx Timestamp Output
      # 0x40: Enables RSSI Output
      # 0x80: Enables Channel ID Output
      self.ant.set_lib_config(value)
      return self.wait_for_response(Message.ID.LIB_CONFIG)

    def set_tx_power(self, value):
      # 0: low, 1...2, 3: High(0dBm), (4: N/A or High(4dbm))
      self.ant.set_tx_power(value)
      return self.wait_for_response(Message.ID.SET_TRANSMIT_POWER)

    def wait_for_event(self, ok_codes):
        return wait_for_event(ok_codes, self._events, self._event_cond)

    def wait_for_response(self, event_id):
        return wait_for_response(event_id, self._responses, self._responses_cond)

    def wait_for_special(self, event_id):
        return wait_for_special(event_id, self._responses, self._responses_cond)

    def _worker_response(self, channel, event, data):
        self._responses_cond.acquire()
        self._responses.append((channel, event, data))
        self._responses_cond.notify()
        self._responses_cond.release()

    def _worker_event(self, channel, event, data):
        if event == Message.Code.EVENT_RX_BURST_PACKET:
            self._datas.put(("burst", channel, data))
        elif event == Message.Code.EVENT_RX_BROADCAST:
            self._datas.put(("broadcast", channel, data))
        elif event == Message.Code.EVENT_TX:
            self._datas.put(("broadcast_tx", channel, data))
        elif event == Message.Code.EVENT_RX_ACKNOWLEDGED:
            self._datas.put(("acknowledge", channel, data))
        else:
            self._event_cond.acquire()
            self._events.append((channel, event, data))
            self._event_cond.notify()
            self._event_cond.release()

    def _worker(self):
        self.ant.response_function = self._worker_response
        self.ant.channel_event_function = self._worker_event

        # TODO: check capabilities
        self.ant.start()

    def _main(self):
        while self._running:
            try:
                (data_type, channel, data) = self._datas.get(True, 1.0)
                self._datas.task_done()

                if data_type == "broadcast":
                    self.channels[channel].on_broadcast_data(data)
                elif data_type == "burst":
                    self.channels[channel].on_burst_data(data)
                elif data_type == "broadcast_tx":
                    self.channels[channel].on_broadcast_tx_data(data)
                elif data_type == "acknowledge":
                    self.channels[channel].on_acknowledge_data(data)
                else:
                    _logger.warning("Unknown data type '%s': %r", data_type, data)
            except queue.Empty as e:
                pass

    def start(self):
        self._main()

    def stop(self):
        if self._running:
            _logger.debug("Stoping ant.easy")
            self._running = False
            self.ant.stop()
            self._worker_thread.join()