ctucx.git: smartied

[nimlang] smarthome server

commit ae65e3bdd49810eb502aaeb830831d6907c6938f
parent 0f7d1e7016cb63a963bd953808ba57b59f13b09c
Author: Milan Pässler <me@pbb.lc>
Date: Wed, 1 Jan 2020 17:25:09 +0100

add prometheus
4 files changed, 60 insertions(+), 2 deletions(-)
M
config.json
|
5
+++--
A
src/frontend_prometheus.nim
|
54
++++++++++++++++++++++++++++++++++++++++++++++++++++++
M
src/smartied.nim
|
2
++
M
src/types.nim
|
1
+
diff --git a/config.json b/config.json
@@ -127,9 +127,10 @@
 	"httpPort": 5000,
 	"tcpPort": 5001,
 	"wsPort": 5002,
-	"modbusAddr": "192.168.1.1",
+	"prometheusPort": 5003,
+	"modbusAddr": "10.0.0.1",
 	"modbusPort": 502,
-	"lacrosseAddr": "192.168.1.1",
+	"lacrosseAddr": "10.0.0.1",
 	"lacrossePort": 2342,
 	"powermeterUpdateIntervalSec": 20,
 	"accessToken": "penis123"
diff --git a/src/frontend_prometheus.nim b/src/frontend_prometheus.nim
@@ -0,0 +1,54 @@
+import asynchttpserver
+import asyncdispatch
+import util
+import types
+import sequtils
+import json
+import vars
+import tables
+
+proc addVal(resp: var string, name: string, key: string, val: string, lastUpdated: string) =
+  resp = resp & name & "{"
+  resp = resp & "device=\"" & key & "\""
+  resp = resp & "} "
+  resp = resp & val
+  resp = resp & " "
+  resp = resp & lastUpdated
+  resp = resp & "\n"
+
+proc fmtBool(b: bool): string =
+  if b:
+    return "1"
+  else:
+    return "0"
+
+proc processPrometheusClient(req: Request) {.async,gcsafe.} =
+  if req.reqMethod == HttpGet:
+    if req.headers.hasKey("Authorization") and req.headers["Authorization"] == "Bearer " & server.config.accessToken:
+      var resp = ""
+      for key, device in server.config.devices.pairs():
+        if device.type == PowerMeter:
+          resp.addVal("powermeter_import", key, $(server.state[key].import), $(server.state[key].lastUpdated))
+          resp.addVal("powermeter_cosphi", key, $(server.state[key].cosphi), $(server.state[key].lastUpdated))
+          resp.addVal("powermeter_power", key, $(server.state[key].power), $(server.state[key].lastUpdated))
+          resp.addVal("powermeter_frequency", key, $(server.state[key].frequency), $(server.state[key].lastUpdated))
+          resp.addVal("powermeter_voltage", key, $(server.state[key].voltage), $(server.state[key].lastUpdated))
+
+        if device.type == RelayBoard:
+          for i, val in server.state[key].relays:
+            resp.addVal("relayboard_relay", key & "\",relay=\"" & $(i), fmtBool(val), "")
+
+        if device.type == LacrosseTempSensor:
+          resp.addVal("lacrossetempsensor_temperature", key, $(server.state[key].temperature), $(server.state[key].lastUpdated2))
+          resp.addVal("lacrossetempsensor_humidity", key, $(server.state[key].humidity), $(server.state[key].lastUpdated2))
+          resp.addVal("lacrossetempsensor_weakbattery", key, fmtBool(server.state[key].weakBattery), $(server.state[key].lastUpdated2))
+
+      await req.respond(Http200, resp)
+    else:
+      await req.respond(Http401, "401 Unauthorized")
+  else:
+    await req.respond(Http405, "405 Method Not Allowed")
+
+proc servePrometheus*() {.async.} =
+  var prometheusServer = newAsyncHttpServer()
+  await prometheusServer.serve(Port(server.config.prometheusPort), processPrometheusClient)
diff --git a/src/smartied.nim b/src/smartied.nim
@@ -2,6 +2,7 @@ import asyncdispatch
 import frontend_tcp
 import frontend_ws
 import frontend_http
+import frontend_prometheus
 import backend_powermeter
 import backend_relayboard
 import backend_lacrosse

@@ -24,6 +25,7 @@ proc main() {.async.} =
   asyncCheck serveTcp()
   asyncCheck serveWs()
   asyncCheck serveHttp()
+  asyncCheck servePrometheus()
 
   runForever()
 
diff --git a/src/types.nim b/src/types.nim
@@ -24,6 +24,7 @@ type Config* = object
   tcpPort*: uint16
   wsPort*: uint16
   httpPort*: uint16
+  prometheusPort*: uint16
   modbusAddr*: string
   modbusPort*: uint16
   lacrosseAddr*: string