summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md10
-rw-r--r--si7021d73
-rw-r--r--systemd/si7021d.service10
3 files changed, 93 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..aa463e4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,10 @@
+# si7021d
+
+A Linux daemon that reads and returns data from a Si-7021 sensor. Written on Python.
+
+It starts TCP server, accepts command `read` and returns JSON with sensor readings.
+You can send as many `read` commands during one connection as you want.
+
+## License
+
+MIT \ No newline at end of file
diff --git a/si7021d b/si7021d
new file mode 100644
index 0000000..77b3970
--- /dev/null
+++ b/si7021d
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+import smbus
+import argparse
+import asyncio
+import json
+import logging
+
+
+logger = logging.getLogger(__name__)
+bus = None
+lock = asyncio.Lock()
+
+
+async def si7021_read():
+ async with lock:
+ await asyncio.sleep(0.01)
+
+ # these are still blocking... meh
+ raw = bus.read_i2c_block_data(0x40, 0xE3, 2)
+ temp = 175.72 * (raw[0] << 8 | raw[1]) / 65536.0 - 46.85
+
+ raw = bus.read_i2c_block_data(0x40, 0xE5, 2)
+ rh = 125.0 * (raw[0] << 8 | raw[1]) / 65536.0 - 6.0
+
+ return rh, temp
+
+
+async def handle_client(reader, writer):
+ request = None
+ while request != 'quit':
+ try:
+ request = await reader.read(255)
+ if request == b'\x04':
+ break
+ request = request.decode('utf-8').strip()
+ except Exception:
+ break
+
+ if request == 'read':
+ rh, temp = await si7021_read()
+ data = dict(humidity=rh, temp=temp)
+ else:
+ data = dict(error='invalid request')
+
+ writer.write((json.dumps(data) + '\r\n').encode('utf-8'))
+ await writer.drain()
+
+ writer.close()
+
+
+async def run_server(host, port):
+ server = await asyncio.start_server(handle_client, host, port)
+ async with server:
+ logger.info('Server started.')
+ await server.serve_forever()
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--host', type=str, default='127.0.0.1')
+ parser.add_argument('--port', type=int, default=8306)
+ parser.add_argument('--bus', type=int, default=0,
+ help='Bus number (X for /dev/i2c-X)')
+
+ args = parser.parse_args()
+ logging.basicConfig(level=logging.INFO)
+
+ bus = smbus.SMBus(args.bus)
+
+ try:
+ asyncio.run(run_server(args.host, args.port))
+ except KeyboardInterrupt:
+ logging.info('Exiting...')
diff --git a/systemd/si7021d.service b/systemd/si7021d.service
new file mode 100644
index 0000000..8537ca4
--- /dev/null
+++ b/systemd/si7021d.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=si7021 daemon
+After=network-online.target
+
+[Service]
+Restart=on-failure
+ExecStart=/usr/local/bin/si7021d --bus 0 --host 0.0.0.0
+
+[Install]
+WantedBy=multi-user.target