def quit(self): if self.doorbird_server: log.info(f"{self.device_name} quit doorbird endpoint...") self.doorbird_server.close() self.d.loop.run_until_complete(self.doorbird_app.shutdown()) self.d.loop.run_until_complete(self.doorbird_handler.shutdown(2.0)) self.d.loop.run_until_complete(self.doorbird_app.cleanup())
def quit(self): if self.ws_server: log.info("quit weather station receiver...") self.ws_server.close() self.d.loop.run_until_complete(self.ws_app.shutdown()) self.d.loop.run_until_complete(self.ws_handler.shutdown(2.0)) self.d.loop.run_until_complete(self.ws_app.cleanup())
async def _write_mqtt(self, knx_group, knx_val, debug_msg): if not self._mqtt_client: return objects = [] request_status = False for item in self.obj_list: if item["knx_group"] == knx_group: objects.append(item) request_status = "request_status" in item for o in objects: if "publish_topic" in o: topic = o["publish_topic"] prev_val = o["value"] if "valmap" in o: payload = o["valmap"][knx_val] else: payload = knx_val log.info(f"{debug_msg} topic {topic} updating {prev_val}=>{knx_val} ({payload})") try: await self._mqtt_client.publish(topic, payload, qos=1, retain=True) o["value"] = knx_val except MqttCodeError as error: log.error(f"{debug_msg} MqttCodeError {error} on topic {topic}") if objects and request_status and "status_object" in self.cfg and self._mqtt_client and not knx_group in self.status_pending_for_groups: so = self.cfg["status_object"] delay = so.get("delay", 10.0) topic = so["topic"] payload = so["payload"] await asyncio.sleep(delay) try: await self._mqtt_client.publish(topic, payload, qos=1, retain=True) log.debug(f"{debug_msg} requested status topic {topic} payload=>{payload}") self.status_pending_for_groups.append(knx_group) except MqttCodeError as error: log.error(f"{debug_msg} MqttCodeError {error} on topic {topic}")
def run(self): if self.cfg["enabled"]: self.ws_app = web.Application(debug=True) self.ws_app.router.add_get('/weatherstation/{name}', self.handle) self.ws_handler = self.ws_app.make_handler() log.info("running weather station receiver...") ws_coro = self.d.loop.create_server( self.ws_handler, self.d.cfg["sys"]["listenHost"], self.cfg["listenPort"]) self.ws_server = self.d.loop.run_until_complete(ws_coro) return None
async def rs485_connection(self, loop): baudrate = "baudRate" in self.cfg and self.cfg["baudRate"] or 115200 dev = self.cfg["serialDevice"] try: self._reader, self._writer = await serial_asyncio.open_serial_connection( loop=loop, url=dev, baudrate=baudrate) log.info( f"{self.device_name} Successfully opened {dev} @ {baudrate} baud." ) except SerialException as e: log.error(f"{self.device_name} Can't open {dev}. {e!r}")
def run(self): if self.cfg["enabled"]: self.doorbird_app = web.Application(debug=True) self.doorbird_app.router.add_get('/doorbird/{name}', self.handle) self.doorbird_handler = self.doorbird_app.make_handler() log.info(f"{self.device_name} running doorbird endpoint...") doorbird_coro = self.d.loop.create_server( self.doorbird_handler, self.d.cfg["sys"]["listenHost"], self.cfg["listenPort"]) self.doorbird_server = self.d.loop.run_until_complete( doorbird_coro) return None
async def set_gpio(self, o, value): log.debug(f"{self.device_name} set_gpio({o!r}, {value})") try: gpio_obj = o["gpio_object"] prev_value = gpio_obj.value set_cb = o["set_cb"] log.info(f"{self.device_name} set_gpio prev_active={prev_value}->{value}. calling {set_cb!r}...") set_cb() if "actuate_seconds" in o: delay = o["actuate_seconds"] log.debug(f"{self.device_name} waiting {delay} s") await asyncio.sleep(delay) gpio_obj.value = prev_value log.debug(f"{self.device_name} restored previous state") except (TypeError, AttributeError): log.warning(f"{self.device_name} set_gpio illegal action '{value}' for {gpio_obj!r}")
async def handle(self, request): query = request.rel_url.query log.debug(f"{self.device_name} handle: {query!r}") if "toggle" in query: if not "key" in query: log.warning( f"{self.device_name} no FOB key given when handling {query!r}!" ) return web.Response(status=403, text="Forbidden\n") fobkey = query["key"] fobname = self.d.cfg["fobs"].get(fobkey, "unknown") for item in self.obj_list: if "opener" in item: opener = item if "lock" in item: lock = item if lock["value"] == "close": if fobkey in lock["allowed_fobs"]: log.warning( f"{self.device_name} {fobname}' FOB ({fobkey}) validated for unlocking!" ) await self.d.set_group_value_dict( {lock["knx_group"]: "open"}) lockdelay = lock["delay"] await asyncio.sleep(lock["delay"]) log.warning( f"{self.device_name} lockdelay waited for {lockdelay}s" ) else: log.warning( f"{self.device_name} {fobname}' FOB ({fobkey}) not allowed to unlock!" ) return web.Response(status=403, text="Forbidden\n") if fobkey in opener["allowed_fobs"]: log.info( f"{self.device_name} {fobname}'s FOB validated ({fobkey}) for opening!" ) await self.d.set_group_value_dict({opener["knx_group"]: "on"}) await asyncio.sleep(opener["delay"]) await self.d.set_group_value_dict({opener["knx_group"]: "off"}) return web.Response(text="success\n") else: log.warning( f"{self.device_name} {fobname}'s FOB ({fobkey}) not allowed to open!" ) return web.Response(status=403, text="Forbidden\n") return web.Response(status=404, text="Not found\n")
def start(self): log.info("Started KNX Bus Adapter Deamon.") knx_client = self.loop.run_until_complete( self.linknx_client(self.loop, self.cfg["linknx"])) knx_server_coro = asyncio.start_server( self.knx_server_handler, self.cfg["sys"]["listenHost"], self.cfg["linknx"]["listenPort"], loop=self.loop) knx_server = self.loop.run_until_complete(knx_server_coro) plugins = [] for plugin_config in self.cfg["plugins"]: klass = plugin_config["class"] if klass in PLUGINS and plugin_config["enabled"]: try: plugin_module = import_module(klass) plugin_class = plugin_module.plugin_def() if plugin_class: plugins.append(plugin_class(self, plugin_config)) except ModuleNotFoundError as e: log.warning( "module not found: {}. Plugin '{}' unavailable!". format(e, klass)) tasks = [] for plugin in plugins: task = plugin.run() if task: tasks += task futs = asyncio.gather(*tasks) self.loop.run_until_complete(futs) try: self.loop.run_forever() except KeyboardInterrupt: pass finally: knx_server.close() self.loop.run_until_complete(knx_server.wait_closed()) for plugin in plugins: plugin.quit() self.loop.close()
async def _card_inserted(self, card): key = str(card.value) if key in self.forbidden_fobs: name = self.fobs[key] log.warning( f"{self.device_name} {name}'s FOB forbidden attempt! ({card})") if key in self.fobs: name = self.fobs[key] log.info(f"{self.device_name} {name}'s FOB validated ({card})") if key in self.objs_by_fob: for obj in self.objs_by_fob[key]: knx_group = obj["knx_group"] log.info(f"{self.device_name} opening {knx_group}") await self.d.set_group_value_dict({knx_group: "on"}) else: log.warning( f"{self.device_name} {name}'s FOB forbidden attempt! ({card})" ) else: log.warning( f"{self.device_name} Unknown FOB {card} attempted! delaying for {self.throttle_delay} s!" ) await asyncio.sleep(self.throttle_delay)