]> average.org Git - tbcncollector.git/commitdiff
Initial code import
authorEugene Crosser <crosser@average.org>
Tue, 9 Jul 2024 20:53:44 +0000 (22:53 +0200)
committerEugene Crosser <crosser@average.org>
Tue, 9 Jul 2024 21:10:41 +0000 (23:10 +0200)
13 files changed:
.gitignore [new file with mode: 0644]
README.md [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/default [new file with mode: 0644]
debian/install [new file with mode: 0644]
debian/postinst [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/source/format [new file with mode: 0644]
debian/tbcncollector.service [new file with mode: 0644]
setup.py [new file with mode: 0644]
tbcncollector/__main__.py [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..5179099
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..2d27138
--- /dev/null
@@ -0,0 +1,5 @@
+tbcncollector (0.01) experimental; urgency=low
+
+  * Initial version
+
+ -- Eugene Crosser <crosser@average.org>  Tue, 09 Jul 2024 22:38:11 +0200
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..babdb48
--- /dev/null
@@ -0,0 +1,25 @@
+Source: tbcncollector
+Maintainer: Eugene Crosser <crosser@average.org>
+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 (file)
index 0000000..0f76107
--- /dev/null
@@ -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 (file)
index 0000000..5b7ef27
--- /dev/null
@@ -0,0 +1,2 @@
+# Environment for tbcncollector
+OPTIONS=""
diff --git a/debian/install b/debian/install
new file mode 100644 (file)
index 0000000..f53ee3b
--- /dev/null
@@ -0,0 +1 @@
+README.md var/lib/tbcncollector
diff --git a/debian/postinst b/debian/postinst
new file mode 100644 (file)
index 0000000..c3a3048
--- /dev/null
@@ -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 (executable)
index 0000000..98153f8
--- /dev/null
@@ -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 (file)
index 0000000..89ae9db
--- /dev/null
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/debian/tbcncollector.service b/debian/tbcncollector.service
new file mode 100644 (file)
index 0000000..b09fc08
--- /dev/null
@@ -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 (file)
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<src>.*) \((?P<version>.*)\) (?P<suite>.*); .*",
+        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 (file)
index 0000000..4b47152
--- /dev/null
@@ -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())