1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import std/asyncdispatch
import std/[os, posix, threadpool]
import std/[tables, json, options]
import nmqtt
import types
var mqttContext* {.threadvar.} : MqttCtx
proc CtrlCHook* () {.noconv.} =
echo "Ctrl+C fired! \nStopping now!"
waitFor mqttContext.disconnect()
quit()
proc asyncReadLine*(file: File): Future[string] =
var fut = newFuture[string]()
var flowVar = spawn file.readLine()
addTimer(50, false, proc(fd: AsyncFD): bool =
if flowVar.isReady():
fut.complete(^flowVar)
return true
)
return fut
proc readSerial(serial: string) {.async.} =
let file = open(serial, fmReadWrite)
while true:
try:
let line = await file.asyncReadLine()
let data = parseJson(line)
let json = %* {
"id": data["id"].getStr,
"temperature": data["temp"].getFloat,
"newBattery": data["newBatt"].getBool,
"weakBattery": data["weakBatt"].getBool
}
if (data["hum"].getInt != 106):
json.add("humidity", newJInt(data["hum"].getInt))
if mqttContext.isConnected:
await mqttContext.publish("lacrosse2mqtt/" & json["id"].getStr, $json, 2, true)
await mqttContext.publish("lacrosse2mqtt/" & json["id"].getStr & "/temperature", $json["temperature"], 2, true)
if (data["hum"].getInt != 106):
await mqttContext.publish("lacrosse2mqtt/" & json["id"].getStr & "/humidity", $json["humidity"], 2, true)
await mqttContext.publish("lacrosse2mqtt/" & json["id"].getStr & "/newBattery", $json["newBattery"], 2, true)
await mqttContext.publish("lacrosse2mqtt/" & json["id"].getStr & "/weakBattery", $json["weakBattery"], 2, true)
except JsonParsingError:
continue
except:
let
e = getCurrentException()
msg = getCurrentExceptionMsg()
echo "Got exception ", repr(e), " with message ", msg
proc main () {.async.} =
setControlCHook(CtrlCHook)
onSignal(SIGTERM):
echo "Got SIGTERM! \nStopping now!"
waitFor mqttContext.disconnect()
quit()
var configFile = "./config.json"
if getEnv("CONFIG_PATH") != "":
configFile = getEnv("CONFIG_PATH")
if not fileExists(configFile):
echo "Config file not found"
quit()
let config = parseFile(configFile).to(Config)
mqttContext = newMqttCtx("lacrosse2mqtt")
mqttContext.set_host(config.mqtt.host, config.mqtt.port)
mqttContext.set_verbosity(1)
if (config.mqtt.username.isSome and config.mqtt.password.isSome):
mqttContext.set_auth(config.mqtt.username.get, config.mqtt.password.get)
await mqttContext.start()
asyncCheck readSerial(config.serialDevice)
asyncCheck main()
runForever()