From f718a80d57565ef41ee3f25e61894cc16aa89f20 Mon Sep 17 00:00:00 2001 From: Eugene Crosser Date: Tue, 9 Jul 2024 22:53:44 +0200 Subject: [PATCH] Initial code import --- .gitignore | 8 +++++ README.md | 1 + debian/changelog | 5 +++ debian/control | 25 +++++++++++++ debian/copyright | 21 +++++++++++ debian/default | 2 ++ debian/install | 1 + debian/postinst | 9 +++++ debian/rules | 8 +++++ debian/source/format | 1 + debian/tbcncollector.service | 16 +++++++++ setup.py | 23 ++++++++++++ tbcncollector/__main__.py | 70 ++++++++++++++++++++++++++++++++++++ 13 files changed, 190 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 debian/changelog create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/default create mode 100644 debian/install create mode 100644 debian/postinst create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 debian/tbcncollector.service create mode 100644 setup.py create mode 100644 tbcncollector/__main__.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5179099 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +**/__pycache__ +debian/*debhelper* +debian/*.substvars +debian/files +debian/tbcncollector/ +.pybuild +build +tbcncollector.egg-info/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..f640c98 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Daemon to collect beacon data from ThermoBeacon units and store in sqlite diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..2d27138 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +tbcncollector (0.01) experimental; urgency=low + + * Initial version + + -- Eugene Crosser Tue, 09 Jul 2024 22:38:11 +0200 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..babdb48 --- /dev/null +++ b/debian/control @@ -0,0 +1,25 @@ +Source: tbcncollector +Maintainer: Eugene Crosser +Section: misc +Priority: optional +Standards-Version: 4.5.1 +X-Python-Version: >= 3.6 +Homepage: http://www.average.org/tbcncollector +Build-Depends: black, + debhelper-compat (= 12), + dh-python, + mypy, + pylint, + python3-all, + python3-setuptools, + python3-bleak + +Package: tbcncollector +Architecture: all +Section: python +Depends: adduser, + python3-bleak, + ${misc:Depends}, + ${python3:Depends} +Description: Daemon to collect data from ThermoBeacons + Stores beacon data: temperature and humidity in sqlite diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..0f76107 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,21 @@ +License: MIT + +Copyright (c) 2022 Eugene Crosser + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/debian/default b/debian/default new file mode 100644 index 0000000..5b7ef27 --- /dev/null +++ b/debian/default @@ -0,0 +1,2 @@ +# Environment for tbcncollector +OPTIONS="" diff --git a/debian/install b/debian/install new file mode 100644 index 0000000..f53ee3b --- /dev/null +++ b/debian/install @@ -0,0 +1 @@ +README.md var/lib/tbcncollector diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 0000000..c3a3048 --- /dev/null +++ b/debian/postinst @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e +adduser --system --group --home /var/lib/tbcncollector tbcncollector +install --owner tbcncollector --group tbcncollector --directory /var/lib/tbcncollector + +#DEBHELPER# + +exit 0 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..98153f8 --- /dev/null +++ b/debian/rules @@ -0,0 +1,8 @@ +#!/usr/bin/make -f + +export PYBUILD_NAME=tbcncollector +#export PYBUILD_BEFORE_TEST=cp -r mypystubs {build_dir} +#export PYBUILD_AFTER_TEST=rm -rf {build_dir}/mypystubs + +%: + dh $@ --with python3 --buildsystem pybuild diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/debian/tbcncollector.service b/debian/tbcncollector.service new file mode 100644 index 0000000..b09fc08 --- /dev/null +++ b/debian/tbcncollector.service @@ -0,0 +1,16 @@ +[Unit] +Description=ThermoBeacon Collector Service + +[Service] +Type=simple +EnvironmentFile=-/etc/default/tbcncollector +ExecStart=python3 -m tbcncollector $OPTIONS +KillSignal=INT +Restart=on-failure +StandardOutput=journal +StandardError=inherit +User=tbcncollector +Group=tbcncollector + +[Install] +WantedBy=multi-user.target diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..30df4cc --- /dev/null +++ b/setup.py @@ -0,0 +1,23 @@ +from setuptools import setup +from re import findall + +with open("debian/changelog", "r") as clog: + _, version, _ = findall( + r"(?P.*) \((?P.*)\) (?P.*); .*", + clog.readline().strip(), + )[0] + +setup( + name="tbcncollector", + version=version, + description="Daemon to collect reports from ThermoBeacon devices", + url="http://www.average.org/tbcncollector/", + author="Eugene Crosser", + author_email="crosser@average.org", + install_requires=["bleak"], + license="MIT", + packages=[ + "tbcncollector", + ], + long_description=open("README.md").read(), +) diff --git a/tbcncollector/__main__.py b/tbcncollector/__main__.py new file mode 100644 index 0000000..4b47152 --- /dev/null +++ b/tbcncollector/__main__.py @@ -0,0 +1,70 @@ +""" TermoBeacon Collector daemon """ + +import asyncio +from sys import argv +from sqlite3 import connect +from struct import unpack +from time import time + +from bleak import BleakScanner + +db = None +INIT = ( + "create table if not exists autoinc(num int)", + "insert into autoinc(num) select 0 where not exists" + " (select 1 from autoinc)", + "create table if not exists data(dt int, id int, addr text, batt float," + " temp float, humid float, tminc int, rssi int, primary key(dt, id))" + " without rowid", + "create temp trigger before insert on data begin" + " update autoinc set num=num+1;" + " end", +) +lastcommit = 0.0 + +def detection_callback(dev, data): + global lastcommit + # print("address", dev.address, "name", dev.name, "rssi", data.rssi) + if dev.address.startswith("A3:E4:"): + for k, v in data.manufacturer_data.items(): + if len(v) == 18: + b, t, h, x, y, z = unpack("HHHBBB", v[8:17]) + tm = (z<<16) + (y<<8) + x + dic = {"addr": dev.address, + "batt": b/1000, + "temp": t/16, + "humid": h/16, + "time": tm, + "rssi": data.rssi, + } + # bat 2.3 is empty, 3.1 is full + # print(dic) + db.execute("""\ + insert into data (dt, id, addr, batt, temp, humid, tminc) + values (unixepoch(), (select num from autoinc), + :addr, :batt, :temp, :humid, :time)""", + dic) + now = time() + if now - lastcommit > 100.0: + db.commit() + lastcommit = now + +async def main(): + async with BleakScanner(detection_callback=detection_callback): + await asyncio.Future() + +async def shutdown(): + db.commit() + db.close() + print("Shutdown complete") + +if __name__ == "__main__": + dbname = argv[1] if len(argv) == 2 else "/var/lib/tbcncollector/raw.db" + db = connect(dbname) + for cmd in INIT: + db.execute(cmd) + lastcommit = time() + try: + asyncio.run(main()) + except KeyboardInterrupt: + asyncio.run(shutdown()) -- 2.43.0