meine Lösung besteht im Wesentlichen aus einem Flow, der die Kommunikation mit dem SHM via SEMP übernimmt:
Code: Alles auswählen
[{"id":"fd609b25.8db358","type":"tab","label":"SEMP","disabled":false,"info":""},{"id":"536ca306.607634","type":"udp out","z":"fd609b25.8db358","name":"","addr":"239.255.255.250","iface":"","port":"1900","ipv":"udp4","outport":"","base64":false,"multicast":"broad","x":680,"y":240,"wires":[]},{"id":"af0b6433.185d58","type":"http in","z":"fd609b25.8db358","name":"","url":"/user/semp/description.xml","method":"get","upload":false,"swaggerDoc":"","x":190,"y":380,"wires":[["e9ac8582.6fe8b"]]},{"id":"1368d191.eb110e","type":"http in","z":"fd609b25.8db358","name":"","url":"/user/semp/","method":"get","upload":false,"swaggerDoc":"","x":140,"y":440,"wires":[["46e599de.9250c"]]},{"id":"7cac974a.1da69","type":"http in","z":"fd609b25.8db358","name":"","url":"/user/semp/DeviceInfo/","method":"get","upload":false,"swaggerDoc":"","x":180,"y":500,"wires":[["6c7f7886.6aa618"]]},{"id":"323b3f25.57c588","type":"http in","z":"fd609b25.8db358","name":"","url":"/user/semp/DeviceStatus/","method":"get","upload":false,"swaggerDoc":"","x":190,"y":560,"wires":[["8adb5e08.9fff5"]]},{"id":"d109b718.a503f","type":"http in","z":"fd609b25.8db358","name":"","url":"/user/semp/PlanningRequest/","method":"get","upload":false,"swaggerDoc":"","x":200,"y":620,"wires":[["1233c579.729363"]]},{"id":"6c7f7886.6aa618","type":"function","z":"fd609b25.8db358","name":"DeviceInfo","func":"msg.payload = {\n Device2EM: {\n $: {\n xmlns: \"http://www.sma.de/communication/schema/SEMP/v1\"\n },\n DeviceInfo: {}\n }\n}\nmsg.payload.Device2EM.DeviceInfo = flow.get(\"DeviceInfo\");\nclearTimeout(context.get(\"timeout\"));\ncontext.set(\"timeout\",setTimeout(() => node.status({}),60000));\nnode.status({fill:\"blue\",shape:\"dot\",text:\"active\"});\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":500,"wires":[["4120ad27.f387dc"]]},{"id":"46e599de.9250c","type":"function","z":"fd609b25.8db358","name":"All","func":"msg.payload = {\n Device2EM: {\n $: {\n xmlns: \"http://www.sma.de/communication/schema/SEMP/v1\"\n },\n DeviceInfo: [{}],\n DeviceStatus: [{}],\n PlanningRequest: [{}]\n }\n}\nmsg.payload.Device2EM.DeviceInfo = flow.get(\"DeviceInfo\");\nmsg.payload.Device2EM.DeviceStatus = flow.get(\"DeviceStatus\");\nmsg.payload.Device2EM.PlanningRequest = flow.get(\"PlanningRequest\");\nclearTimeout(context.get(\"timeout\"));\ncontext.set(\"timeout\",setTimeout(() => node.status({}),60000));\nnode.status({fill:\"blue\",shape:\"dot\",text:\"active\"});\nreturn msg;","outputs":1,"noerr":0,"x":450,"y":440,"wires":[["4120ad27.f387dc"]]},{"id":"8adb5e08.9fff5","type":"function","z":"fd609b25.8db358","name":"DeviceStatus","func":"msg.payload = {\n Device2EM: {\n $: {\n xmlns: \"http://www.sma.de/communication/schema/SEMP/v1\"\n },\n DeviceStatus: {}\n }\n}\nmsg.payload.Device2EM.DeviceStatus = flow.get(\"DeviceStatus\");\nclearTimeout(context.get(\"timeout\"));\ncontext.set(\"timeout\",setTimeout(() => node.status({}),60000));\nnode.status({fill:\"blue\",shape:\"dot\",text:\"active\"});\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":560,"wires":[["4120ad27.f387dc"]]},{"id":"1233c579.729363","type":"function","z":"fd609b25.8db358","name":"PlanningRequest","func":"msg.payload = {\n Device2EM: {\n $: {\n xmlns: \"http://www.sma.de/communication/schema/SEMP/v1\"\n },\n PlanningRequest: {}\n }\n}\nmsg.payload.Device2EM.PlanningRequest = flow.get(\"PlanningRequest\");\nclearTimeout(context.get(\"timeout\"));\ncontext.set(\"timeout\",setTimeout(() => node.status({}),60000));\nnode.status({fill:\"blue\",shape:\"dot\",text:\"active\"});\nreturn msg;","outputs":1,"noerr":0,"x":490,"y":620,"wires":[["4120ad27.f387dc"]]},{"id":"4120ad27.f387dc","type":"xml","z":"fd609b25.8db358","name":"","property":"payload","attr":"","chr":"","x":750,"y":500,"wires":[["f26384ab.c3017"]]},{"id":"f26384ab.c3017","type":"http response","z":"fd609b25.8db358","name":"","statusCode":"","headers":{},"x":750,"y":620,"wires":[]},{"id":"e9ac8582.6fe8b","type":"function","z":"fd609b25.8db358","name":"Description","func":"msg.payload = {\n root: {\n $: {\n xmlns: \"urn:schemas-upnp-org:device-1-0\"\n },\n specVersion: {\n major: \"1\",\n minor: \"0\"\n },\n device: {\n deviceType: \"urn:schemas-simple-energy-management-protocol:device:Gateway:1\",\n friendlyName: \"Haralds Gateway\",\n manufacturer: \"Harald Paulus\",\n manufacturerURL: \"http://www.haraldpaulus.de\",\n modelDescription: \"Haralds Gateway\",\n modelName: \"Haralds Gateway\",\n modelNumber: \"1.0\",\n modelURL: \"http://www.haraldpaulus.de\",\n serialNumber: flow.get(\"GatewayUUID\").substr(-12,12),\n UDN: \"uuid:\" + flow.get(\"GatewayUUID\"),\n serviceList: {\n service: {\n serviceType: \"urn:schemas-simple-energy-management-protocol:service:NULL:1:service:NULL:1\",\n serviceId: \"urn:schemas-simple-energy-management-protocol:serviceId:NULL:serviceId:NULL\",\n SCPDURL: \"/XD/NULL.xml\",\n controlURL: \"/UD/?0\",\n eventSubURL: \"\"\n }\n },\n 'semp:X_SEMPSERVICE': {\n $: {\n 'xmlns:semp': \"urn:schemas-simple-energy-management-protocol:service-1-0\"\n },\n 'semp:server': flow.get(\"SEMPserver\"), \n 'semp:basePath': flow.get(\"SEMPbasePath\"),\n 'semp:transport': \"HTTP/Pull\",\n 'semp:exchangeFormat': \"XML\",\n 'semp:wsVersion': \"1.1.0\"\n }\n }\n }\n};\nnode.status({fill:\"blue\",shape:\"dot\",text:\"active\"});\nclearTimeout(context.get(\"timeout\"));\ncontext.set(\"timeout\",setTimeout(() => node.status({}),60000));\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":380,"wires":[["4120ad27.f387dc"]]},{"id":"8b1e688c.b09ab8","type":"http in","z":"fd609b25.8db358","name":"","url":"/user/semp/","method":"post","upload":false,"swaggerDoc":"","x":150,"y":680,"wires":[["461b073b.7ede08","96572dea.aeb37"]]},{"id":"81632ec2.c093d8","type":"link in","z":"fd609b25.8db358","name":"Ladeleistung","links":["1d31445f.0cbf94"],"x":35,"y":960,"wires":[["598ef3f0.46ebd4"]]},{"id":"598ef3f0.46ebd4","type":"smooth","z":"fd609b25.8db358","name":"","property":"payload","action":"mean","count":"2","round":"0","mult":"single","reduce":false,"x":140,"y":960,"wires":[["602d762a.7df668"]]},{"id":"602d762a.7df668","type":"change","z":"fd609b25.8db358","name":"","rules":[{"t":"set","p":"DeviceStatus[0].PowerConsumption.PowerInfo.AveragePower","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":960,"wires":[[]]},{"id":"a953db6c.a4b3a8","type":"inject","z":"fd609b25.8db358","name":"Neustart","topic":"Neustart","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":true,"onceDelay":"0.1","x":100,"y":80,"wires":[["56fcc613.23be18","931658a8.580fc"]]},{"id":"461b073b.7ede08","type":"function","z":"fd609b25.8db358","name":"toString","func":"msg.payload = msg.payload.toString()\nclearTimeout(context.get(\"timeout\"));\ncontext.set(\"timeout\",setTimeout(() => node.status({}),60000));\nnode.status({fill:\"blue\",shape:\"dot\",text:\"active\"});\nreturn msg;","outputs":1,"noerr":0,"x":300,"y":740,"wires":[["f958ea8b.a6fee8"]]},{"id":"f958ea8b.a6fee8","type":"xml","z":"fd609b25.8db358","name":"","property":"payload","attr":"","chr":"","x":450,"y":740,"wires":[["7d9bfdbe.aa4d9c"]]},{"id":"12a375dc.3249f2","type":"link in","z":"fd609b25.8db358","name":"AutoLaden","links":["663fc333.5467fc"],"x":35,"y":920,"wires":[["5ecc7dbd.eb37c4"]]},{"id":"5ecc7dbd.eb37c4","type":"change","z":"fd609b25.8db358","name":"","rules":[{"t":"set","p":"DeviceStatus[0].EMSignalsAccepted","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":920,"wires":[[]]},{"id":"8f5bc047.362858","type":"link in","z":"fd609b25.8db358","name":"Ladestation","links":["f26a514.83cd33"],"x":35,"y":880,"wires":[["a5eb2ea3.9632d"]]},{"id":"12473ec9.fc1ea9","type":"change","z":"fd609b25.8db358","name":"","rules":[{"t":"set","p":"DeviceStatus[0].Status","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":880,"wires":[[]]},{"id":"a5eb2ea3.9632d","type":"change","z":"fd609b25.8db358","name":"true/false -> On/Off","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"On","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"Off","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":170,"y":880,"wires":[["12473ec9.fc1ea9"]]},{"id":"2e15c100.82b6f8","type":"link out","z":"fd609b25.8db358","name":"DeviceControl[0]","links":["3d8bbd0e.41dfd2","9097c340.a490f8","60c37243.f76ba4"],"x":795,"y":700,"wires":[]},{"id":"c443513b.b3c708","type":"link in","z":"fd609b25.8db358","name":"Lade-Planung","links":["dca9eb91.28294"],"x":35,"y":1000,"wires":[["15440738.d47e11"]]},{"id":"15440738.d47e11","type":"change","z":"fd609b25.8db358","name":"setze flow.PlanningRequest[0]","rules":[{"t":"set","p":"PlanningRequest[0].Timeframe.EarliestStart","pt":"flow","to":"payload.EarliestStart","tot":"msg"},{"t":"set","p":"PlanningRequest[0].Timeframe.LatestEnd","pt":"flow","to":"payload.LatestEnd","tot":"msg"},{"t":"set","p":"PlanningRequest[0].Timeframe.MinEnergy","pt":"flow","to":"payload.MinEnergy","tot":"msg"},{"t":"set","p":"PlanningRequest[0].Timeframe.MaxEnergy","pt":"flow","to":"payload.MaxEnergy","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":1000,"wires":[[]]},{"id":"7d9bfdbe.aa4d9c","type":"function","z":"fd609b25.8db358","name":"DeviceControl.On","func":"Device = msg.payload.EM2Device.DeviceControl[0].DeviceId[0];\nOn = msg.payload.EM2Device.DeviceControl[0].On[0];\nif (msg.payload.EM2Device.DeviceControl[0].RecommendedPowerConsumption !== undefined) {\n msg.RecommendedPowerConsumption = parseInt(msg.payload.EM2Device.DeviceControl[0].RecommendedPowerConsumption[0]);\n}\nelse {\n msg.RecommendedPowerConsumption = 0;\n}\nif (On == \"true\") {\n msg.payload = true;\n node.status({fill:\"blue\",shape:\"dot\",text:\"true\"});\n}\nelse {\n msg.payload = false;\n msg.RecommendedPowerConsumption = 0;\n node.status({fill:\"grey\",shape:\"ring\",text:\"false\"});\n}\nmsg.topic = Device;\nDeviceId = flow.get(\"DeviceId\");\nswitch (Device) {\n case DeviceId[0]:\n return [msg,null,null];\n case DeviceId[1]:\n return [null,msg,null];\n case DeviceId[2]:\n return [null,null,msg];\n default: \n return [null,null,null];\n}","outputs":3,"noerr":0,"x":630,"y":740,"wires":[["2e15c100.82b6f8"],["f906d05d.989eb"],["bd55cdb8.c0c4f8"]]},{"id":"96572dea.aeb37","type":"change","z":"fd609b25.8db358","name":"msg.payload = \"\"","rules":[{"t":"set","p":"payload","pt":"msg","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":680,"wires":[["f26384ab.c3017"]]},{"id":"f906d05d.989eb","type":"link out","z":"fd609b25.8db358","name":"DeviceControl[1]","links":["85520e7d.1f5e58","60c37243.f76ba4"],"x":795,"y":740,"wires":[]},{"id":"5ba71422.70fed4","type":"link in","z":"fd609b25.8db358","name":"DeviceStatus[1]","links":["4b624e2a.5e337"],"x":35,"y":1100,"wires":[["4e7f3ac1.197c84"]]},{"id":"94496a25.460f5","type":"change","z":"fd609b25.8db358","name":"","rules":[{"t":"set","p":"DeviceStatus[1].Status","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":1100,"wires":[[]]},{"id":"4e7f3ac1.197c84","type":"change","z":"fd609b25.8db358","name":"true/false -> On/Off","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"On","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"Off","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":170,"y":1100,"wires":[["94496a25.460f5"]]},{"id":"fea15359.7a9348","type":"change","z":"fd609b25.8db358","name":"","rules":[{"t":"set","p":"DeviceStatus[1].EMSignalsAccepted","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":1140,"wires":[[]]},{"id":"1d80c82b.821e2","type":"change","z":"fd609b25.8db358","name":"","rules":[{"t":"set","p":"DeviceStatus[1].PowerConsumption.PowerInfo.AveragePower","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":1180,"wires":[[]]},{"id":"56fcc613.23be18","type":"function","z":"fd609b25.8db358","name":"Init Devices","func":"const DeviceSerial = [\n \"012345678900\",\n \"012345678901\",\n \"012345678902\"\n ]; \nconst DeviceId = [\n \"F-11223344-\" + DeviceSerial[0] + \"-00\",\n \"F-11223344-\" + DeviceSerial[1] + \"-00\",\n \"F-11223344-\" + DeviceSerial[2] + \"-00\"\n ];\nflow.set(\"DeviceId\",DeviceId);\nvar DeviceInfo = [{\n Identification: {\n DeviceId: DeviceId[0],\n DeviceName: \"vCharge Ladestation\",\n DeviceType: \"EVCharger\",\n DeviceSerial: DeviceSerial[0],\n DeviceVendor: \"Harald Paulus\"\n },\n Characteristics: {\n MinPowerConsumption: 1380,\n MaxPowerConsumption: 4600,\n PowerLevels: {\n PowerLevel: [1380,1840,2760,4600]\n },\n MinOnTime: 600,\n MinOffTime: 600\n },\n Capabilities: {\n CurrentPower: {\n Method: \"Measurement\"\n },\n Timestamps: {\n AbsoluteTimestamps: false\n },\n Interruptions: {\n InterruptionsAllowed: true\n },\n Requests: {\n OptionalEnergy: true\n }\n }\n},{\n Identification: {\n DeviceId: DeviceId[1],\n DeviceName: \"HMIP-PSM\",\n DeviceType: \"Other\",\n DeviceSerial: DeviceSerial[1],\n DeviceVendor: \"Harald Paulus\"\n },\n Characteristics: {\n MaxPowerConsumption: 500,\n MinOnTime: 600,\n MinOffTime: 600\n },\n Capabilities: {\n CurrentPower: {\n Method: \"Measurement\"\n },\n Timestamps: {\n AbsoluteTimestamps: false\n },\n Interruptions: {\n InterruptionsAllowed: true\n },\n Requests: {\n OptionalEnergy: true\n }\n }\n},{\n Identification: {\n DeviceId: DeviceId[2],\n DeviceName: \"HMIP-PSM\",\n DeviceType: \"Other\",\n DeviceSerial: DeviceSerial[2],\n DeviceVendor: \"Harald Paulus\"\n },\n Characteristics: {\n MaxPowerConsumption: 500,\n MinOnTime: 600,\n MinOffTime: 600\n },\n Capabilities: {\n CurrentPower: {\n Method: \"Measurement\"\n },\n Timestamps: {\n AbsoluteTimestamps: false\n },\n Interruptions: {\n InterruptionsAllowed: true\n },\n Requests: {\n OptionalEnergy: true\n }\n }\n}]\nflow.set(\"DeviceInfo\",DeviceInfo);\nvar DeviceStatus = [{\n DeviceId: DeviceId[0],\n EMSignalsAccepted: false,\n Status: \"Off\",\n PowerConsumption: {\n PowerInfo: {\n AveragePower: 0,\n Timestamp: 0,\n AveragingInterval: 60\n }\n }\n},{\n DeviceId: DeviceId[1],\n EMSignalsAccepted: false,\n Status: \"Off\",\n PowerConsumption: {\n PowerInfo: {\n AveragePower: 0,\n Timestamp: 0,\n AveragingInterval: 60\n }\n }\n},{\n DeviceId: DeviceId[2],\n EMSignalsAccepted: false,\n Status: \"Off\",\n PowerConsumption: {\n PowerInfo: {\n AveragePower: 0,\n Timestamp: 0,\n AveragingInterval: 60\n }\n }\n}]\nflow.set(\"DeviceStatus\",DeviceStatus);\nvar PlanningRequest = [{\n Timeframe: {\n DeviceId: DeviceId[0],\n EarliestStart: 0,\n LatestEnd: 86400,\n MinEnergy: 0,\n MaxEnergy: 22000\n }\n},{\n Timeframe: {\n DeviceId: DeviceId[1],\n EarliestStart: 0,\n LatestEnd: 60000,\n MinRunningTime: 0,\n MaxRunningTime: 59400,\n }\n},{\n Timeframe: {\n DeviceId: DeviceId[2],\n EarliestStart: 0,\n LatestEnd: 60000,\n MinRunningTime: 0,\n MaxRunningTime: 59400,\n }\n}]\nflow.set(\"PlanningRequest\",PlanningRequest);\nmsg.payload = {\n DeviceInfo: DeviceInfo,\n DeviceStatus: DeviceStatus,\n PlanningRequest: PlanningRequest\n}\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":100,"wires":[["77dcd78.1b34328"]]},{"id":"8883967b.8433e8","type":"link in","z":"fd609b25.8db358","name":"PowerConsumption[1]","links":["a78a98d.4727168"],"x":35,"y":1180,"wires":[["f7c8727b.9d3458"]]},{"id":"f7c8727b.9d3458","type":"smooth","z":"fd609b25.8db358","name":"","property":"payload","action":"mean","count":"2","round":"0","mult":"single","reduce":false,"x":140,"y":1180,"wires":[["1d80c82b.821e2"]]},{"id":"60ae981f.7f131","type":"change","z":"fd609b25.8db358","name":"setze flow.PlanningRequest[1]","rules":[{"t":"set","p":"PlanningRequest[1].Timeframe.EarliestStart","pt":"flow","to":"payload.EarliestStart","tot":"msg"},{"t":"set","p":"PlanningRequest[1].Timeframe.LatestEnd","pt":"flow","to":"payload.LatestEnd","tot":"msg"},{"t":"set","p":"PlanningRequest[1].Timeframe.MinRunningTime","pt":"flow","to":"payload.MinRunningTime","tot":"msg"},{"t":"set","p":"PlanningRequest[1].Timeframe.MaxRunningTime","pt":"flow","to":"payload.MaxRunningTime","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":1220,"wires":[[]]},{"id":"a5eead0e.51624","type":"link in","z":"fd609b25.8db358","name":"PlanningRequest[1]","links":["fb7a6f20.928db"],"x":35,"y":1220,"wires":[["60ae981f.7f131"]]},{"id":"f614c819.f9822","type":"link in","z":"fd609b25.8db358","name":"EMSignalsAccepted[1]","links":["1bbd8604.d3e812"],"x":35,"y":1140,"wires":[["fea15359.7a9348"]]},{"id":"77dcd78.1b34328","type":"link out","z":"fd609b25.8db358","name":"Init Devices","links":["f391992d.65bd48"],"x":795,"y":100,"wires":[]},{"id":"f3e219f.86bc4e8","type":"inject","z":"fd609b25.8db358","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"60","crontab":"","once":true,"onceDelay":"14","x":90,"y":200,"wires":[["2c9bf7c3.07bb18"]]},{"id":"24bd655a.9d36f2","type":"inject","z":"fd609b25.8db358","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"60","crontab":"","once":true,"onceDelay":"16","x":90,"y":240,"wires":[["745bd2c2.fb6f14"]]},{"id":"5310786c.75a4e8","type":"inject","z":"fd609b25.8db358","name":"","topic":"","payload":"true","payloadType":"bool","repeat":"60","crontab":"","once":true,"onceDelay":"18","x":90,"y":280,"wires":[["c6c9d36f.b1c8"]]},{"id":"c6c9d36f.b1c8","type":"function","z":"fd609b25.8db358","name":"SEMP Gateway Device Type","func":"return {payload: \n \"NOTIFY * HTTP/1.1\\r\\n\" +\n \"HOST: 239.255.255.250:1900\\r\\n\" + \n \"CACHE-CONTROL: max-age = 1800\\r\\n\" +\n \"SERVER: Linux/2.6.32 UPnP/1.0 SomeGateway SSDP Server/1.0.0\\r\\n\" +\n \"NTS: ssdp:alive\\r\\n\" +\n \"LOCATION: \" + flow.get(\"SEMPserver\") + flow.get(\"SEMPbasePath\") + \"/description.xml\\r\\n\" +\n \"NT: urn:schemas-simple-energy-management-protocol:device:Gateway:1\\r\\n\" +\n \"USN: uuid:\" + flow.get(\"GatewayUUID\") + \"::urn:schemas-simple-energy-management-protocol:device:Gateway:1\\r\\n\\r\\n\"\n};","outputs":1,"noerr":0,"x":320,"y":280,"wires":[["536ca306.607634"]]},{"id":"931658a8.580fc","type":"function","z":"fd609b25.8db358","name":"Init Gateway","func":"flow.set (\"GatewayUUID\",\"76e0967a-4eee-40cd-a36d-c1d076e79ae9\");\nflow.set (\"SEMPserver\",\"http://192.168.0.222:80\");\nflow.set (\"SEMPbasePath\",\"/addons/red/user/semp\");\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":60,"wires":[[]]},{"id":"745bd2c2.fb6f14","type":"function","z":"fd609b25.8db358","name":"Device UUID","func":"return {payload:\n \"NOTIFY * HTTP/1.1\\r\\n\" +\n \"HOST: 239.255.255.250:1900\\r\\n\" + \n \"CACHE-CONTROL: max-age = 1800\\r\\n\" +\n \"SERVER: Linux/2.6.32 UPnP/1.0 SomeGateway SSDP Server/1.0.0\\r\\n\" +\n \"NTS: ssdp:alive\\r\\n\" +\n \"LOCATION: \" + flow.get(\"SEMPserver\") + flow.get(\"SEMPbasePath\") + \"/description.xml\\r\\n\" +\n \"NT: uuid:\" + flow.get(\"GatewayUUID\") + \"\\r\\n\" +\n \"USN: uuid:\" + flow.get(\"GatewayUUID\") + \"\\r\\n\\r\\n\"\n};","outputs":1,"noerr":0,"x":270,"y":240,"wires":[["536ca306.607634"]]},{"id":"2c9bf7c3.07bb18","type":"function","z":"fd609b25.8db358","name":"Root-Device","func":"return {payload:\n \"NOTIFY * HTTP/1.1\\r\\n\" +\n \"HOST: 239.255.255.250:1900\\r\\n\" + \n \"CACHE-CONTROL: max-age = 1800\\r\\n\" +\n \"SERVER: Linux/2.6.32 UPnP/1.0 SomeGateway SSDP Server/1.0.0\\r\\n\" +\n \"NTS: ssdp:alive\\r\\n\" +\n \"LOCATION: \" + flow.get(\"SEMPserver\") + flow.get(\"SEMPbasePath\") + \"/description.xml\\r\\n\" +\n \"NT: upnp:rootdevice\\r\\n\" +\n \"USN: uuid:\" + flow.get(\"GatewayUUID\") + \"::upnp:rootdevice\\r\\n\\r\\n\"\n};","outputs":1,"noerr":0,"x":270,"y":200,"wires":[["536ca306.607634"]]},{"id":"bd45b465.1517e8","type":"link in","z":"fd609b25.8db358","name":"DeviceStatus[2]","links":["7da7f16.2c1f09"],"x":35,"y":1320,"wires":[["67bac032.57e19"]]},{"id":"f2c9b0eb.0f0048","type":"change","z":"fd609b25.8db358","name":"","rules":[{"t":"set","p":"DeviceStatus[2].Status","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":1320,"wires":[[]]},{"id":"67bac032.57e19","type":"change","z":"fd609b25.8db358","name":"true/false -> On/Off","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"On","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"Off","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":170,"y":1320,"wires":[["f2c9b0eb.0f0048"]]},{"id":"fab5ea38.50dd7","type":"change","z":"fd609b25.8db358","name":"","rules":[{"t":"set","p":"DeviceStatus[2].EMSignalsAccepted","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":1360,"wires":[[]]},{"id":"98f68a02.447af8","type":"change","z":"fd609b25.8db358","name":"","rules":[{"t":"set","p":"DeviceStatus[2].PowerConsumption.PowerInfo.AveragePower","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":1400,"wires":[[]]},{"id":"69f48782.5bd67","type":"link in","z":"fd609b25.8db358","name":"PowerConsumption[2]","links":["a43e7ff2.e908b8"],"x":35,"y":1400,"wires":[["d0e664d2.90876"]]},{"id":"d0e664d2.90876","type":"smooth","z":"fd609b25.8db358","name":"","property":"payload","action":"mean","count":"2","round":"0","mult":"single","reduce":false,"x":140,"y":1400,"wires":[["98f68a02.447af8"]]},{"id":"f2884ecc.928018","type":"change","z":"fd609b25.8db358","name":"setze flow.PlanningRequest[2]","rules":[{"t":"set","p":"PlanningRequest[2].Timeframe.EarliestStart","pt":"flow","to":"payload.EarliestStart","tot":"msg"},{"t":"set","p":"PlanningRequest[2].Timeframe.LatestEnd","pt":"flow","to":"payload.LatestEnd","tot":"msg"},{"t":"set","p":"PlanningRequest[2].Timeframe.MinRunningTime","pt":"flow","to":"payload.MinRunningTime","tot":"msg"},{"t":"set","p":"PlanningRequest[2].Timeframe.MaxRunningTime","pt":"flow","to":"payload.MaxRunningTime","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":1440,"wires":[[]]},{"id":"b839f425.edd6f8","type":"link in","z":"fd609b25.8db358","name":"PlanningRequest[2]","links":["461b6779.2283b8"],"x":35,"y":1440,"wires":[["f2884ecc.928018"]]},{"id":"b5e623d8.42e24","type":"link in","z":"fd609b25.8db358","name":"EMSignalsAccepted[2]","links":["f22ef942.b1601"],"x":35,"y":1360,"wires":[["fab5ea38.50dd7"]]},{"id":"bd55cdb8.c0c4f8","type":"link out","z":"fd609b25.8db358","name":"DeviceControl[2]","links":["2b459752.8c5d7","60c37243.f76ba4"],"x":795,"y":780,"wires":[]}]
Code: Alles auswählen
[{"id":"32167ddd.7aac8a","type":"subflow","name":"Save State","info":"","category":"","in":[{"x":60,"y":80,"wires":[{"id":"a76c9ffb.cf9448"}]}],"out":[{"x":540,"y":80,"wires":[{"id":"371e0f31.35687","port":0}]}],"env":[],"color":"#DDAA99"},{"id":"5f5970b.547131","type":"inject","z":"32167ddd.7aac8a","name":"Init 20s","topic":"Init","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":true,"onceDelay":"20","x":180,"y":140,"wires":[["371e0f31.35687"]]},{"id":"371e0f31.35687","type":"function","z":"32167ddd.7aac8a","name":"set/get Payload","func":"if (msg.topic != \"Init\") {\n if (context.get(\"Init\") === true) {\n context.set(\"Payload\",msg.payload,\"file\");\n }\n return null;\n}\nelse {\n context.set(\"Init\",true);\n msg.payload = context.get(\"Payload\",\"file\");\n if (msg.payload === undefined)\n return null;\n else\n return msg;\n}\n","outputs":1,"noerr":0,"x":380,"y":80,"wires":[[]]},{"id":"a76c9ffb.cf9448","type":"change","z":"32167ddd.7aac8a","name":"Save","rules":[{"t":"set","p":"topic","pt":"msg","to":"Save","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":170,"y":80,"wires":[["371e0f31.35687"]]},{"id":"97e7bb76.58a4c","type":"tab","label":"HMIP-PSM 001","disabled":false,"info":""},{"id":"81701f86.d3f3b","type":"function","z":"97e7bb76.58a4c","name":"PlanningRequest","func":"if (msg.topic == \"Startzeit\") {\n Startzeit = msg.payload;\n context.set(\"Startzeit\",Startzeit);\n}\nelse {\n Startzeit = context.get(\"Startzeit\")||0;\n}\nif (msg.topic == \"Endzeit\") {\n Endzeit = msg.payload;\n context.set(\"Endzeit\",Endzeit);\n}\nelse {\n Endzeit = context.get(\"Endzeit\")||0;\n}\nif (msg.topic == \"Mindestzeit\") {\n Mindestzeit = msg.payload;\n context.set(\"Mindestzeit\",Mindestzeit);\n}\nelse {\n Mindestzeit = context.get(\"Mindestzeit\")||0;\n}\nif (msg.topic == \"Laufzeit\") {\n Laufzeit = msg.payload;\n context.set(\"Laufzeit\",Laufzeit);\n}\nelse {\n Laufzeit = context.get(\"Laufzeit\")||0;\n}\nd = new Date();\nUhrzeit = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();\nif (Endzeit <= Startzeit) {\n if (Uhrzeit < Startzeit && Uhrzeit > Endzeit) {\n Endzeit = Endzeit + 86400;\n }\n else {\n Startzeit = Startzeit - 86400;\n }\n}\nif (Startzeit >= Uhrzeit) {\n EarliestStart = Startzeit - Uhrzeit;\n LatestEnd = Endzeit - Uhrzeit;\n}\nelse {\n if (Uhrzeit <= Endzeit) {\n EarliestStart = 0;\n LatestEnd = Endzeit - Uhrzeit;\n }\n else {\n EarliestStart = Startzeit - Uhrzeit + 86400;\n LatestEnd = Endzeit - Uhrzeit + 86400;\n }\n}\nEarliestStart = Math.max(0,EarliestStart);\nMaxRunningTime = Math.max(0,LatestEnd - EarliestStart);\nMinRunningTime = Mindestzeit;\nif (EarliestStart === 0) {\n MinRunningTime = MinRunningTime - Laufzeit;\n}\nMinRunningTime = Math.max(0,MinRunningTime);\nMinRunningTime = Math.min(MinRunningTime,MaxRunningTime);\nif (MinRunningTime > 0) {\n MaxRunningTime = MinRunningTime;\n}\nmsg.topic = \"PlanningRequest\";\nmsg.payload = {};\nmsg.payload.MinRunningTime = MinRunningTime;\nmsg.payload.MaxRunningTime = MaxRunningTime;\nmsg.payload.EarliestStart = EarliestStart;\nmsg.payload.LatestEnd = LatestEnd;\nStatusText = EarliestStart.toString() + \" | \" + LatestEnd.toString() + \" | \" + MinRunningTime.toString() + \" | \" + MaxRunningTime.toString();\nnode.status({fill:\"grey\",shape:\"dot\",text:StatusText})\nreturn msg;","outputs":1,"noerr":0,"x":390,"y":540,"wires":[["fb7a6f20.928db"]]},{"id":"b3ecc8e7.733a68","type":"ui_numeric","z":"97e7bb76.58a4c","name":"Startzeit","label":"Startzeit","tooltip":"","group":"cb838872.b3abf","order":3,"width":"6","height":"1","wrap":true,"passthru":true,"topic":"Startzeit","format":"{{value*1000|date:'HH:mm':'UTC'}}","min":0,"max":"85500","step":"900","x":120,"y":440,"wires":[["81701f86.d3f3b","99be3f72.78a37","83b74082.981868"]]},{"id":"fb7a6f20.928db","type":"link out","z":"97e7bb76.58a4c","name":"PlanningRequest","links":["e504cf8d.0944e8"],"x":735,"y":540,"wires":[]},{"id":"b93423a9.4eaef","type":"ccu-value","z":"97e7bb76.58a4c","name":"HMIP-PSM STATE","iface":"HmIP-RF","channel":"0001D3C99C91FE:3 HMIP-PSM 0001D3C99C91FE:3","datapoint":"STATE","mode":"","start":true,"change":true,"cache":true,"queue":false,"on":0,"onType":"undefined","ramp":0,"rampType":"undefined","working":true,"ccuConfig":"38263145.35ea0e","topic":"Status","x":390,"y":200,"wires":[["da3bf22c.b8358","4b624e2a.5e337"]]},{"id":"b42b3f40.d24cc","type":"ui_dropdown","z":"97e7bb76.58a4c","name":"Modus","label":"","tooltip":"","place":"","group":"cb838872.b3abf","order":2,"width":"3","height":"1","passthru":true,"options":[{"label":"Automatik","value":0,"type":"num"},{"label":"Ein","value":1,"type":"num"},{"label":"Aus","value":2,"type":"num"}],"payload":"","topic":"Mode","x":110,"y":140,"wires":[["dc317e36.4cdbb","2871b229.bdaf36"]]},{"id":"c051a998.a62bf8","type":"ui_text","z":"97e7bb76.58a4c","group":"cb838872.b3abf","order":1,"width":"3","height":"1","name":"","label":"Modus","format":"","layout":"row-left","x":110,"y":60,"wires":[]},{"id":"77a34e3f.4c477","type":"ui_text","z":"97e7bb76.58a4c","group":"cb838872.b3abf","order":7,"width":0,"height":0,"name":"","label":"Leistung aktuell","format":"{{msg.payload}} W","layout":"row-spread","x":680,"y":380,"wires":[]},{"id":"dc317e36.4cdbb","type":"function","z":"97e7bb76.58a4c","name":"Modus","func":"if (msg.payload === 0) {\n msg = null;\n Automatik = true;\n node.status({fill:\"blue\",shape:\"dot\",text:\"auto\"});\n}\nelse {\n if (msg.payload == 1) {\n Schalter = true;\n node.status({fill:\"green\",shape:\"dot\",text:\"active\"});\n }\n else {\n Schalter = false;\n node.status({fill:\"red\",shape:\"ring\",text:\"inactive\"});\n }\n msg = {};\n msg.topic = \"Schalter\";\n msg.payload = Schalter;\n Automatik = false;\n}\nmsg2 = {};\nmsg2.topic = \"Automatik\";\nmsg2.payload = Automatik;\nreturn [msg,msg2];","outputs":2,"noerr":0,"x":350,"y":140,"wires":[["b93423a9.4eaef"],["1bbd8604.d3e812"]]},{"id":"3d3e2966.0fd9a6","type":"ui_led","z":"97e7bb76.58a4c","group":"cb838872.b3abf","order":6,"width":"6","height":"1","label":"Schalterzustand","labelPlacement":"left","labelAlignment":"left","colorForValue":[{"color":"blue","value":"ON","valueType":"str"},{"color":"green","value":"ACTIVE","valueType":"str"}],"allowColorForValueInMessage":false,"name":"Zustand LED","x":690,"y":260,"wires":[]},{"id":"da3bf22c.b8358","type":"function","z":"97e7bb76.58a4c","name":"Schalterzustand","func":"if (msg.topic == \"Status\") {\n Status = msg.payload;\n context.set(\"Status\",Status);\n}\nelse {\n Status = context.get(\"Status\")||false;\n}\nif (msg.topic == \"Leistung\") {\n Leistung = msg.payload;\n context.set(\"Leistung\",Leistung);\n}\nelse {\n Leistung = context.get('Leistung')||0;\n}\nif (Status === false) {\n msg.payload = \"OFF\";\n node.status({fill:\"grey\",shape:\"ring\",text:\"OFF\"});\n\n}\nelse if (Leistung > 0) {\n msg.payload = \"ACTIVE\";\n node.status({fill:\"green\",shape:\"dot\",text:\"ACTIVE\"})\n}\nelse {\n msg.payload = \"ON\";\n node.status({fill:\"blue\",shape:\"dot\",text:\"ON\"})\n}\nreturn msg;","outputs":1,"noerr":0,"x":380,"y":260,"wires":[["3d3e2966.0fd9a6"]]},{"id":"a78a98d.4727168","type":"link out","z":"97e7bb76.58a4c","name":"Schalter-Leistung","links":["71e7a2df.2e5744"],"x":735,"y":320,"wires":[]},{"id":"1bbd8604.d3e812","type":"link out","z":"97e7bb76.58a4c","name":"Schalter-Automatik","links":["9dc1cb39.d57578"],"x":735,"y":140,"wires":[]},{"id":"4b624e2a.5e337","type":"link out","z":"97e7bb76.58a4c","name":"Schalter-Status","links":["73a47154.c5854"],"x":735,"y":200,"wires":[]},{"id":"85520e7d.1f5e58","type":"link in","z":"97e7bb76.58a4c","name":"DeviceControl","links":["78b6e1bc.4ecde8"],"x":75,"y":200,"wires":[["b93423a9.4eaef"]]},{"id":"8f35923e.d0024","type":"ui_numeric","z":"97e7bb76.58a4c","name":"Mindestzeit","label":"Mindestlaufzeit","tooltip":"","group":"cb838872.b3abf","order":5,"width":"6","height":"1","wrap":true,"passthru":true,"topic":"Mindestzeit","format":"{{value*1000|date:'HH:mm':'UTC'}}","min":0,"max":"85500","step":"900","x":130,"y":640,"wires":[["81701f86.d3f3b","2788a757.a4a7"]]},{"id":"19b291c4.bbbbfe","type":"ui_numeric","z":"97e7bb76.58a4c","name":"Endzeit","label":"Endzeit","tooltip":"","group":"cb838872.b3abf","order":4,"width":"6","height":"1","wrap":true,"passthru":true,"topic":"Endzeit","format":"{{value*1000|date:'HH:mm':'UTC'}}","min":0,"max":"85500","step":"900","x":120,"y":540,"wires":[["81701f86.d3f3b","ebc1f486.678b18"]]},{"id":"a62bf73a.2cf98","type":"inject","z":"97e7bb76.58a4c","name":"Jede Minute","topic":"Leistung","payload":"true","payloadType":"bool","repeat":"60","crontab":"","once":true,"onceDelay":"10","x":140,"y":320,"wires":[["16e9ea86.1539bd"]]},{"id":"16e9ea86.1539bd","type":"ccu-get-value","z":"97e7bb76.58a4c","name":"HMIP-PSM POWER","ccuConfig":"38263145.35ea0e","iface":"HmIP-RF","channel":"0001D3C99C91FE:6 HMIP-PSM 0001D3C99C91FE:6","sysvar":"Alarmmeldungen","sysvarProperty":"value","datapoint":"POWER","datapointProperty":"value","setProp":"payload","setPropType":"msg","x":400,"y":320,"wires":[["da3bf22c.b8358","a78a98d.4727168","77a34e3f.4c477","99be3f72.78a37"]]},{"id":"99be3f72.78a37","type":"function","z":"97e7bb76.58a4c","name":"Laufzeit","func":"if (msg.topic == \"Startzeit\") {\n Startzeit = msg.payload;\n context.set(\"Startzeit\",Startzeit);\n return null;\n}\nelse {\n Startzeit = context.get(\"Startzeit\")||0;\n LaufzeitAktuell = 0;\n LaufzeitGesamt = 0;\n d = new Date();\n Uhrzeit = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();\n if (Math.round(Startzeit/60 == Math.round(Uhrzeit/60))) {\n Laufzeit = 0;\n LastStart = -1;\n }\n else {\n Laufzeit = context.get(\"Laufzeit\",\"file\")||0;\n LastStart = context.get(\"LastStart\",\"file\")||-1;\n if (LastStart >= 0) {\n if (Uhrzeit > LastStart) {\n LaufzeitAktuell = Uhrzeit - LastStart;\n }\n else {\n LaufzeitAktuell = Uhrzeit - LastStart + 86400;\n }\n }\n LaufzeitGesamt = Laufzeit + LaufzeitAktuell;\n if (msg.payload > 0.1) {\n if (LastStart === -1) {\n LastStart = Uhrzeit;\n }\n }\n else {\n Laufzeit = LaufzeitGesamt;\n LastStart = -1;\n }\n }\n context.set(\"Laufzeit\",Laufzeit,\"file\");\n context.set(\"LastStart\",LastStart,\"file\");\n msg.topic = \"Laufzeit\";\n msg.payload = LaufzeitGesamt;\n StatusText = LastStart.toString() + \" | \" + LaufzeitAktuell.toString() + \" | \" + Laufzeit.toString();\n node.status({fill:\"grey\",shape:\"dot\",text:StatusText})\n return msg;\n}","outputs":1,"noerr":0,"x":360,"y":440,"wires":[["ef811e5b.b9941","81701f86.d3f3b"]]},{"id":"ef811e5b.b9941","type":"ui_text","z":"97e7bb76.58a4c","group":"cb838872.b3abf","order":7,"width":0,"height":0,"name":"","label":"Laufzeit aktuell","format":"{{value*1000|date:'HH:mm':'UTC'}}","layout":"row-spread","x":680,"y":440,"wires":[]},{"id":"2871b229.bdaf36","type":"subflow:32167ddd.7aac8a","z":"97e7bb76.58a4c","name":"Modus","env":[],"x":110,"y":100,"wires":[["b42b3f40.d24cc"]]},{"id":"83b74082.981868","type":"subflow:32167ddd.7aac8a","z":"97e7bb76.58a4c","name":"Startzeit","env":[],"x":120,"y":400,"wires":[["b3ecc8e7.733a68"]]},{"id":"ebc1f486.678b18","type":"subflow:32167ddd.7aac8a","z":"97e7bb76.58a4c","name":"Endzeit","env":[],"x":120,"y":500,"wires":[["19b291c4.bbbbfe"]]},{"id":"2788a757.a4a7","type":"subflow:32167ddd.7aac8a","z":"97e7bb76.58a4c","name":"Mindestzeit","env":[],"x":130,"y":600,"wires":[["8f35923e.d0024"]]},{"id":"cb838872.b3abf","type":"ui_group","z":"","name":"HMIP-PSM 001","tab":"f59e4e6b.4ce978","disp":true,"width":"6","collapse":false},{"id":"38263145.35ea0e","type":"ccu-connection","z":"","name":"localhost","host":"localhost","regaEnabled":true,"bcrfEnabled":true,"iprfEnabled":true,"virtEnabled":true,"bcwiEnabled":false,"cuxdEnabled":true,"regaPoll":true,"regaInterval":"30","rpcPingTimeout":"60","rpcInitAddress":"127.0.0.1","rpcServerHost":"127.0.0.1","rpcBinPort":"2047","rpcXmlPort":"2048","queueTimeout":"5000","queuePause":"250","contextStore":""},{"id":"f59e4e6b.4ce978","type":"ui_tab","z":"","name":"HMIP-PSM","icon":"dashboard","disabled":false,"hidden":false}]
Der Flow für die Gerätesteuerung verwendet noch diesen Subflow, um Einstellungen über einen Restart hinweg zu erhalten:
Diese Flows stellen aber keine 100% fertige Lösung dar, sondern sollen Dir nur als Ausgangsbasis dienen.
Im Node InitGateway die IP-Adresse Deiner CCU3 und eventuell die GatewayUUID, z.B. mit einer online generierten, zufälligen UUID.
Im Node InitDevices werden die einzelnen Geräte definiert, welche Du einbinden möchtest. In jedem Fall solltest Du hier die Seriennummern und die DeviceId anpassen. Dafür und für die ganzen anderen Parameter musst Du Dir unbedingt die SEMP Dokumentation von SMA ansehen. Ich habe hier drei Geräte definiert, nämlich eine Auto-Ladestation und zwei Schalt-Mess-Steckdosen HMIP-PSM.
Falls Du die Anzahl der Geräte änderst, also die Arrays, die in diesem Node definiert werden vergrößerst oder verkleinerst, musst Du auch noch den Node DeviceControl.On entsprechend anpassen. Dieser empfängt die Schaltbefehle vom SHM und gibt sie an die Geräte-Steuerung-Flows weiter.
Ebenfalls anpassen musst Du dann die unteren drei Abschnitte, welche die von den Geräte-Steuerung-Flows kommenden Daten empfangen und in die SEMP Datenstrukturen einbauen.
Der hier beigefügte beispielhafte Geräte-Steuerung-Flow sollte funktionieren, so wie er ist, wenn Du eine HMIP-PSM Steckdose hast und diese in den entsprechenden Nodes einträgst.
Mein Geräte-Flow für die Ladestation ist recht speziell und deshalb hier nicht dabei. Den kannst Du aber auch erst einmal weglassen. Für die zweite Steckdose kannst Du den hier beigefügten Flow ein zweites Mal einfügen und die Verbindungen zum SEMP-Flow entsprechend anpassen. Dann siehst Du gleich, wie das funktioniert
Wichtig ist noch zu wissen, dass die Flows davon ausgehen, dass der default Context Storage "memory" ist! Sollte das bei Dir nicht sein, musst Du unbedingt alle Stellen, an denen auf den Context Storage zugegriffen wird, anpassen. Ich verwende nämlich teilweise explizit "file" um den Zustand der Steuerung über einen Neustart hinweg zu erhalten.
Soweit erst einmal für heute, ich denke, da kommen sicher noch ein paar Fragen auf, die ich gerne beantworten werde.