diff options
author | Daniel Friesel <derf@finalrewind.org> | 2022-04-18 10:52:01 +0200 |
---|---|---|
committer | Daniel Friesel <derf@finalrewind.org> | 2022-04-18 10:52:01 +0200 |
commit | 87f3d0c12c21963a7a9e6056c4d67dce3cf1980f (patch) | |
tree | de952453d1a3e6d639f8157ebc8d82626080bd9d /sds011.lua |
initial commit
Diffstat (limited to 'sds011.lua')
-rw-r--r-- | sds011.lua | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/sds011.lua b/sds011.lua new file mode 100644 index 0000000..a528720 --- /dev/null +++ b/sds011.lua @@ -0,0 +1,74 @@ +local sds011 = {} + +local c_head = 0xaa +local c_tail = 0xab +local c_id = 0xb4 + +local c_read = 0x00 +local c_write = 0x01 + +local c_report_mode = 0x02 +local c_active = 0x00 +local c_passive = 0x01 + +local c_query = 0x04 + +local c_sleepcmd = 0x06 +local c_sleep = 0x00 +local c_work = 0x01 +local c_workperiod = 0x08 + +function sds011.finish_cmd(cmd) + cmd = cmd .. string.char(0xff, 0xff) + local checksum = 0 + for i = 3, string.len(cmd) do + checksum = (checksum + string.byte(cmd, i)) % 256 + end + cmd = cmd .. string.char(checksum, c_tail) + return cmd +end + +function sds011.set_report_mode(active) + local cmd = string.char(c_head, c_id, c_report_mode, c_write) + if active then + cmd = cmd .. string.char(c_active) + else + cmd = cmd .. string.char(c_passive) + end + cmd = cmd .. string.char(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + return sds011.finish_cmd(cmd) +end + +function sds011.sleep(sleep) + local cmd = string.char(c_head, c_id, c_sleepcmd, c_write) + if sleep then + cmd = cmd .. string.char(c_sleep) + else + cmd = cmd .. string.char(c_work) + end + cmd = cmd .. string.char(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + return sds011.finish_cmd(cmd) +end + +function sds011.set_work_period(period) + -- period == 0 : continuous operation, about one measurement per second + -- period > 0 : about one measurement every <period> minutes, fan is turned off in-between + if period < 0 or period > 30 then + return + end + local cmd = string.char(c_head, c_id, c_workperiod, c_write, period) + cmd = cmd .. string.char(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + return sds011.finish_cmd(cmd) +end + +function sds011.parse_frame(data) + local header, command, pm25l, pm25h, pm10l, pm10h, id1, id2, sum, tail = struct.unpack("BBBBBBBBBB", data) + if header ~= c_head or command ~= 0xc0 or (pm25l + pm25h + pm10l + pm10h + id1 + id2) % 256 ~= sum or tail ~= c_tail then + return nil + end + pm25 = pm25h * 256 + pm25l + pm10 = pm10h * 256 + pm10l + return pm25 / 10, pm25 % 10, pm10 / 10, pm10 % 10 +end + +return sds011 |