diff --git a/README.md b/README.md index cf96518..1406404 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Requires `gattlib` to be installed, currently Python 2.7 only -Best way to start is to look at [demo.py](demo.py) file, and run it. +Best way to start is to look into [demo.py](demo.py) file, and run it. ## Features @@ -20,7 +20,6 @@ Best way to start is to look at [demo.py](demo.py) file, and run it. from pylgbst import MoveHub hub = MoveHub() -print(hub.get_name()) for device in hub.devices: print(device) @@ -39,6 +38,7 @@ sudo python -c "from pylgbst.comms import *; import logging; logging.basicConfig - Give nice documentation examples, don't forget to mention logging - make angled motors to be synchronous by default => 3-state status - make sure unit tests cover all important code +- generalize getting device info + give constants (low priority) ## Links diff --git a/demo.py b/demo.py index de79d72..0155542 100644 --- a/demo.py +++ b/demo.py @@ -177,6 +177,6 @@ if __name__ == '__main__': sleep(10) # demo_port_cd_motor(hub) sleep(10) - hub.button.unsubscribe(cb_log) + #hub.button.unsubscribe(cb_log) sleep(10) # demo_all(hub) diff --git a/pylgbst/__init__.py b/pylgbst/__init__.py index aa1a4c1..85c92f8 100644 --- a/pylgbst/__init__.py +++ b/pylgbst/__init__.py @@ -59,10 +59,6 @@ class MoveHub(object): log.warning("Got only these devices: %s", builtin_devices) raise RuntimeError("Failed to obtain all builtin devices") - def get_name(self): - # note: reading this too fast makes it hang - return self.connection.read(DEVICE_NAME) - def _notify(self, handle, data): orig = data diff --git a/pylgbst/comms.py b/pylgbst/comms.py index 165eb81..a2d1f40 100644 --- a/pylgbst/comms.py +++ b/pylgbst/comms.py @@ -6,14 +6,14 @@ import json import logging import socket import sys -import time import traceback -from six.moves import queue from abc import abstractmethod from binascii import unhexlify from gattlib import DiscoveryService, GATTRequester from threading import Thread +from six.moves import queue + from pylgbst.constants import LEGO_MOVE_HUB, MSG_DEVICE_SHUTDOWN log = logging.getLogger('comms') @@ -70,10 +70,6 @@ class Requester(GATTRequester): class Connection(object): - @abstractmethod - def read(self, handle): - pass - @abstractmethod def write(self, handle, data): pass @@ -88,17 +84,17 @@ class BLEConnection(Connection): Main transport class, uses real Bluetooth LE connection. Loops with timeout of 1 seconds to find device named "Lego MOVE Hub" - :type _requester: Requester + :type requester: Requester """ def __init__(self): super(BLEConnection, self).__init__() - self._requester = None + self.requester = None def connect(self, bt_iface_name='hci0'): service = DiscoveryService(bt_iface_name) - while not self._requester: + while not self.requester: log.info("Discovering devices using %s...", bt_iface_name) devices = service.discover(1) log.debug("Devices: %s", devices) @@ -106,30 +102,21 @@ class BLEConnection(Connection): for address, name in devices.items(): if name == LEGO_MOVE_HUB: logging.info("Found %s at %s", name, address) - self._requester = Requester(address, True, bt_iface_name) + self.requester = Requester(address, True, bt_iface_name) break return self def set_notify_handler(self, handler): - if self._requester: + if self.requester: log.debug("Setting notification handler: %s", handler) - self._requester.notification_sink = handler + self.requester.notification_sink = handler else: raise RuntimeError("No requester available") - def read(self, handle): - # FIXME: repeating reads hangs it... - log.debug("Reading from: %s", handle) - data = self._requester.read_by_handle(handle) - log.debug("Result: %s", data) - if isinstance(data, list): - data = data[0] - return data - def write(self, handle, data): log.debug("Writing to %s: %s", handle, str2hex(data)) - return self._requester.write_by_handle(handle, data) + return self.requester.write_by_handle(handle, data) class DebugServer(object): @@ -156,7 +143,7 @@ class DebugServer(object): conn, addr = self.sock.accept() if not self._running: raise KeyboardInterrupt("Shutdown") - self.ble._requester.notification_sink = lambda x, y: self._notify(conn, x, y) + self.ble.requester.notification_sink = lambda x, y: self._notify(conn, x, y) try: self._handle_conn(conn) except KeyboardInterrupt: @@ -164,7 +151,7 @@ class DebugServer(object): except BaseException: log.error("Problem handling incoming connection: %s", traceback.format_exc()) finally: - self.ble._requester.notification_sink = self._notify_dummy + self.ble.requester.notification_sink = self._notify_dummy conn.close() def __del__(self): @@ -220,11 +207,6 @@ class DebugServer(object): def _handle_cmd(self, cmd): if cmd['type'] == 'write': self.ble.write(cmd['handle'], unhexlify(cmd['data'])) - elif cmd['type'] == 'read': - data = self.ble.read(cmd['handle']) - payload = {"type": "response", "data": str2hex(data)} - log.debug("Send response: %s", payload) - self.sock.send(json.dumps(payload) + "\n") else: raise ValueError("Unhandled cmd: %s", cmd) @@ -258,20 +240,6 @@ class DebugServerConnection(Connection): } self._send(payload) - def read(self, handle): - payload = { - "type": "read", - "handle": handle - } - self._send(payload) - - while True: - for item in self.incoming: - if item['type'] == 'response': - self.incoming.remove(item) - return unhexlify(item['data']) - time.sleep(0.1) - def _send(self, payload): log.debug("Sending to debug server: %s", payload) self.sock.send(json.dumps(payload) + "\n") diff --git a/pylgbst/constants.py b/pylgbst/constants.py index 4f09887..8f2b948 100644 --- a/pylgbst/constants.py +++ b/pylgbst/constants.py @@ -34,6 +34,7 @@ PORTS = { # PACKET TYPES MSG_DEVICE_INFO = 0x01 +# 0501010305 gives 090001030600000010 MSG_DEVICE_SHUTDOWN = 0x02 # sent when hub shuts down by button hold MSG_PING_RESPONSE = 0x03 MSG_PORT_INFO = 0x04 diff --git a/setup.py b/setup.py index 53ba291..db07f32 100644 --- a/setup.py +++ b/setup.py @@ -6,5 +6,5 @@ setup(name='pylgbst', author='Andrey Pokhilko', author_email='apc4@ya.ru', packages=['pylgbst'], - requires=['six', 'future', 'gattlib'] + requires=['six', 'gattlib'] ) diff --git a/tests.py b/tests.py index f9036e1..03983fb 100644 --- a/tests.py +++ b/tests.py @@ -42,10 +42,6 @@ class ConnectionMock(Connection): log.debug("Writing to %s: %s", handle, str2hex(data)) self.writes.append((handle, str2hex(data))) - def read(self, handle): - log.debug("Reading from: %s", handle) - return None # TODO - class HubMock(MoveHub): def __init__(self, connection=None):