ctucx.git: smartied

[nimlang] smarthome server

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 
import asyncdispatch, asyncnet, tables, json, times, options
import ../types, ../vars, ../utils, ../influx

proc lacrosseHandleLoop (sock: AsyncSocket) {.async.} =
  while true:
    try:
      let line = await sock.recvLine()
      if line == "":
        break

      let msg = parseJson(line).to(LacrosseMessage)

      for key, device in server.config.devices.pairs():
        if device.type != LacrosseTempSensor:
          continue
        if device.id != msg.id:
          continue

        let currentTimestamp = toUnix(getTime())

        if server.state[key].lastUpdated.isSome:
          if (currentTimestamp - server.state[key].lastUpdated.get) < 50:
            break

        if msg.hum == 106:
          server.state[key].humidity = -1
        else:
          server.state[key].humidity = msg.hum
        server.state[key].temperature = msg.temp.isaRound(2)
        server.state[key].weakBattery = bool(msg.weakBatt)
        server.state[key].lastUpdated = some(currentTimestamp)

        if server.config.serverConfig.influx.isSome:
          let config = server.config.serverConfig.influx.get

          if config.sensorsDatabase.isSome:
            var tags, fields = initTable[string, string]()

            tags["device"] = key

            if msg.hum != 106:
              fields["humidity"] = $msg.hum

            fields["temperature"] = $msg.temp.isaRound(2)

            discard await config.insertDatabase(config.sensorsDatabase.get, key, tags, fields, currentTimestamp * 1000000000)


        broadcastServerState()

    except:
      echo "Error[lacrosseHandleLoop]:\n", getCurrentExceptionMsg()

proc lacrosseConnectLoop () {.async.} =
  while true:
    try:
      let config = server.config.serverConfig.lacrosse.get
      lacrosseSocket = await asyncnet.dial(config.host, Port(config.port))
      await lacrosseHandleLoop(lacrosseSocket)
    except:
      lacrosseSocket.close()
      echo "Error[lacrosseConnectLoop]:\n", getCurrentExceptionMsg()
    await sleepAsync(1000)

proc initLacrosseSensors* () =
  for key, device in server.config.devices.pairs():
    if device.type != LacrosseTempSensor:
      continue
    server.state[key] = DeviceState(type: LacrosseTempSensor)

  asyncCheck lacrosseConnectLoop()