summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorctucx <c@ctu.cx>2020-09-14 16:20:59 +0200
committerctucx <c@ctu.cx>2020-09-14 16:20:59 +0200
commit9c93e45919cabbbdf3cf99d1a0ee2f8b7bb9788a (patch)
tree900300aa10ed17d0cbc3f6865d28743745ea2167
parentb9b9e730a25b881e822be8a0ad3ab4c787f99361 (diff)
downloadnimtradfri-9c93e45919cabbbdf3cf99d1a0ee2f8b7bb9788a.tar.gz
nimtradfri-9c93e45919cabbbdf3cf99d1a0ee2f8b7bb9788a.tar.bz2
nimtradfri-9c93e45919cabbbdf3cf99d1a0ee2f8b7bb9788a.zip
update
-rw-r--r--coapClient.nim32
-rw-r--r--helpers.nim3
-rw-r--r--mappings.nim38
-rw-r--r--test.nim13
-rw-r--r--tradfri.nim107
-rw-r--r--types.nim62
6 files changed, 206 insertions, 49 deletions
diff --git a/coapClient.nim b/coapClient.nim
index e6c75f4..ade4349 100644
--- a/coapClient.nim
+++ b/coapClient.nim
@@ -1,25 +1,25 @@
import osproc, json
type
- CoapResponse* = object
- successful*: bool
- data*: JsonNode
- message*: string
+ CoapException* = object of ValueError
-proc makeCoapRequest* (host: string, port: int, reqMethod: string, user: string, password: string, endpoint: string) :CoapResponse =
- let reqResult = execProcess("coap-client", args=["-B", "2", "-m", reqMethod, "-u", user, "-k", password, "coaps://" & host & ":" & $port & endpoint], options={poUsePath})
+proc makeCoapRequest* (host: string, port: int, reqMethod: string, user: string, password: string, endpoint: string, reqPayload: JsonNode): JsonNode =
+ var arguments = @["-B", "2", "-m", reqMethod, "-u", user, "-k", password]
+
+ if reqMethod == "put":
+ arguments.add("-e")
+ arguments.add($reqPayload)
+
+ arguments.add("coaps://" & host & ":" & $port & endpoint)
+
+ let reqResult = execProcess("coap-client", args = arguments, options = {poUsePath})
try:
- result = CoapResponse(
- successful: true,
- data: parseJson(reqResult),
- message: ""
- )
+ if reqMethod == "put" and reqResult == "":
+ return %* {}
+
+ return parseJson(reqResult)
except JsonParsingError:
- result = CoapResponse(
- successful: false,
- data: %* {},
- message: reqResult
- )
+ raise newException(CoapException, reqResult)
diff --git a/helpers.nim b/helpers.nim
new file mode 100644
index 0000000..85c21e3
--- /dev/null
+++ b/helpers.nim
@@ -0,0 +1,3 @@
+proc boolToInt* (value: bool): int =
+ if value != true: return 0
+ else: return 1
diff --git a/mappings.nim b/mappings.nim
new file mode 100644
index 0000000..a0bb1ae
--- /dev/null
+++ b/mappings.nim
@@ -0,0 +1,38 @@
+import tables
+
+let endpoints* = {
+ "devices": "/15001/",
+ "groups": "/15004/",
+ "scenes": "/15005/",
+ "notifications": "/15006/",
+ "smart_tasks": "/15010/"
+}.toTable
+
+let devices* = {
+ "MotionSensor": "3300",
+ "Lightbulb": "3311",
+ "Plug": "3312",
+ "Blind": "15015"
+}.toTable
+
+let parameters* = {
+ "DeviceName": "9001",
+ "DeviceCreatedAt": "9002",
+ "DeviceId": "9003",
+ "DeviceAlive": "9019",
+ "DeviceLastSeen": "9020",
+
+ "PowerState": "5850",
+ "DimmerValue": "5851",
+
+ "ColorHex": "5706",
+ "Hue": "5707",
+ "Saturation": "5708",
+ "ColorX": "5709",
+ "ColorY": "5710",
+ "ColorTemperature": "5711",
+ "TransitionTime": "5712",
+
+ "blindTrigger": "5523",
+ "BlindPosition": "5536",
+}.toTable
diff --git a/test.nim b/test.nim
index c3af19b..f7f3733 100644
--- a/test.nim
+++ b/test.nim
@@ -1,4 +1,4 @@
-import types, tradfri, json, tables
+import types, tradfri, json
let tradfriGateway = newTradfriGateway(
host = "192.168.100.225",
@@ -8,9 +8,12 @@ let tradfriGateway = newTradfriGateway(
)
-let devices = tradfriGateway.getDevices()
+let devices = tradfriGateway.getDevices()
+let jsonDevices = %* devices
-for id, device in devices.pairs:
- let device = %* device
+echo pretty jsonDevices
- echo $id & ": " & pretty device
+echo devices[2].operateDevice(TradfriDeviceAction(
+ kind: TradfriDeviceActionType(0),
+ lightPowerState: false
+))
diff --git a/tradfri.nim b/tradfri.nim
index 4d312dd..e8caa59 100644
--- a/tradfri.nim
+++ b/tradfri.nim
@@ -1,10 +1,9 @@
-import json, strutils, tables, options
+import json, strutils, options, tables
-import coapClient, types
+import coapClient, types, mappings, helpers
-
-proc newTradfrigateway* (host: string, port: int, user: string, pass: string): TradfriGatewayObj =
- return TradfriGatewayObj(
+proc newTradfrigateway* (host: string, port: int, user: string, pass: string): TradfriGatewayRef =
+ return TradfriGatewayRef(
host: host,
port: port,
user: user,
@@ -109,11 +108,11 @@ proc parseTradfriDevice (data: JsonNode): TradfriDevice =
return TradfriDevice(
`type`: deviceType,
+ id: data["9003"].getInt,
name: data["9001"].getStr,
alive: data["9019"].getBool,
createdAt: data["9002"].getInt,
lastSeen: data["9020"].getInt,
- instanceId: data["9003"].getInt,
state: state,
info: TradfriDeviceInfo(
manufacturer: data["3"]["0"].getStr,
@@ -125,14 +124,94 @@ proc parseTradfriDevice (data: JsonNode): TradfriDevice =
)
)
-proc getDevice* (gatewayObj: TradfriGatewayObj, deviceId: int): TradfriDevice =
- let resp = makeCoapRequest(gatewayObj.host, gatewayObj.port, "get", gatewayObj.user, gatewayObj.pass, "/15001/" & $deviceId )
- return parseTradfriDevice(resp.data)
+proc operateDevice* (device: TradfriDevice, action: TradfriDeviceAction): bool =
+ var requestParams = %* {}
+
+ template CheckDeviceType(typeId: int) =
+ if device.`type` != TradfriDeviceType(typeId):
+ raise newException(ValueError, "Wrong action for this Devicetype")
+
+
+ case action.kind:
+ of LightSetPowerState:
+ CheckDeviceType(2)
+
+ requestParams.add(devices["Lightbulb"],%* [{
+ parameters["PowerState"]: boolToInt(action.lightPowerState),
+ parameters["TransitionTime"]: action.transitionTime
+ }])
+
+ of LightSetBrightness:
+ CheckDeviceType(2)
+
+ requestParams.add(devices["Lightbulb"], %* [{
+ parameters["DimmerValue"]: action.lightBrightness,
+ parameters["TransitionTime"]: action.transitionTime
+ }])
+
+ of LightSetColorHex:
+ CheckDeviceType(2)
+
+ requestParams.add(devices["Lightbulb"], %* [{
+ parameters["ColorHex"]: action.lightColorHex,
+ parameters["TransitionTime"]: action.transitionTime
+ }])
+
+ of LightSetColorXY:
+ CheckDeviceType(2)
+
+ requestParams.add(devices["Lightbulb"], %* [{
+ parameters["ColorX"]: action.lightColorX,
+ parameters["ColorY"]: action.lightColorY,
+ parameters["TransitionTime"]: action.transitionTime
+ }])
+
+ of LightSetHueSaturation:
+ CheckDeviceType(2)
+
+ requestParams.add(devices["Lightbulb"], %* [{
+ parameters["Hue"]: action.lightHue,
+ parameters["Saturatio"]: action.lightSaturation,
+ parameters["TransitionTime"]: action.transitionTime
+ }])
+
+ of LightSetColorTemperature:
+ CheckDeviceType(2)
+
+ requestParams.add(devices["Lightbulb"], %* [{
+ parameters["ColorTemperature"]: action.lightColorTemperature,
+ parameters["TransitionTime"]: action.transitionTime
+ }])
+
+ of PlugSetPowerState:
+ CheckDeviceType(3)
+
+ requestParams.add(devices["Plug"], %* [{
+ parameters["PowerState"]: action.plugPowerState,
+ }])
+
+ of PlugSetDimmerValue:
+ CheckDeviceType(3)
+
+ requestParams.add(devices["Plug"], %* [{
+ parameters["DimmerValue"]: action.plugDimmerValue,
+ }])
+
+
+ discard makeCoapRequest(device.gatewayRef.host, device.gatewayRef.port, "put", device.gatewayRef.user, device.gatewayRef.pass, endpoints["devices"] & $device.id, requestParams)
+
+
+proc getDevice* (gatewayRef: TradfriGatewayRef, deviceId: int): TradfriDevice =
+ let request = makeCoapRequest(gatewayRef.host, gatewayRef.port, "get", gatewayRef.user, gatewayRef.pass, endpoints["devices"] & $deviceId, %* {})
+
+ result = parseTradfriDevice(request)
+ result.gatewayRef = gatewayRef
+
-proc getDevices* (gatewayObj: TradfriGatewayObj): Table[int, TradfriDevice] =
- let resp = makeCoapRequest(gatewayObj.host, gatewayObj.port, "get", gatewayObj.user, gatewayObj.pass, "/15001")
+proc getDevices* (gatewayRef: TradfriGatewayRef): seq[TradfriDevice] =
+ let request = makeCoapRequest(gatewayRef.host, gatewayRef.port, "get", gatewayRef.user, gatewayRef.pass, endpoints["devices"], %* {})
- result = initTable[int, TradfriDevice]()
+ result = newSeq[TradfriDevice]()
- for id in resp.data:
- result.add(id.getInt, getDevice(gatewayObj, id.getInt))
+ for id in request:
+ result.add(getDevice(gatewayRef, id.getInt))
diff --git a/types.nim b/types.nim
index a34d217..60008c6 100644
--- a/types.nim
+++ b/types.nim
@@ -1,12 +1,6 @@
import options
type
- TradfriGatewayObj* = object
- host*: string
- port*: int
- user*: string
- pass*: string
-
TradfriDeviceType* = enum
Remote, slaveRemote, Lightbulb, Plug, motionSensor, signalRepeater, Blind, soundRemote
@@ -16,6 +10,16 @@ type
TradfriLightSpectrum* = enum
RGB, White, None
+ TradfriDeviceActionType* = enum
+ LightSetPowerState, LightSetBrightness, LightSetColorHex, LightSetColorXY, LightSetHueSaturation, LightSetColorTemperature, PlugSetPowerState, PlugSetDimmerValue
+
+
+ TradfriGatewayRef* = object
+ host*: string
+ port*: int
+ user*: string
+ pass*: string
+
TradfriDeviceInfo* = object
manufacturer*: string
modelNumber*: string
@@ -62,11 +66,41 @@ type
soundRemoteSupported*: bool
TradfriDevice* = object
- `type`*: TradfriDeviceType
- name*: string
- alive*: bool
- createdAt*: int
- lastSeen*: int
- instanceId*: int
- info*: TradfriDeviceInfo
- state*: TradfriDeviceState
+ gatewayRef*: TradfriGatewayRef
+ `type`*: TradfriDeviceType
+ id*: int
+ name*: string
+ alive*: bool
+ createdAt*: int
+ lastSeen*: int
+ info*: TradfriDeviceInfo
+ state*: TradfriDeviceState
+
+ TradfriDeviceAction* = object
+ transitionTime*: int
+ case kind*: TradfriDeviceActionType
+ of LightSetPowerState:
+ lightPowerState*: bool
+
+ of LightSetBrightness:
+ lightBrightness*: bool
+
+ of LightSetColorHex:
+ lightColorHex*: string
+
+ of LightSetColorXY:
+ lightColorX*: int
+ lightColorY*: int
+
+ of LightSetHueSaturation:
+ lightHue*: int
+ lightSaturation*: int
+
+ of LightSetColorTemperature:
+ lightColorTemperature*: int
+
+ of PlugSetPowerState:
+ plugPowerState*: bool
+
+ of PlugSetDimmerValue:
+ plugDimmerValue*: int