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 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 import asyncdispatch, strutils, json, tables, options, times
import ../types, ../vars, ../utils
import nmqtt

proc setZigbee2MqttLampState* (deviceName: string, value: bool) {.async.} =
  let config    = server.config.devices[deviceName]
  var sendState = "OFF"

  if config.type != Zigbee2MqttLamp:
    return 

  if value == true:
    sendState = "ON"

  await mqttContext.publish("zigbee2mqtt/" & config.deviceName.get & "/set", "{\"state\": \"" & sendState & "\"}")

proc toggleZigbee2MqttLampState* (deviceName: string) {.async.} =
  let config = server.config.devices[deviceName]

  if config.type != Zigbee2MqttLamp:
    return 

  await mqttContext.publish("zigbee2mqtt/" & config.deviceName.get & "/set", "{\"state\": \"TOGGLE\"}")

proc setZigbee2MqttLampBrightness* (deviceName: string, brightness: uint8) {.async.} = 
    let config = server.config.devices[deviceName]

    if config.type != Zigbee2MqttLamp:
      return 

    await mqttContext.publish("zigbee2mqtt/" & config.deviceName.get & "/set", "{\"brightness\": \"" & $brightness & "\"}")

proc setZigbee2MqttLampColor* (deviceName: string, colorX: float, colorY: float) {.async.} = 
    let config = server.config.devices[deviceName]

    if config.type != Zigbee2MqttLamp:
      return 

    await mqttContext.publish("zigbee2mqtt/" & config.deviceName.get & "/set", "{\"color\": {\"X\": \"" & $colorX & "\", \"Y\": \"" & $colorY & "\"}}")

proc setZigbee2MqttLampColorTemperature* (deviceName: string, colorTemperature: int) {.async.} = 
    let config = server.config.devices[deviceName]

    if config.type != Zigbee2MqttLamp:
      return 

    await mqttContext.publish("zigbee2mqtt/" & config.deviceName.get & "/set", "{\"color_temp\": \"" & $colorTemperature & "\"}")

proc updateLamp (topic: string, message: string) =
  try:
    let deviceName = zigbee2mqttDevices[topic]
    let recivedData = parseJson(message)

    server.state[deviceName].lastUpdated = some(toUnix(getTime()))

    if recivedData.hasKey("linkquality"):
      server.state[deviceName].lampLinkquality = recivedData["linkquality"].getInt

    if recivedData.hasKey("state"):
      if recivedData["state"].getStr != "ON":
        server.state[deviceName].lampState = false
      else:
        server.state[deviceName].lampState = true

    if recivedData.hasKey("brightness"):
      server.state[deviceName].lampBrightness = recivedData["brightness"].getInt

    if recivedData.hasKey("color"):
      server.state[deviceName].lampColorX = recivedData["color"]["x"].getFloat
      server.state[deviceName].lampColorY = recivedData["color"]["y"].getFloat

    if recivedData.hasKey("color_temp"):
      server.state[deviceName].lampColorTemperature = recivedData["color_temp"].getInt

    broadcastServerState()

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

proc initZigbee2MqttLamps* () {.async.} =
  for key, device in server.config.devices.pairs():
    if device.type != Zigbee2MqttLamp: continue

    zigbee2mqttDevices["zigbee2mqtt/" & device.deviceName.get] = key
    server.state[key] = DeviceState(type: Zigbee2MqttLamp, lampType: device.lampType)

    await mqttContext.subscribe("zigbee2mqtt/" & device.deviceName.get, 2, updateLamp)