diff options
author | Evgeny Zinoviev <me@ch1p.io> | 2021-08-03 02:03:07 +0300 |
---|---|---|
committer | Evgeny Zinoviev <me@ch1p.io> | 2021-08-03 02:03:07 +0300 |
commit | 79d2d87e32bde6a8347cbf7098026c65dec2b755 (patch) | |
tree | 349bc231a2c14082a21dff8ddd98047aae94c333 | |
parent | 7428042d6fcc97ccb13db1876b60a961af15d610 (diff) |
update readme
-rw-r--r-- | README.md | 172 |
1 files changed, 170 insertions, 2 deletions
@@ -1,10 +1,178 @@ # si7021d -A Linux daemon that reads and returns data from a Si-7021 sensor. Written on Python. +This is a Linux daemon that reads and returns data from a Si-7021 sensor. It's written +on Python, uses asyncio and was tested on Python 3.9. 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. +## Why? + +It was created for AwesomeWM widget. The daemon is running on some Orange Pi board +with Si7021 sensor attached, the widget periodically pings it and draws temperature +and relative humidity on a wibox. + +Sample widget code: +```lua +local wibox = require("wibox") +local gears = require('gears') +local awful = require("awful") +local naughty = require("naughty") +local theme = require("./themes/default/theme") +local json = require('json') +local util = require('./util') +local lgi = require('lgi') +local Gio = lgi.Gio + +local SI7021_IP = '192.168.1.212' +local SI7021_PORT = 8306 +local UPDATE_FREQUENCY = 2 + +local timer +local timer_started = false + + +----------------- +-- widgets stuff + +local function create_image(file) + image_widget = wibox.widget.imagebox() + image_widget:set_resize(false) + image_widget:set_image(file) + return image_widget +end + +local function wrap_image(image, top) + margin = wibox.container.margin() + margin:set_left(16) + margin:set_top(top) + margin:set_right(5) + margin:set_widget(image) + return margin +end + +local function create_text(placeholder) + text_widget = wibox.widget.textbox() + text_widget:set_font(theme.font) + if placeholder then + text_widget:set_text(placeholder) + end + return text_widget +end + + +local temp_image = create_image(awful.util.getdir("config") .. "/icons/fs_01.png") +local temp_text = create_text('Connecting...') +local temp_image_wrapped = wrap_image(temp_image, 8) + +local hum_image = create_image(awful.util.getdir("config") .. "/icons/humidity.png") +local hum_text = create_text() +local hum_image_wrapped = wrap_image(hum_image, 7) + +local layout = wibox.layout.fixed.horizontal() +layout:add(temp_image_wrapped) +layout:add(temp_text) + +local hum_visible = false +local function hum_hide() + if not hum_visible then return end + layout:remove_widgets(hum_image_wrapped) + layout:remove_widgets(hum_text) + hum_visible = false +end + +local function hum_show() + if hum_visible then return end + layout:add(hum_image_wrapped) + layout:add(hum_text) + hum_visible = true +end + + +-------------------- +--- networking stuff + +local _socket +local _tcp_conn +local _istream +local _ostream + +local function sensor_get_status() + _istream = _tcp_conn:get_input_stream() + _ostream = _tcp_conn:get_output_stream() + + _ostream:async_write("read\r\n") + + local buf = '' + while true do + local bytes = _istream:async_read_bytes(4096) + + -- it returns nil on error (such as disconnect) + if bytes == nil then return nil end + if not bytes then break end + + local len = bytes:get_size() + if len > 0 then + buf = bytes.data + break + end + end + + return true, buf +end + +local function sensor_update() + Gio.Async.start(function() + local ok, body = sensor_get_status() + + -- handle errors + if ok == nil then + temp_text:set_text("Connection error") + hum_hide() + + _socket = nil + + timer:stop() + timer_started = false + + return + end + + local status = json.decode(body) + + hum_show() + temp_text:set_text('' .. util.round(status.temp, 1) .. ' °C') + hum_text:set_text('' .. util.round(status.humidity, 1) .. ' %') + end)() +end + +local function sensor_connect() + _socket = Gio.SocketClient.new() + _socket:set_timeout(1) + + _tcp_conn = _socket:async_connect_to_host(SI7021_IP, SI7021_PORT) + + if not _tcp_conn then + _socket = nil + temp_text:set_text('Connection error') + return + end + + timer = gears.timer({ timeout = UPDATE_FREQUENCY }) + timer:connect_signal("timeout", sensor_update) + + timer:start() + timer_started = true + + sensor_update() +end + + +Gio.Async.start(sensor_connect)() + +return layout +``` + ## License -MIT
\ No newline at end of file +MIT |