diff --git a/.env b/.env index 9caf140..8627511 100644 --- a/.env +++ b/.env @@ -1,5 +1,6 @@ KNX_GATEWAY_IP=10.0.0.36 KNX_TOPOLOGY=export-addresses.csv +LOG_ONLY=1 INFLUX_BUCKET=my_bucket INFLUX_ORG=example.com diff --git a/.gitignore b/.gitignore index 6ff67dc..16289cc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -venv/ +.venv/ requirements/ __py*/ .env diff --git a/README.md b/README.md index 9fc6a9b..43e8edf 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,9 @@ pip install --no-cache-dir -r .requirements.txt You need to configure the following environment variables: - `KNX_GATEWAY_IP` is the address of the gateway/router. Default value is *10.0.0.36* -- `KNX_TOPOLOGY` is the CSV export of the group adresses. It's used to map the monitored data with types and store the proper values. It defaults to *export-addresses.csv*. PLease see below how to export the right format. +- `KNX_TOPOLOGY` is the CSV export of the group adresses. It's used to map the monitored data with types and store the proper values. It defaults to *export-addresses.csv*. Please see below how to export the right format. + +- `LOG_ONLY` only logs the collected information, doesn't push to InfluxDB. It defaults to *1* - `INFLUX_BUCKET` - the bucket to store the data. It defaults to *my_bucket* - `INFLUX_ORG` - the organisation (defined when you initialise the bucket). Defaults to *example.com* diff --git a/db.py b/db.py index dbcc18c..3e21eb4 100644 --- a/db.py +++ b/db.py @@ -17,9 +17,13 @@ write_api = client.write_api(write_options=SYNCHRONOUS) def publish_measurement(value): - try: - p = influxdb_client.Point(f'KNX-{value["type"]}').tag("name", f'{value["name"]}').tag("destination", f'{value["destination"]}').tag("description", f'{value["description"]}').field("value", value["value"]) - write_api.write(bucket=bucket, org=org, record=p) - except Exception as e: - print(f"Could not send value {value} to {url}") - print(e) \ No newline at end of file + # Only push to Influx if not logging + if (os.environ.get('LOG_ONLY', "0") != "1"): + try: + p = influxdb_client.Point(f'KNX-{value["type"]}').tag("name", f'{value["name"]}').tag("destination", f'{value["destination"]}').tag("description", f'{value["description"]}').field("value", value["value"]) + write_api.write(bucket=bucket, org=org, record=p) + except Exception as e: + print(f"Could not send value {value} to {url}") + print(e) + else: + print(f"debug: {value}") \ No newline at end of file diff --git a/export-addresses.csv b/export-addresses.csv index 43bbbbd..899e88b 100644 --- a/export-addresses.csv +++ b/export-addresses.csv @@ -1,5 +1,41 @@ "Group name";"Address";"Central";"Unfiltered";"Description";"DatapointType";"Security" -"Cellar - HVAC";"0/-/-";"";"";"";"";"Auto" +"Global - Building Based";"0/-/-";"";"";"";"";"Auto" +"Timers";"0/0/-";"";"";"";"";"Auto" +"Current Time";"0/0/1";"";"";"";"DPST-10-1";"Auto" +"Current date";"0/0/2";"";"";"";"DPST-11-1";"Auto" +"Ventilation";"0/1/-";"";"";"";"";"Auto" +"Ventilation SW";"0/1/0";"";"";"";"DPT-5";"Auto" +"Ventilation FB";"0/1/1";"";"";"";"DPT-5";"Auto" +"External setpoint SW";"0/1/2";"";"";"";"";"Auto" +"External setpoint FB";"0/1/3";"";"";"";"";"Auto" +"Boost SW";"0/1/4";"";"";"";"DPT-1";"Auto" +"Boost FB";"0/1/5";"";"";"";"";"Auto" +"Boost time SW";"0/1/6";"";"";"";"DPT-7";"Auto" +"Boost time FB";"0/1/7";"";"";"";"";"Auto" +"Temperature profile SW";"0/1/8";"";"";"";"DPT-5";"Auto" +"Temperature profile FB";"0/1/9";"";"";"";"DPT-5";"Auto" +"Temperature profile mode SW";"0/1/10";"";"";"";"DPT-5";"Auto" +"Temperature profile mode FB";"0/1/11";"";"";"";"DPT-5";"Auto" +"Away function SW";"0/1/12";"";"";"";"DPT-1";"Auto" +"Away function FB";"0/1/13";"";"";"";"";"Auto" +"Ventilator preset 0 (Away) SW";"0/1/14";"";"";"";"DPT-1";"Auto" +"Ventilator preset 1 SW";"0/1/15";"";"";"";"DPT-1";"Auto" +"Ventilator preset 2 SW";"0/1/16";"";"";"";"DPT-1";"Auto" +"Ventilator preset 3 SW";"0/1/17";"";"";"";"DPT-1";"Auto" +"Ventilator preset 0 (Away) FB";"0/1/18";"";"";"";"DPT-1";"Auto" +"Ventilator preset 1 FB";"0/1/19";"";"";"";"DPT-1";"Auto" +"Ventilator preset 2 FB";"0/1/20";"";"";"";"DPT-1";"Auto" +"Ventilator preset 3 FB";"0/1/21";"";"";"";"DPT-1";"Auto" +"Auto mode SW";"0/1/22";"";"";"";"DPT-1";"Auto" +"Auto mode FB";"0/1/23";"";"";"";"DPT-1";"Auto" +"ComfoCool SW";"0/1/24";"";"";"";"DPT-1";"Auto" +"ComfoCool FB";"0/1/25";"";"";"";"DPT-1";"Auto" +"Ventilator preset SW";"0/1/26";"";"";"";"DPT-5";"Auto" +"Ventilator preset FB";"0/1/27";"";"";"";"DPT-5";"Auto" +"Temperature - Supply FB";"0/1/28";"";"";"";"DPT-9";"Auto" +"Temperature - Exhaust FB";"0/1/29";"";"";"";"DPT-9";"Auto" +"Temperature - Extract FB";"0/1/30";"";"";"";"DPT-9";"Auto" +"Airflow FB";"0/1/31";"";"";"";"DPT-13";"Auto" "Media - HVAC";"0/3/-";"";"";"";"";"Auto" "Valve1-1 Media [CTEMP 1.3.10]";"0/3/6";"";"";"Wellness Lounge H";"DPST-9-1";"Auto" "Valve1-1 Media [SETPOINT TEMP]";"0/3/7";"";"";"Wellness Lounge H";"DPST-9-1";"Auto" @@ -11,12 +47,6 @@ "Valve1-2 Lounge [CMD]";"0/5/4";"";"";"Wellness HVAC - Lounge";"DPST-5-1";"Auto" "Valve1-2 Lounge [OP]";"0/5/5";"";"";"Wellness HVAC - Lounge";"DPST-20-102";"Auto" "Ground floor";"2/-/-";"";"";"";"";"Auto" -"Dining";"2/3/-";"";"";"";"";"Auto" -"Lights1-1[78] Dining all lights [SW]";"2/3/4";"";"";"Dining room All";"DPST-1-1";"Auto" -"Lights1-1[78] Dining all lights [FB]";"2/3/5";"";"";"Dining room All";"DPST-1-1";"Auto" -"Living";"2/6/-";"";"";"";"";"Auto" -"Lights1-[16,18,20,21] Living all [SW]";"2/6/8";"";"";"Living room All";"DPST-1-1";"Auto" -"Lights1-[16,18,20,21] Living all [FB]";"2/6/9";"";"";"Living room All";"DPST-1-1";"Auto" "First floor - HVAC";"3/-/-";"";"";"";"";"Auto" "Master bed - HVAC";"3/1/-";"";"";"";"";"Auto" "Valve2-2 Master bed [CTEMP 2.2.1]";"3/1/14";"";"";"Master HVAC";"DPST-9-1";"Auto" @@ -89,9 +119,8 @@ Sender done via NodeRed.";"DPST-1-1";"Auto" "Lights1-6 Media mid FB";"5/1/11";"";"";"";"DPST-1-1";"Auto" "Lights1-7 Media front SW";"5/1/12";"";"";"";"DPST-1-1";"Auto" "Lights1-7 Media front FB";"5/1/13";"";"";"";"DPST-1-1";"Auto" -"Shutter";"5/2/-";"";"";"";"";"Auto" -"Heating";"5/3/-";"";"";"";"";"Auto" -"Timers";"5/4/-";"";"";"";"";"Auto" +"HVAC";"5/2/-";"";"";"";"";"Auto" +"LED night reduction";"5/4/-";"";"";"";"";"Auto" "GF - Building Based";"6/-/-";"";"";"";"";"Auto" "Scene";"6/0/-";"";"";"";"";"Auto" "Lights1-2[34] Shower, all lights [SW]";"6/0/0";"";"";"Shower both lamps switching";"DPST-1-1";"Auto" @@ -101,6 +130,10 @@ Feedback received via NodeRed";"DPST-1-1";"Auto" "Lights1-1[45] Kitchen, all lights [FB]";"6/0/3";"";"";"";"DPST-1-1";"Auto" "Lights[1-13,2-13] Hallway [SW]";"6/0/4";"";"";"";"DPST-1-1";"Auto" "Lights[1-13,2-13] Hallway [FB]";"6/0/5";"";"";"";"DPST-1-1";"Auto" +"Lights1-1[78] Dining all lights [SW]";"6/0/6";"";"";"Dining room All";"DPST-1-1";"Auto" +"Lights1-1[78] Dining all lights [FB]";"6/0/7";"";"";"Dining room All";"DPST-1-1";"Auto" +"Lights1-[16,18,20,21] Living all [SW]";"6/0/8";"";"";"Living room All";"DPST-1-1";"Auto" +"Lights1-[16,18,20,21] Living all [FB]";"6/0/9";"";"";"Living room All";"DPST-1-1";"Auto" "Lighting";"6/1/-";"";"";"";"";"Auto" "Lights1-8 Guest, Ceiling lamp [SW]";"6/1/0";"";"";"Guest ceiling lamp switching";"DPST-1-1";"Auto" "Lights1-8 Guest, Ceiling lamp [FB]";"6/1/1";"";"";"Guest ceiling lamp switching feedback";"DPST-1-1";"Auto" @@ -156,8 +189,7 @@ Feedback received via NodeRed";"DPST-1-1";"Auto" "Valve1-X Stairway [CTEMP 2.1.6]";"6/3/23";"";"";"Stairway GF";"DPST-9-1";"Auto" "Valve1-X Slider [CTEMP 2.1.12]";"6/3/24";"";"";"Slider";"DPST-9-1";"Auto" "Valve1-X Kitchen front [CTEMP 2.1.14]";"6/3/25";"";"";"Kitchen front";"DPST-9-1";"Auto" -"Timers";"6/4/-";"";"";"";"";"Auto" -"Current Time";"6/4/0";"";"";"";"DPST-10-1";"Auto" +"LED night reduction";"6/4/-";"";"";"";"";"Auto" "Led night reduction - Guest";"6/4/1";"";"";"";"DPST-1-1";"Auto" "Led night reduction - Hallway";"6/4/2";"";"";"";"DPST-1-1";"Auto" "Led night reduction - Shower";"6/4/3";"";"";"";"DPST-1-1";"Auto" diff --git a/knx_monitor.py b/knx_monitor.py index 38fffa2..e2d26c8 100644 --- a/knx_monitor.py +++ b/knx_monitor.py @@ -23,6 +23,7 @@ mapping = {} async def telegram_received_cb(telegram): """Do something with the received telegram.""" val = parse_message(config, mapping, telegram) + publish_measurement(val) diff --git a/structure.py b/structure.py index b670f26..2bc5087 100644 --- a/structure.py +++ b/structure.py @@ -1,18 +1,24 @@ import csv import json -import json_fix +from os import environ -import xknx.remote_value -import xknx -from xknx.dpt import DPT2ByteFloat, DPTBinary, DPTTime, DPTValue1ByteUnsigned +from xknx.dpt import DPT2ByteFloat, DPTBinary, DPTTime, DPTValue1ByteUnsigned, DPT4ByteUnsigned from datetime import datetime class DPST: def __init__(self, str): vals = str.split('-') + if len(vals) <= 1: + self.major = "1" + self.minor = "0" + return + self.major = vals[1] - self.minor = vals[2] + if len(vals) >=3: + self.minor = vals[2] + else: + self.minor = "0" def __str__(self): return f"DPST {self.major}.{self.minor}" @@ -50,6 +56,7 @@ def init_value_mapping(): config['9'] = { "value": DPT2ByteFloat, "type": "number" } config['10'] = { "value": DPTTime, "type": "time" } config['5'] = { "value": DPTValue1ByteUnsigned, "type": "number" } + config['13'] = { "value": DPT4ByteUnsigned, "type": "number" } return config @@ -103,5 +110,5 @@ if __name__ == '__main__': from dotenv import load_dotenv dotenv_path = join(dirname(__file__), '.env') load_dotenv(dotenv_path) - config = load_structure(os.environ.get('KNX_TOPOLOGY')) + config = load_structure(environ.get('KNX_TOPOLOGY')) print(json.dumps(config["6/4/0"], indent=2))