From 608e70e5de946a79d50ca862556dfd6b7d9c9d49 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 13 Sep 2023 10:49:44 +0200 Subject: [PATCH 01/10] Add KNX Interfacer --- src/interfacers/EmonHubKNXInterfacer.py | 261 ++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 src/interfacers/EmonHubKNXInterfacer.py diff --git a/src/interfacers/EmonHubKNXInterfacer.py b/src/interfacers/EmonHubKNXInterfacer.py new file mode 100644 index 00000000..2e2e3638 --- /dev/null +++ b/src/interfacers/EmonHubKNXInterfacer.py @@ -0,0 +1,261 @@ +import time +import json +import re +import Cargo +import serial +import struct +import asyncio +import concurrent.futures +import threading + +from emonhub_interfacer import EmonHubInterfacer +from xknx import XKNX +from xknx.io import ConnectionConfig, ConnectionType + +from xknx.devices import Light +from xknx.devices import NumericValue +from xknx.devices import RawValue +from xknx.devices import Sensor +from xknx.dpt import DPTArray +from xknx.telegram import GroupAddress, Telegram +from xknx.telegram.apci import GroupValueRead, GroupValueResponse, GroupValueWrite +from xknx.core import ValueReader + +""" +[[KNX]] + Type = EmonHubKNXInterfacer + [[[init_settings]]] + gateway_ip = 192.168.254.40 + port = 3691 + [[[runtimesettings]]] + pubchannels = ToEmonCMS, + read_interval = 10 + validate_checksum = False + nodename = KNX + [[[[meters]]]] + [[[[[compteur]]]]] + group=1/1/1 + eis=DPT-14 + [[[[[[consommationWh]]]]]] + group=10/5/1 + eis=DPT-12 +""" + +"""class EmonHubKNXInterfacer + +KNX interfacer + +""" + +class EmonHubKNXInterfacer(EmonHubInterfacer): + + def __init__(self, name, gateway_ip="127.0.0.1", local_ip="127.0.0.1", port=3671): + """Initialize Interfacer + + """ + # Initialization + super(EmonHubKNXInterfacer, self).__init__(name) + + # This line will stop the default values printing to logfile at start-up + # self._settings.update(self._defaults) + + # Interfacer specific settings + self._KNX_settings = {'read_interval': 10.0, + 'nodename':'KNX', + 'validate_checksum': True, + 'meters':[]} + + self._last_read_time = 0 + + try: + self.loop = asyncio.get_event_loop() + + task = self.loop.create_task(self.initKnx(gateway_ip, local_ip)) + self.loop.run_until_complete(task) + + self.cargoList = {} + + except ModuleNotFoundError as err: + self._log.error(err) + self.ser = False + + + def action(self): + super().action() + + + async def initKnx(self, gateway_ip, local_ip): + connection_config = ConnectionConfig( + connection_type=ConnectionType.TUNNELING, + gateway_ip=gateway_ip, + local_ip = local_ip + ) + + self._log.info("Connect to KNX Gateway : " + gateway_ip) + self.xknx = XKNX(connection_config=connection_config, device_updated_cb=self.device_updated_cb, daemon_mode=False) + + async def startKnx(self): + await self.xknx.start() + + + #@asyncio.coroutine + async def device_updated_cb(self, device): + value = device.resolve_state() + name = device.name + unit = device.unit_of_measurement() + + self._log.debug("Device:" + name + ' <> ' + str(value)) + + namePart = name.split("_") + meter = namePart[0] + key = namePart[1] + + meterObj=self._settings['meters'][meter] + dptConf = meterObj[key] + if 'divider' in dptConf: + divider = dptConf["divider"] + if divider != '': + value = float(value) / float(divider) + + + + result = {} + result[key] = [value,unit] + + + if meter in self.cargoList: + c = self.cargoList[meter] + self.add_result_to_cargo(c, result) + else: + cargoNew = Cargo.new_cargo("", False,[], []) + cargoNew.nodeid = meter + self.cargoList[meter] = cargoNew + self.add_result_to_cargo(cargoNew, result) + + + + def add_result_to_cargo(self, cargo, result): + if result != None: + + for key in result: + cargo.names.append(key) + cargo.realdata.append(result[key][0]) + else: + self._log.debug("Decoded KNX data: None") + + + async def setupSensor(self): + metters = self._settings['meters'] + + self.sensor={} + for metter in metters: + dpPoint = metters[metter] + + for dpKey in dpPoint: + dpConfig = dpPoint[dpKey] + + group = dpConfig["group"] + eis = dpConfig["eis"] + + self.sensor[metter+"_"+dpKey] = Sensor(self.xknx, metter + "_" + dpKey, value_type=eis, group_address_state=group, always_callback=True) + + + + + def add(self, cargo): + self.buffer.storeItem(f) + + + async def waitSensor(self): + pass + + + def read(self): + """Read data and process + + Return data as a list: [NodeID, val1, val2] + + """ + interval = int(self._settings['read_interval']) + if time.time() - self._last_read_time < interval: + return + + self._last_read_time = time.time() + + #self.displayCargo("read") + result = self.cargoList; + self.cargoList ={}; + + return result; + + def start(self): + self._log.info("Start KNX interface") + + task = self.loop.create_task(self.setupSensor()) + self.loop.run_until_complete(task) + + task = self.loop.create_task(self.startKnx()) + self.loop.run_until_complete(task) + + + self.updater = self.Updater(self) + self.updater.start() + + super().start() + + + def set(self, **kwargs): + for key, setting in self._KNX_settings.items(): + # Decide which setting value to use + if key in kwargs: + setting = kwargs[key] + else: + setting = self._KNX_settings[key] + + if key in self._settings and self._settings[key] == setting: + continue + elif key == 'read_interval': + self._log.info("Setting %s read_interval: %s", self.name, setting) + self._settings[key] = float(setting) + continue + elif key == 'nodename': + self._log.info("Setting %s nodename: %s", self.name, setting) + self._settings[key] = str(setting) + continue + elif key == 'validate_checksum': + self._log.info("Setting %s validate_checksum: %s", self.name, setting) + self._settings[key] = True + if setting=='False': + self._settings[key] = False + continue + elif key == 'meters': + self._log.info("Setting %s meters: %s", self.name, json.dumps(setting)) + self._settings['meters'] = {} + for meter in setting: + # default + address = 1 + meter_type = "standard" + records = [] + + self._settings['meters'][meter] = setting[meter] + continue + else: + self._log.warning("'%s' is not valid for %s: %s", setting, self.name, key) + + # include kwargs from parent + super().set(**kwargs) + + + + class Updater(threading.Thread): + def __init__(self, knxIntf): + super().__init__() + self.loop = asyncio.get_event_loop() + self.knxIntf = knxIntf + + pass + + def run(self): + while not self.knxIntf.stop: + self.loop.run_until_complete(asyncio.sleep(1)) + pass From 50d837c6e4de1e4bd75f3f61f87dd68073577a1d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 13 Sep 2023 11:04:00 +0200 Subject: [PATCH 02/10] Add KNX Interfacer --- src/interfacers/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interfacers/__init__.py b/src/interfacers/__init__.py index 4ac9ac0f..f2506594 100644 --- a/src/interfacers/__init__.py +++ b/src/interfacers/__init__.py @@ -27,6 +27,7 @@ "EmonHubRedisInterfacer", "EmonHubSDM120Interfacer", "EmonHubMBUSInterfacer", + "EmonHubKNXInterfacer", "EmonHubMinimalModbusInterfacer", "EmonHubBleInterfacer", "EmonHubGoodWeInterfacer", From 8a3e338d4d9206cd7f82f62dc85067d32360aeaa Mon Sep 17 00:00:00 2001 From: Laurent ARNAL Date: Wed, 13 Sep 2023 11:34:44 +0200 Subject: [PATCH 03/10] Add KNX Interfacer --- src/interfacers/EmonHubKNXInterfacer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/interfacers/EmonHubKNXInterfacer.py b/src/interfacers/EmonHubKNXInterfacer.py index 2e2e3638..68e2b6f8 100644 --- a/src/interfacers/EmonHubKNXInterfacer.py +++ b/src/interfacers/EmonHubKNXInterfacer.py @@ -27,6 +27,7 @@ [[[init_settings]]] gateway_ip = 192.168.254.40 port = 3691 + local_ip = 192.168.254.1 [[[runtimesettings]]] pubchannels = ToEmonCMS, read_interval = 10 From df70f0503f8645130644a3a672a3ff44b1106282 Mon Sep 17 00:00:00 2001 From: Laurent ARNAL Date: Wed, 13 Sep 2023 15:18:42 +0200 Subject: [PATCH 04/10] Add some documentation for KNX interfacer --- conf/interfacer_examples/KNX/knx.emonhub.conf | 37 +++++++++++ conf/interfacer_examples/KNX/readme.md | 66 +++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 conf/interfacer_examples/KNX/knx.emonhub.conf create mode 100644 conf/interfacer_examples/KNX/readme.md diff --git a/conf/interfacer_examples/KNX/knx.emonhub.conf b/conf/interfacer_examples/KNX/knx.emonhub.conf new file mode 100644 index 00000000..7fa53b74 --- /dev/null +++ b/conf/interfacer_examples/KNX/knx.emonhub.conf @@ -0,0 +1,37 @@ +[[KNX]] + Type = EmonHubKNXInterfacer + [[[init_settings]]] + gateway_ip = 192.168.254.1 + port = 3671 + [[[runtimesettings]]] + pubchannels = ToEmonCMS, + read_interval = 5 + validate_checksum = False + nodeid=1 + nodename = KNX + [[[[meters]]]] + [[[[[compteur]]]]] + [[[[[[voltage]]]]]] + group=10/0/1 + eis=DPT-14 + [[[[[[intensite]]]]]] + group=10/1/1 + eis=DPT-14 + [[[[[[puissance]]]]]] + group=10/2/1 + eis=DPT-14 + [[[[[[consommation]]]]]] + group=10/3/1 + eis=DPT-12 + [[[[[[consommationWh]]]]]] + group=10/5/1 + eis=DPT-12 + [[[[[compteurNew]]]]] + [[[[[[voltage]]]]]] + group=10/0/2 + eis=DPT-14 + [[[[[[intensite]]]]]] + group=10/1/2 + eis=DPT-14 + + diff --git a/conf/interfacer_examples/KNX/readme.md b/conf/interfacer_examples/KNX/readme.md new file mode 100644 index 00000000..12f57226 --- /dev/null +++ b/conf/interfacer_examples/KNX/readme.md @@ -0,0 +1,66 @@ +### KNX Reader to read value from knx group using a knx Gateway + +KNX is a international standard for home automation. +KNX is based on a bus, where each device can communicate using knx group. +A Knx group is address using a knx address group notation of the form x/y/z. + +To configure this interfacers, you would need: + +to fill the global init_settings, mainly: + +- **gateway_ip** The ip address of your ip gateway device. +- **port** The port of the gateway device (3671 is the default). +- **local_ip** If your server have multiple ip interface, indicate the ip of the interface link to the gateway device. + +In runtimeseetings, you will have to list the group you want to read. +You can make some grouping by indicating a devicename under the meters section + +Each device can contains single or many group read section of the form: + [[[[[[groupName]]]]]] + group=10/0/1 + eis=DPT-14 + +- **groupName:** Will indicate the name of the group, indicate what you want, it will be the name of the input in emoncms inputs. +- **group:** The address of the group +- **eis:** The KNX type use for this group (please refer to KNX official documentation for the list). + + +```text +[[KNX]] + Type = EmonHubKNXInterfacer + [[[init_settings]]] + gateway_ip = 192.168.254.1 + port = 3671 + [[[runtimesettings]]] + pubchannels = ToEmonCMS, + read_interval = 5 + validate_checksum = False + nodeid=1 + nodename = KNX + [[[[meters]]]] + [[[[[compteur]]]]] + [[[[[[voltage]]]]]] + group=10/0/1 + eis=DPT-14 + [[[[[[intensite]]]]]] + group=10/1/1 + eis=DPT-14 + [[[[[[puissance]]]]]] + group=10/2/1 + eis=DPT-14 + [[[[[[consommation]]]]]] + group=10/3/1 + eis=DPT-12 + [[[[[[consommationWh]]]]]] + group=10/5/1 + eis=DPT-12 + [[[[[compteurNew]]]]] + [[[[[[voltage]]]]]] + group=10/0/2 + eis=DPT-14 + [[[[[[intensite]]]]]] + group=10/1/2 + eis=DPT-14 + + + From 87f55540fd037b8baf2b866328746dec2423520a Mon Sep 17 00:00:00 2001 From: Laurent ARNAL Date: Thu, 5 Dec 2024 15:29:23 +0100 Subject: [PATCH 05/10] Update to support last xknx versions --- src/interfacers/EmonHubKNXInterfacer.py | 28 ++++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/interfacers/EmonHubKNXInterfacer.py b/src/interfacers/EmonHubKNXInterfacer.py index 68e2b6f8..458de73b 100644 --- a/src/interfacers/EmonHubKNXInterfacer.py +++ b/src/interfacers/EmonHubKNXInterfacer.py @@ -92,24 +92,28 @@ async def initKnx(self, gateway_ip, local_ip): local_ip = local_ip ) - self._log.info("Connect to KNX Gateway : " + gateway_ip) - self.xknx = XKNX(connection_config=connection_config, device_updated_cb=self.device_updated_cb, daemon_mode=False) + self._log.trace("Connect to KNX Gateway : " + gateway_ip) + self.xknx = XKNX(connection_config=connection_config, connection_state_changed_cb = self.connection_state_changed_cb,device_updated_cb=self.device_updated_cb, daemon_mode=False) async def startKnx(self): - await self.xknx.start() + try: + await self.xknx.start() + except Exception: + self._log.error("KNX Error start") + def connection_state_changed_cb(self, state): + self._log.trace("KNX CnxUpdate:" + state) - #@asyncio.coroutine - async def device_updated_cb(self, device): + def device_updated_cb(self, device): value = device.resolve_state() name = device.name unit = device.unit_of_measurement() self._log.debug("Device:" + name + ' <> ' + str(value)) - namePart = name.split("_") - meter = namePart[0] - key = namePart[1] + pos = name.index("_") + meter = name[0:pos] + key = name[pos+1:] meterObj=self._settings['meters'][meter] dptConf = meterObj[key] @@ -142,7 +146,7 @@ def add_result_to_cargo(self, cargo, result): cargo.names.append(key) cargo.realdata.append(result[key][0]) else: - self._log.debug("Decoded KNX data: None") + self._log.info("Decoded KNX data: None") async def setupSensor(self): @@ -158,7 +162,9 @@ async def setupSensor(self): group = dpConfig["group"] eis = dpConfig["eis"] + self._log.debug("add Sensors:" + metter+"_"+dpKey + ' <> ' + group) self.sensor[metter+"_"+dpKey] = Sensor(self.xknx, metter + "_" + dpKey, value_type=eis, group_address_state=group, always_callback=True) + self.xknx.devices.async_add(self.sensor[metter+"_"+dpKey]) @@ -177,10 +183,12 @@ def read(self): Return data as a list: [NodeID, val1, val2] """ + interval = int(self._settings['read_interval']) if time.time() - self._last_read_time < interval: return + self._last_read_time = time.time() #self.displayCargo("read") @@ -203,7 +211,7 @@ def start(self): self.updater.start() super().start() - + def set(self, **kwargs): for key, setting in self._KNX_settings.items(): From 0ae220c048741408ce4832fc8958f4a8a7ad559f Mon Sep 17 00:00:00 2001 From: Laurent ARNAL Date: Thu, 5 Dec 2024 17:51:00 +0100 Subject: [PATCH 06/10] fix knx error --- src/interfacers/EmonHubKNXInterfacer.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/interfacers/EmonHubKNXInterfacer.py b/src/interfacers/EmonHubKNXInterfacer.py index 458de73b..81203071 100644 --- a/src/interfacers/EmonHubKNXInterfacer.py +++ b/src/interfacers/EmonHubKNXInterfacer.py @@ -92,24 +92,27 @@ async def initKnx(self, gateway_ip, local_ip): local_ip = local_ip ) - self._log.trace("Connect to KNX Gateway : " + gateway_ip) + self._log.debug("Connect to KNX Gateway : " + gateway_ip) self.xknx = XKNX(connection_config=connection_config, connection_state_changed_cb = self.connection_state_changed_cb,device_updated_cb=self.device_updated_cb, daemon_mode=False) async def startKnx(self): try: await self.xknx.start() - except Exception: - self._log.error("KNX Error start") + except Exception as err: + self._log.error("KNX Error start:") + self._log.error(err); def connection_state_changed_cb(self, state): - self._log.trace("KNX CnxUpdate:" + state) + self._log.debug("KNX CnxUpdate:" ) + self._log.debug(state) + def device_updated_cb(self, device): value = device.resolve_state() name = device.name unit = device.unit_of_measurement() - self._log.debug("Device:" + name + ' <> ' + str(value)) + self._log.info("Device:" + name + ' <> ' + str(value)) pos = name.index("_") meter = name[0:pos] From 265b00f13c9236a85ca16bf0ae0f8a7622a270b4 Mon Sep 17 00:00:00 2001 From: Laurent ARNAL Date: Wed, 18 Feb 2026 10:38:29 +0100 Subject: [PATCH 07/10] review event loop for compatibility with last python version --- src/interfacers/EmonHubKNXInterfacer.py | 42 ++++++++++++++++++------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/interfacers/EmonHubKNXInterfacer.py b/src/interfacers/EmonHubKNXInterfacer.py index 81203071..1cdc47c1 100644 --- a/src/interfacers/EmonHubKNXInterfacer.py +++ b/src/interfacers/EmonHubKNXInterfacer.py @@ -69,10 +69,16 @@ def __init__(self, name, gateway_ip="127.0.0.1", local_ip="127.0.0.1", port=3671 self._last_read_time = 0 try: - self.loop = asyncio.get_event_loop() + #self.loop = asyncio.get_event_loop() + self.loop = asyncio.new_event_loop() + self._loop_thread = threading.Thread(target=self._run_loop, name=f"{name}-asyncio", daemon=True) + self._loop_thread.start() + + fut = asyncio.run_coroutine_threadsafe(self.initKnx(gateway_ip, local_ip), self.loop) + fut.result() # raise si erreur - task = self.loop.create_task(self.initKnx(gateway_ip, local_ip)) - self.loop.run_until_complete(task) + #task = self.loop.create_task(self.initKnx(gateway_ip, local_ip)) + #self.loop.run_until_complete(task) self.cargoList = {} @@ -81,6 +87,10 @@ def __init__(self, name, gateway_ip="127.0.0.1", local_ip="127.0.0.1", port=3671 self.ser = False + def _run_loop(self): + asyncio.set_event_loop(self.loop) + self.loop.run_forever() + def action(self): super().action() @@ -112,7 +122,7 @@ def device_updated_cb(self, device): name = device.name unit = device.unit_of_measurement() - self._log.info("Device:" + name + ' <> ' + str(value)) + #self._log.info("Device:" + name + ' <> ' + str(value)) pos = name.index("_") meter = name[0:pos] @@ -173,7 +183,8 @@ async def setupSensor(self): def add(self, cargo): - self.buffer.storeItem(f) + #self.buffer.storeItem(f) + self.buffer.storeItem(cargo) async def waitSensor(self): @@ -203,18 +214,27 @@ def read(self): def start(self): self._log.info("Start KNX interface") - task = self.loop.create_task(self.setupSensor()) - self.loop.run_until_complete(task) + # Setup sensors + start KNX dans la loop + asyncio.run_coroutine_threadsafe(self.setupSensor(), self.loop).result() + asyncio.run_coroutine_threadsafe(self.startKnx(), self.loop).result() + + #task = self.loop.create_task(self.setupSensor()) + #self.loop.run_until_complete(task) - task = self.loop.create_task(self.startKnx()) - self.loop.run_until_complete(task) + #task = self.loop.create_task(self.startKnx()) + #self.loop.run_until_complete(task) - self.updater = self.Updater(self) - self.updater.start() + #self.updater = self.Updater(self) + #self.updater.start() super().start() + def close(self): + # si EmonHub appelle close/stop, tu peux stopper proprement + self._stop_evt.set() + if self.loop.is_running(): + self.loop.call_soon_threadsafe(self.loop.stop) def set(self, **kwargs): for key, setting in self._KNX_settings.items(): From c87abf6cd05962ff67c71ef226b38cbccacef4e5 Mon Sep 17 00:00:00 2001 From: Laurent ARNAL Date: Wed, 18 Feb 2026 11:13:38 +0100 Subject: [PATCH 08/10] add doc for knx --- docs/emonhub-interfacers.md | 67 +++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/docs/emonhub-interfacers.md b/docs/emonhub-interfacers.md index 62350c00..fb8ffd3f 100644 --- a/docs/emonhub-interfacers.md +++ b/docs/emonhub-interfacers.md @@ -48,6 +48,7 @@ For a full list of interfacers, view GitHub source [https://github.com/openenerg - [RFM69 Interfacer](https://github.com/openenergymonitor/emonhub/tree/master/conf/interfacer_examples/RF69) - [Plum ecoNET 300 Interfacer](https://github.com/openenergymonitor/emonhub/tree/master/conf/interfacer_examples/Econet300) - [E+E Environmental Modbus Sensors Interfacer](https://github.com/openenergymonitor/emonhub/tree/master/conf/interfacer_examples/E%2BE) +- [KNX Interfacer]((https://github.com/openenergymonitor/emonhub/tree/master/conf/interfacer_examples/KNX) ## Using emonHub @@ -614,3 +615,69 @@ EmonHub also makes this data available via MQTT `emon/samsung-ashp` ### Modbus Renogy See example config:
[EmonHub Github: Renogy.emonhub.conf](https://github.com/openenergymonitor/emonhub/blob/master/conf/interfacer_examples/Renogy/Renogy.emonhub.conf) + + +#### KNX + +KNX Reader enable to read value from KNX group on KNX Bus using a KNX Gateway + +KNX is a international standard for home automation. +KNX is based on a bus, where each device can communicate using knx group. +A Knx group is address using a knx address group notation of the form x/y/z. + +To configure this interfacers, you would need: + +to fill the global init_settings, mainly: + +- **gateway_ip** The ip address of your ip gateway device. +- **port** The port of the gateway device (3671 is the default). +- **local_ip** If your server have multiple ip interface, indicate the ip of the interface link to the gateway device. + +In runtimeseetings, you will have to list the group you want to read. +You can make some grouping by indicating a devicename under the meters section + +Each device can contains single or many group read section of the form: + [[[[[[groupName]]]]]] + group=10/0/1 + eis=DPT-14 + +- **groupName:** Will indicate the name of the group, indicate what you want, it will be the name of the input in emoncms inputs. +- **group:** The address of the group +- **eis:** The KNX type use for this group (please refer to KNX official documentation for the list). + + +```text +[[KNX]] + Type = EmonHubKNXInterfacer + [[[init_settings]]] + gateway_ip = 192.168.254.1 + port = 3671 + [[[runtimesettings]]] + pubchannels = ToEmonCMS, + read_interval = 5 + validate_checksum = False + nodeid=1 + nodename = KNX + [[[[meters]]]] + [[[[[compteur]]]]] + [[[[[[voltage]]]]]] + group=10/0/1 + eis=DPT-14 + [[[[[[intensite]]]]]] + group=10/1/1 + eis=DPT-14 + [[[[[[puissance]]]]]] + group=10/2/1 + eis=DPT-14 + [[[[[[consommation]]]]]] + group=10/3/1 + eis=DPT-12 + [[[[[[consommationWh]]]]]] + group=10/5/1 + [[[[[compteurNew]]]]] + [[[[[[voltage]]]]]] + group=10/0/2 + eis=DPT-14 + [[[[[[intensite]]]]]] + group=10/1/2 + eis=DPT-14 From f2204769f5cd969d3666e7bfc46ce664c3afc68c Mon Sep 17 00:00:00 2001 From: Laurent ARNAL Date: Wed, 18 Feb 2026 11:48:13 +0100 Subject: [PATCH 09/10] clean code comment --- src/interfacers/EmonHubKNXInterfacer.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/interfacers/EmonHubKNXInterfacer.py b/src/interfacers/EmonHubKNXInterfacer.py index 1cdc47c1..ee26de93 100644 --- a/src/interfacers/EmonHubKNXInterfacer.py +++ b/src/interfacers/EmonHubKNXInterfacer.py @@ -57,9 +57,6 @@ def __init__(self, name, gateway_ip="127.0.0.1", local_ip="127.0.0.1", port=3671 # Initialization super(EmonHubKNXInterfacer, self).__init__(name) - # This line will stop the default values printing to logfile at start-up - # self._settings.update(self._defaults) - # Interfacer specific settings self._KNX_settings = {'read_interval': 10.0, 'nodename':'KNX', @@ -69,7 +66,6 @@ def __init__(self, name, gateway_ip="127.0.0.1", local_ip="127.0.0.1", port=3671 self._last_read_time = 0 try: - #self.loop = asyncio.get_event_loop() self.loop = asyncio.new_event_loop() self._loop_thread = threading.Thread(target=self._run_loop, name=f"{name}-asyncio", daemon=True) self._loop_thread.start() @@ -77,9 +73,6 @@ def __init__(self, name, gateway_ip="127.0.0.1", local_ip="127.0.0.1", port=3671 fut = asyncio.run_coroutine_threadsafe(self.initKnx(gateway_ip, local_ip), self.loop) fut.result() # raise si erreur - #task = self.loop.create_task(self.initKnx(gateway_ip, local_ip)) - #self.loop.run_until_complete(task) - self.cargoList = {} except ModuleNotFoundError as err: @@ -122,8 +115,6 @@ def device_updated_cb(self, device): name = device.name unit = device.unit_of_measurement() - #self._log.info("Device:" + name + ' <> ' + str(value)) - pos = name.index("_") meter = name[0:pos] key = name[pos+1:] @@ -183,7 +174,6 @@ async def setupSensor(self): def add(self, cargo): - #self.buffer.storeItem(f) self.buffer.storeItem(cargo) @@ -205,7 +195,6 @@ def read(self): self._last_read_time = time.time() - #self.displayCargo("read") result = self.cargoList; self.cargoList ={}; @@ -218,16 +207,6 @@ def start(self): asyncio.run_coroutine_threadsafe(self.setupSensor(), self.loop).result() asyncio.run_coroutine_threadsafe(self.startKnx(), self.loop).result() - #task = self.loop.create_task(self.setupSensor()) - #self.loop.run_until_complete(task) - - #task = self.loop.create_task(self.startKnx()) - #self.loop.run_until_complete(task) - - - #self.updater = self.Updater(self) - #self.updater.start() - super().start() def close(self): From fca4984586020efda4870fbb2c5668c5f1e8e66c Mon Sep 17 00:00:00 2001 From: Laurent ARNAL Date: Wed, 18 Feb 2026 15:00:57 +0100 Subject: [PATCH 10/10] fix for @alexandrecuer review Signed-off-by: Laurent ARNAL --- conf/interfacer_examples/KNX/readme.md | 3 ++ docs/emonhub-interfacers.md | 3 ++ src/interfacers/EmonHubKNXInterfacer.py | 46 +++++-------------------- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/conf/interfacer_examples/KNX/readme.md b/conf/interfacer_examples/KNX/readme.md index 12f57226..c4561d23 100644 --- a/conf/interfacer_examples/KNX/readme.md +++ b/conf/interfacer_examples/KNX/readme.md @@ -1,5 +1,8 @@ ### KNX Reader to read value from knx group using a knx Gateway +KNX Reader is base on the use of the xknkx library: +https://pypi.org/project/xknx/ + KNX is a international standard for home automation. KNX is based on a bus, where each device can communicate using knx group. A Knx group is address using a knx address group notation of the form x/y/z. diff --git a/docs/emonhub-interfacers.md b/docs/emonhub-interfacers.md index fb8ffd3f..67808e7d 100644 --- a/docs/emonhub-interfacers.md +++ b/docs/emonhub-interfacers.md @@ -621,6 +621,9 @@ See example config:
[EmonHub Github: Renogy.emonhub.conf](https://github.com/ KNX Reader enable to read value from KNX group on KNX Bus using a KNX Gateway +KNX Reader is base on the use of the xknkx library: +https://pypi.org/project/xknx/ + KNX is a international standard for home automation. KNX is based on a bus, where each device can communicate using knx group. A Knx group is address using a knx address group notation of the form x/y/z. diff --git a/src/interfacers/EmonHubKNXInterfacer.py b/src/interfacers/EmonHubKNXInterfacer.py index ee26de93..5c7443a3 100644 --- a/src/interfacers/EmonHubKNXInterfacer.py +++ b/src/interfacers/EmonHubKNXInterfacer.py @@ -84,10 +84,6 @@ def _run_loop(self): asyncio.set_event_loop(self.loop) self.loop.run_forever() - def action(self): - super().action() - - async def initKnx(self, gateway_ip, local_ip): connection_config = ConnectionConfig( connection_type=ConnectionType.TUNNELING, @@ -145,7 +141,6 @@ def device_updated_cb(self, device): def add_result_to_cargo(self, cargo, result): if result != None: - for key in result: cargo.names.append(key) cargo.realdata.append(result[key][0]) @@ -157,29 +152,17 @@ async def setupSensor(self): metters = self._settings['meters'] self.sensor={} - for metter in metters: - dpPoint = metters[metter] - - for dpKey in dpPoint: - dpConfig = dpPoint[dpKey] - - group = dpConfig["group"] - eis = dpConfig["eis"] - - self._log.debug("add Sensors:" + metter+"_"+dpKey + ' <> ' + group) - self.sensor[metter+"_"+dpKey] = Sensor(self.xknx, metter + "_" + dpKey, value_type=eis, group_address_state=group, always_callback=True) - self.xknx.devices.async_add(self.sensor[metter+"_"+dpKey]) + + for meter_key, metter in metters.items(): + for conf_key, config in metter.items(): + group = config["group"] + eis = config["eis"] - - def add(self, cargo): - self.buffer.storeItem(cargo) - - - async def waitSensor(self): - pass - + self._log.info("add Sensors:" + meter_key +"_"+ conf_key + ' <> ' + group) + self.sensor[meter_key + "_" + conf_key] = Sensor(self.xknx, meter_key + "_" + conf_key, value_type=eis, group_address_state=group, always_callback=True) + self.xknx.devices.async_add(self.sensor[meter_key + "_" + conf_key]) def read(self): """Read data and process @@ -258,15 +241,4 @@ def set(self, **kwargs): - class Updater(threading.Thread): - def __init__(self, knxIntf): - super().__init__() - self.loop = asyncio.get_event_loop() - self.knxIntf = knxIntf - - pass - - def run(self): - while not self.knxIntf.stop: - self.loop.run_until_complete(asyncio.sleep(1)) - pass + \ No newline at end of file