diff options
author | dakkar <dakkar@thenautilus.net> | 2024-07-07 15:36:09 +0000 |
---|---|---|
committer | dakkar <dakkar@thenautilus.net> | 2024-07-07 15:38:59 +0000 |
commit | b9121a113e50e81f09b01c0f95bf3fa1010feb56 (patch) | |
tree | e3e677a9c36eb5c5178b1fd36769a7495363d67d | |
download | ats-therm-b9121a113e50e81f09b01c0f95bf3fa1010feb56.tar.gz ats-therm-b9121a113e50e81f09b01c0f95bf3fa1010feb56.tar.bz2 ats-therm-b9121a113e50e81f09b01c0f95bf3fa1010feb56.zip |
start
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | README.md | 9 | ||||
-rw-r--r-- | requirements.txt | 3 | ||||
-rwxr-xr-x | scan.py | 71 | ||||
-rwxr-xr-x | therm.openrc | 19 |
5 files changed, 107 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3724229 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*~ +/venv/ +/*.out +/*.err +/*.pid diff --git a/README.md b/README.md new file mode 100644 index 0000000..05ef966 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Install + +```bash +python -m venv ./venv +. ./venv/bin/activate +pip install -r requirements.txt +``` + +see also https://github.com/pvvx/ATC_MiThermometer diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..39ec0de --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +atc-mi-interface +asyncio +asyncio_simple_http_server @@ -0,0 +1,71 @@ +#!/usr/bin/env python +import asyncio +from asyncio_simple_http_server import HttpServer, uri_mapping, HttpHeaders, HttpResponse +from datetime import datetime, timezone +from bleak import BleakScanner +from functools import partial +from atc_mi_interface import general_format, atc_mi_advertising_format + +fields=['temperature','humidity','battery_level','battery_v'] + +def write_out_prometheus(collected): + f = open("metrics", "w", encoding="utf-8") + for field in fields: + print("# HELP therm_{0} {0}\n# TYPE therm_{0} gauge".format(field),file=f) + for mac in collected: + print("therm_{0}{{mac=\"{1}\"}} {2:f}".format(field,mac,collected[mac][field][0]),file=f) + +class Prom: + collected = {} + + @uri_mapping('/metrics') + def expose(self) -> HttpResponse: + output="" + for field in fields: + output = output + "# HELP therm_{0} {0}\n# TYPE therm_{0} gauge\n".format(field) + for mac in self.collected: + output = output + "therm_{0}{{mac=\"{1}\"}} {2:f}\n".format( + field, mac, self.collected[mac][field][0] + ) + + headers = HttpHeaders() + headers.set('Content-type', 'text/plain; version=0.0.4; charset=utf-8; escaping=values') + return HttpResponse(200, headers, output.encode('utf-8')) + +async def main(): + stop_event = asyncio.Event() + http_server = HttpServer() + + handler=Prom() + http_server.add_handler(handler) + + async def detection_callback(device, advertisement_data): + format_label, adv_data = atc_mi_advertising_format(advertisement_data) + if not adv_data: + return + mac_address = bytes.fromhex(device.address.replace(":", "")) + atc_mi_data = general_format.parse( + adv_data, + mac_address=mac_address, + bindkey=None, + ) + + data={ + "timestamp": datetime.now(timezone.utc).isoformat(), + "temperature": atc_mi_data.search_all("^temperature"), + "humidity": atc_mi_data.search_all("^humidity"), + "battery_level": atc_mi_data.search_all("^battery_level"), + "battery_v": atc_mi_data.search_all("^battery_v"), + "MAC": atc_mi_data.search_all("^MAC$"), + } + handler.collected[data["MAC"][0]]=data + + await http_server.start('10.111.0.66',9003) + + async with BleakScanner( + detection_callback=partial(detection_callback) + ) as scanner: + await http_server.serve_forever() + print("Stopped") + +asyncio.run(main()) diff --git a/therm.openrc b/therm.openrc new file mode 100755 index 0000000..7aa3d36 --- /dev/null +++ b/therm.openrc @@ -0,0 +1,19 @@ +#!/sbin/openrc-run + +thisdir="$(dirname "$(readlink -f "$1")")" + +description="XIAOMI Mijia prometheus exporter" +directory="$thisdir" +command="/usr/bin/env VIRTUAL_ENV='${thisdir}/venv' PATH='${thisdir}/venv/bin:/bin:/usr/bin' ./scan.py" +pidfile="${thisdir}/ats-therm.pid" +command_background=true +command_user=dakkar +output_log="${thisdir}/scan.out" +error_log="${thisdir}/scan.err" +name="ats-therm" +procname="python" + +depend() { + need localmount net + after bootmisc +} |