diff --git a/nuki_bridge/__main__.py b/nuki_bridge/__main__.py index 42d4528..0626c3b 100644 --- a/nuki_bridge/__main__.py +++ b/nuki_bridge/__main__.py @@ -7,16 +7,17 @@ from scan_ble import find_ble_device from utils import logger, handler from web_server import WebServer +from nuki_manager import NukiManager logging.getLogger("aiohttp").addHandler(handler) logging.getLogger("aiohttp").setLevel(logging.ERROR) logging.getLogger("bleak").addHandler(handler) logging.getLogger("bleak").setLevel(logging.ERROR) logging.getLogger("pyNukiBT").addHandler(handler) -logging.getLogger("pyNukiBT").setLevel(logging.INFO) +logging.getLogger("pyNukiBT").setLevel(logging.WARNING) -def _add_devices_to_manager(data, nuki_manager): +def _add_devices_to_manager(data, nuki_manager:NukiManager): for ls in data["smartlock"]: address = ls["address"] auth_id = bytes.fromhex(ls["auth_id"]) @@ -42,14 +43,17 @@ def _add_devices_to_manager(data, nuki_manager): if not args.verbose: logger.setLevel(level=logging.INFO) + logging.getLogger("pyNukiBT").setLevel(logging.WARNING) logging.getLogger("aiohttp").setLevel(level=logging.ERROR) logging.getLogger("bleak").setLevel(level=logging.ERROR) elif args.verbose == 1: logger.setLevel(level=logging.DEBUG) + logging.getLogger("pyNukiBT").setLevel(logging.INFO) logging.getLogger("aiohttp").setLevel(level=logging.INFO) logging.getLogger("bleak").setLevel(level=logging.INFO) elif args.verbose == 2: logger.setLevel(level=logging.DEBUG) + logging.getLogger("pyNukiBT").setLevel(logging.DEBUG) logging.getLogger("aiohttp").setLevel(level=logging.DEBUG) logging.getLogger("bleak").setLevel(level=logging.DEBUG) @@ -75,16 +79,10 @@ def _add_devices_to_manager(data, nuki_manager): bridge_public_key, bridge_private_key = _generate_bridge_keys() nuki = NukiDevice(address, None, None, bridge_public_key, bridge_private_key, nuki_manager.app_id, nuki_manager.name, nuki_manager.type_id) + ret = nuki.pair() + logger.info(f"Pairing completed, nuki_public_key: {ret['nuki_public_key'].hex()}") + logger.info(f"Pairing completed, auth_id: {ret['auth_id'].hex()}") nuki_manager.add_nuki(nuki) - - loop = asyncio.get_event_loop() - - def pairing_completed(paired_nuki): - logger.info(f"Pairing completed, nuki_public_key: {paired_nuki.nuki_public_key.hex()}") - logger.info(f"Pairing completed, auth_id: {paired_nuki.auth_id.hex()}") - loop.stop() - loop.create_task(nuki.pair(pairing_completed)) - loop.run_forever() else: if not nuki_manager.device_list: _add_devices_to_manager(data, nuki_manager) diff --git a/nuki_bridge/config.py b/nuki_bridge/config.py index a71fd65..35e7096 100644 --- a/nuki_bridge/config.py +++ b/nuki_bridge/config.py @@ -101,33 +101,24 @@ def init_config(config_file, addon_config_file): # Pair nuki = NukiDevice(address, None, None, bridge_public_key, bridge_private_key, nuki_manager.app_id, nuki_manager.name, nuki_manager.type_id) - nuki_manager.add_nuki(nuki) - loop = asyncio.new_event_loop() - - nuki_manager.start(loop) - - def pairing_completed(paired_nuki): - nuki_public_key = paired_nuki.nuki_public_key.hex() - auth_id = paired_nuki.auth_id.hex() - logger.info(f"Pairing completed, auth_id: {auth_id}") - logger.info(f"nuki_public_key: {nuki_public_key}") - logger.info(f"********************************************************************") - logger.info(f"* *") - logger.info(f"* Pairing completed! *") - logger.info(f"* Access Token *") - logger.info(f"* {token} *") - logger.info(f"* *") - logger.info(f"********************************************************************") - smartlock['nuki_public_key'] = nuki_public_key - smartlock['auth_id'] = auth_id - - data['smartlock'] = [smartlock] - yaml.dump(data, open(config_file, 'w')) - loop.stop() - - loop.create_task(nuki.pair(pairing_completed)) - loop.run_forever() + ret = nuki.pair() + nuki_public_key = ret["nuki_public_key"].hex() + auth_id = ret["auth_id"].hex() + logger.info(f"Pairing completed, auth_id: {auth_id}") + logger.info(f"nuki_public_key: {nuki_public_key}") + logger.info(f"********************************************************************") + logger.info(f"* *") + logger.info(f"* Pairing completed! *") + logger.info(f"* Access Token *") + logger.info(f"* {token} *") + logger.info(f"* *") + logger.info(f"********************************************************************") + smartlock['nuki_public_key'] = nuki_public_key + smartlock['auth_id'] = auth_id + + data['smartlock'] = [smartlock] + yaml.dump(data, open(config_file, 'w')) return nuki_manager, data diff --git a/nuki_bridge/nuki_manager.py b/nuki_bridge/nuki_manager.py index 66f7df3..71d118a 100644 --- a/nuki_bridge/nuki_manager.py +++ b/nuki_bridge/nuki_manager.py @@ -39,7 +39,10 @@ def nuki_by_id(self, nuki_id) -> NukiDevice: return next(nuki for nuki in self._devices.values() if nuki.config.get("nuki_id") == nuki_id) def add_nuki(self, nuki: NukiDevice): - self._devices[nuki.address] = nuki + self._devices[nuki._address] = nuki + def _cb(): + self.nuki_newstate(nuki) + nuki.subscribe(_cb) @property def device_list(self): @@ -84,6 +87,6 @@ async def stop_scanning(self, timeout=10.0): async def _detected_ibeacon(self, device: BLEDevice, advertisement_data: AdvertisementData): if device.address in self._devices: nuki = self._devices[device.address] - await nuki.parse_advertisement_data(device, advertisement_data) + nuki.parse_advertisement_data(device, advertisement_data) if nuki.poll_needed(): await nuki.update_state() diff --git a/nuki_bridge/requirements.txt b/nuki_bridge/requirements.txt index fd90181..d81d86d 100644 --- a/nuki_bridge/requirements.txt +++ b/nuki_bridge/requirements.txt @@ -1,4 +1,4 @@ aiohttp==3.8.1 bleak==0.20.1 PyYAML==6.0 -pyNukiBT @ git+https://github.com/ronengr/pyNukiBT.git@main \ No newline at end of file +pyNukiBT==0.0.4 \ No newline at end of file diff --git a/nuki_bridge/web_server.py b/nuki_bridge/web_server.py index f1c055b..6959851 100644 --- a/nuki_bridge/web_server.py +++ b/nuki_bridge/web_server.py @@ -33,8 +33,8 @@ def start(self): web.get('/callback/add', self.callback_add), web.get('/callback/list', self.callback_list), web.get('/callback/remove', self.callback_remove), - web.get('/verify_pin', self.verify_pin), - web.get('/request_last_log_entry', self.request_last_log_entry), + web.get('/verify_security_pin', self.verify_security_pin), + web.get('/request_log_entries', self.request_log_entries), ]) app.on_startup.append(self._startup) web.run_app(app, host=self._host, port=self._port, loop=self._loop) @@ -172,24 +172,27 @@ async def nuki_lock(self, request): res = json.dumps({"success": True, "batteryCritical": n.is_battery_critical}) return web.Response(text=res) - async def verify_pin(self, request): + async def verify_security_pin(self, request): if not self._check_token(request): raise web.HTTPForbidden() n: NukiDevice = self.nuki_manager.nuki_by_id(int(request.query["nukiId"], base=16)) try: - ret = await n.verify_pin(int(request.query["pin"], base=10)) + ret = await n.verify_security_pin(int(request.query["pin"], base=10)) except NukiErrorException as ex: res = json.dumps({"success" : False, "error_code": ex.error_code}) else: res = json.dumps({"success": ret}) return web.Response(text=res) - async def request_last_log_entry(self, request): + async def request_log_entries(self, request): if not self._check_token(request): raise web.HTTPForbidden() n: NukiDevice = self.nuki_manager.nuki_by_id(int(request.query["nukiId"], base=16)) + security_pin=int(request.query.get("security_pin"), base=10) + count=int(request.query.get("count", default=1)) + start_index=int(request.query.get("start_index", default=0)) try: - ret = await n.request_last_log_entry(int(request.query["pin"], base=10)) + ret = await n.request_log_entries(security_pin=security_pin, count=count, start_index=start_index) except NukiErrorException as ex: res = json.dumps({"success" : False, "error_code": ex.error_code}) else: