Browsed by
Category: Hardware

Ovládání tepelného čerpadla Rapid Mini Inverter

Ovládání tepelného čerpadla Rapid Mini Inverter

Když jsem si k bazénu pořídil tepelné čerpadlo, začal jsem zároveň řešit, jak efektivně využít přebytky z FVE a jak to celé propojit. Prvním nápadem bylo spínat čerpadlo rovnou přes relé, ale nebyl jsem si jistý, jestli po zapnutí naběhne samo, a taky jsem měl obavy, že časté vypínání by mohlo kompresoru škodit.

Další volba tak padla na Wi-Fi modul a jeho propojení přes TinyTuya (LoxBerry). Základní funkce, které jsem potřeboval – tedy zapnutí/vypnutí, čtení teploty vody v bazénu a nastavení požadované teploty – jsem tímto způsobem získal, a víc jsem v té chvíli nepotřeboval.

Jenže letos při odzimování bazénu přišlo “ale”. Wi-Fi modul se začal samovolně odpojovat od sítě – klidně i na hodinu. A to je problém, když potřebujete spínat podle přebytků z FVE v reálném čase.

Začal jsem proto hledat jiné řešení a zjistil, že čerpadlo má rozhraní RS485.

Takže hurá do toho.

Model, který mám je Rapid Mini Inverter RMIC06, ale ve skutečnosti je to výrobce Fairland, takže by měli fungovat stejné adresy pro všechny modely od nich.

Použité díly:

  1. Odstranění krytu hlavního přívodu

Nejprve je potřeba sejmout kryt, pod kterým se nachází hlavní elektrický přívod. Kryt je upevněn několika šrouby – po jejich odšroubování lze kryt jednoduše sundat.

      2. Demontáž displeje

Pod tímto krytem se nachází další šrouby, které drží displej. Ty je třeba vyšroubovat a displej opatrně vyjmout.

      3. Odstranění horního krytu čerpadla

Po demontáži displeje se zpřístupní další dva šrouby, které upevňují horní kryt čerpadla. I tyto šrouby je třeba odstranit. Poslední šroub, který drží horní kryt, je umístěn na zadní straně jednotky, v blízkosti chladiče (radiátoru). Po jeho odšroubování lze horní kryt kompletně sejmout a získat tak přístup k vnitřní elektronice a sběrnici RS485.

      4. Sejmutí krytů řídicí jednotky

Po odstranění všech krytů řídicí jednotky je možné najít konektor typu JST XH 2,54 mm (4pin), do kterého je zapojen modul pro připojení Wi-Fi.

Zde je můžeme vidět 4 piny – první dva jsou RS485 B a A zbylé dva je napájení tedy G zem a +12V, takže můžeme z desky rovnou napájet náš převodník

    5. výsledné propojení

Nyní stačí jen pro jednotku najít vhodné umístění a přivést LAN kabel a znovu vše tepelné čerpadlo poskládat zpět.

6. Nastavení převodníku

  • přenosová rychlost 9600
  • Parity NONE
  • data 8
  • Stop 1
  • TCP Server
  • port 502
  • Modbus TCP

7. Loxone config

Přidáme nový modbus server kde zadáme IP adresu + port a nyní v předefinovaných zařízení přidáme šablonu ke stažení zde

 

 

Modbus relays – seznam zařízení a návodů pro ně

Modbus relays – seznam zařízení a návodů pro ně

Seznam všech návodů na různá zařízení, které se mi povedlo sehnat jsou zde

Pokud máte nějaké další linky, klidně mi je házejte zde do komntářů nebo na mail [email protected] a já je sem budu přidávat.

USB – Modbus

CE035 2 channel rs485 (relays)

N4D8B08 8-channel RS485 (relay)

10IOA04 (relay)

10IOA08 8-channel RS485 (or 12DIDO) (relay)

10IOAXX 12-channel RS485 (relay)

N434E01 1CH RS485 (temperature)

PTA9B01 PT100 RS485 (temperature)

 

Modbus relay – jak spínat

Modbus relay – jak spínat

Pro každé zařízení je vždy potřeba získat manuál, protože každý výrobce a dokonce i každý konkrétní kus má ovládání trochu jinak

Zatímco u některých relay devices se stav nastavuje 0/1 dle adresy, u jiných je potřeba nastavit složitější hodnotu, která například obsauje i délku zpoždění sepnutí.

2 channel RS485 Relay Eletechsup (a také N4D8B08)

Tento kousek je právě takový oříšek. Je potřeba získat dokumentaci:

Kde se dozvíte, že k nastavní stavu je potřeba volat následující příkaz: ADDR 06 01 02 00 CTC

To přeloženo do řeči Modbus Materu znamená toto:

Tzn, je potřeba nastavit HEX value, a poslat 01 00. poslání samotné 01 totiž nefunguje (ztrávil jsem tu nad tím více než 2 hodiny, kdy sem neměl manuál a řeši jsem ,proc načítání funguje, ale nastavování nikoli 🙂 )

Všechny zařízení a návody, které jsem testoval a sehnal, dávám do jedné společné wiki stránky sem: https://www.vodnici.net/wiki/modbus-relays-seznam-navodu-pro-ruzna-zarizeni/

 

Modbus device – jak nastavit vnitřní parametry

Modbus device – jak nastavit vnitřní parametry

Některé modbus boardy nemají všechny své parametry nastavitelne pomocí DIP switchu, ale je potřeba je nastavit pomocí AT commands nebo modbus address. Například tento 10IOA04, který je vcelku šikovný, má v defaultním nastavení nastaveno, že při sepnutí vstupu se automaticky sepne výstupní relé.

pro tyto potřeby je nutné si sehnat dokumentaci k zařízení, v tomto případě dostupnout třeba zde:

Přímý link na dokumentaci:

dále pak QModbusMaster:

V dokumentaci jsou pak jednak adresy se vstupy a výstupy:

 

a hlavně pak adresy s konfiguračníma parametrama:

Pro vypnutí automatického provázání vstupů a výstupu je potřeba nastavit adresu 250 přes funkco 0x06 Write Single Registry (případně ji načíst přes 0x03 Read Single Registry)

Samotné nastavování relé / vyčítaní stavů rele či vstupů se pak děla přes funkci 0x01 pro Read DO state,  0x05 pro Write single DO state, a 0x02 pro Read signle digital input

Pokud nekomunikuje, zkusit ruzne rychlosti. Defaultní by měla byt 9600, bits 8, stop 1, parity none, rts disabled:

 

link na toto zařízení na Ali:

 

Všechny zařízení a návody, které jsem testoval a sehnal, dávám do jedné společné wiki stránky sem: https://www.vodnici.net/wiki/modbus-relays-seznam-navodu-pro-ruzna-zarizeni/

Jak zprovoznit Waveshare RS485-Ethernet

Jak zprovoznit Waveshare RS485-Ethernet

Krátky návod jak rozběhat Waveshare RS485 to ETH (non POE, ale pro POE by to mělo být stejné)

Link ke koupi zařízení: https://s.click.aliexpress.com/e/_DF7mXrn

Návod k zařízení: https://www.waveshare.com/wiki/RS485_TO_ETH_(B)

Manuál ke stažení: https://files.waveshare.com/upload/4/4d/RS485-to-eth-b-user-manual-EN-v1.33.pdf

VirCom ke stažení: https://files.waveshare.com/upload/4/42/VirCom_en.rar

 

Zprovoznění:

Jako první propojit zařízení pomocí USB-to-Modbus (na konktory A/B modbus) + napájení.

K propojení použít USB->modbus : https://s.click.aliexpress.com/e/_DBYmbaV

Ve windows jde pak USB-modbus vidět takto:

Spustit VirCom-> devices -> search serial, to najde zařízení a přidá ho do seznamu:

double click na zařízení, nastavit DHCP, přepnout na ModbusTCP server, snížit rychlost COM komunikace. Změnit z:

na toto:

Odpojit USB->modbus, zapojit ethernet cabel, počkat na naběhnutí DHCP

pak se připojit na danou adresu, nastavit heslo (dole key).

A tím hotovo.

 

Všechny zařízení a návody, které jsem testoval a sehnal, dávám do jedné společné wiki stránky sem: https://www.vodnici.net/wiki/modbus-relays-seznam-navodu-pro-ruzna-zarizeni/

ZigBee integration with Loxone and ConBee II USB stick

ZigBee integration with Loxone and ConBee II USB stick

What it is?

This is full ZigBee gateway integration for Loxone over ConBee II USB stick, RPI and Node-Red using web sockets for Lights and UDP for sensors. Supported ZigBee vendors can be found here https://phoscon.de/en/conbee2/compatible

What it can do?

There will be more things coming when I add them to my home installation. Currently following ZigBee components are tested and fully working:

  • Xiaomi sensors over UDP
    • Multi (temperature and humidity)
    • Door (open/close)
    • Vibration
    • Water (flood)
    • Motion
    • Button
  • Philips HUE over web-sockets
    • White bulb LWB010
    • Color bulb LCT015

In general, any ConBee supported sensor can be integrated using UDP as well as any switch/stateful component can be integrated with web-sockets.

Why do it?

For me the biggest advantage was to move from complex and wifi unreliable underlying network design of Sensor <ZigBee> Xiaomi GW <wifi> Wemos D1 <wifi> Loxone <eth> which in combination of HUE on Zigbee -> Hue Bridge <wifi> Loxone <eth> sometimes results in missing UDP packet. Now there is only Ethernet connected RPI doing everything with significantly lower latency.

Get rid of Xiaomi GW, get rid of Wemos, get rid of HUE Bridge, never buy any other bridge and just integrate supported ZigBee devices directly to this setup.

On top motion sensors from Xiaomi are working 100% correctly while sending the moving payload every time without delay like in the case of Xiaomi GW.

And last but not least – it is fun 🙂

 

What HW will you need?

There is certain hardware you need to buy to be able to use this.

 

What SW will you need?

Let’s get to the implementation. I will not explain and go deep on how to do UDP virtual inputs in Loxone work, same as for standard Loxone principles or Node-Red because most of it can be easily found on this forum or elsewhere on the internet wikis, articles and community forums.

As I am an extreme rookie coder my Node-Red flows are sometimes stupid and too simple 🙂 Especially functions for sensors can be converted to sub-flows and automated using object variable of source node’s name to avoid manual variable input within the nodes themselves.

I was not able to combine Humi+Temp+Battery information into a single UDP message and send it to Loxone, because of multiple problems (most of them probably by my “not knowing” javascript). So please excuse so many “same” functions.

In the case of Philips HUE, I already got better and the integration is done via subflow which is nicer, but I have no time now to rewrite the sensor part as well. Also, there are people waiting for this manual 🙂

 

1. Setting up RPI

Plug-in the USB stick (using the extension cable to avoid interference especially when pairing bulbs)  to the RPI and go to http:\\ip_rpi, Phoscon APP should be already running and listening on TCP80 as a web server. Go through the initial configuration

Go to Settings and check you have latest FW

Right now the RPI and USB stick are ready to start pairing devices.

 

2. ZigBee device pairing in Phoscon web app

The pairing process is very different for difference ZigBee devices as well as their vendors. Good thing is that Phoscon runs as a web server so you can go with your HUE bulb to the USB stick and use your cell phone to start the pairing process 🙂

Let’s break down the Xiaomi devices and Philips HUE bulbs.

Xiaomi

in general, you need to reset the device if it is already paired with other ZigBee gateway or Xiaomi MI Hub. This is done using 10s hold of the pairing button, after release the Xiaomi HUB says something like “blablabla” which means the device has been unpaired and is ready to pair with another gateway.

  1. Reset Zigbee device
  2. Go to Phoscon->Sensors->Add New Sensor->Other
  3. Press and hold the pairing button on the Zigbee device for approx. 3 sec, release (blue diode blinks) and change the state (motion, door sensor, change of temp/humi)
  4. Wait 1-3 sec and Phoscon app should go green with Pairing Done

Philips HUE

Unfortunately how Xiaomi is easy HUE is not that nice and honestly speaking after pair white and color bulb I am still not sure how it is done 🙂

  1. Reset the BULB. This is already a hard task because you need to have the HUE Dimmer otherwise it is not that easy 🙂 hold ON+OFF together on the remote as close as possible to bulb for 10 seconds. BULB blinks twice, keep holding and go back to the original light. Power cycle the bulb. Bulb SHOULD BE now reset
  2. Go to Phoscon->Lights->Add Light
  3. Now comes the magic
    1. Power Cycle the bulb
    2. Reset the bulb again
    3. 1. again
    4. 2.again
    5. repeat “somehow” until the bulb is detected, always wait for approx 5-10s
    6. sooner or later bulb appears in the Phoscon
  4. rename, done

Ikea, Osram, etc

Come later when I buy them/try them 🙂

 

3. Deconz contrib as a bridge between Phoscon and NodeRed

Node-Red integration with all the above mentioned contribs works as following:

DeconZ contrib has WebSocket connection towards Phoscon and listening for changes on ZigBee devices. this is done via the Deconz-IN NODE, selected device and selected payload to be sent to the next flow.

DeconZ connection towards the Phoscon is authenticated via the API key, which needs to be generated in Phoscon. There is a documented procedure on DeconZ github, however I had to do it manually using CURL POST command according to the documentation because the “Magic” button in Node-Red does not work. Please see https://dresden-elektronik.github.io/deconz-rest-doc/configuration/ and follow the manual

When you have the API key create new connection in your 1st NODE, I had to install another Node Red instance on same RPI as the Phoscon (that is why IP is the loopback), because running the DeconZ contrib on Loxberry located Node Red instance I was not able to put the web socket connection between NR<>Phoscon to work.

Correctly connected NODE results in a list of available devices, select payload based on what you want to monitor and you are all set

 

4. Loxone and Sensors over UDP

Set up a virtual UDP input in Loxone (follow any UDP related manual for Loxone). The principle is exactly the same as here https://www.vodnici.net/2019/02/zigbee2mqtt-nodered-a-loxone/ only the source of the UDP message will be different.

Every sensor and every payload type has to have its own Deconz-IN NODE which then passes the function and is send to Loxone over UDP.

In Loxone UDP virtual input is create on the same UDP port as the Node Red UDP OUT NODE and command detection is set according to msg.payload coming from the function for each and every NODE.

Here is the complete Node Red flow:

[{"id":"91feccf8.c1b43","type":"tab","label":"Wiki","disabled":false,"info":""},{"id":"79b42ace.b5d094","type":"deconz-input","z":"91feccf8.c1b43","name":"SKLEP-temp","server":"98ad42dd.bf8fa","device":"00:15:8d:00:01:f2:aa:ee-01-0402","device_name":"MS - SKLEP : ZHATemperature","state":"temperature","output":"always","outputAtStartup":true,"x":130,"y":80,"wires":[["4a5b4a0a.37e0c4"],[]]},{"id":"32f1f979.ee1426","type":"deconz-input","z":"91feccf8.c1b43","name":"SKLEP-humi","server":"98ad42dd.bf8fa","device":"00:15:8d:00:01:f2:aa:ee-01-0405","device_name":"Multi Sensor - SKLEP : ZHAHumidity","state":"humidity","output":"always","outputAtStartup":true,"x":130,"y":120,"wires":[["8a91e089.0b19e"],[]]},{"id":"41f30e16.2bfd","type":"deconz-battery","z":"91feccf8.c1b43","name":"SKLEP-bat","server":"98ad42dd.bf8fa","device":"00:15:8d:00:01:f2:aa:ee-01-0405","device_name":"Multi Sensor - SKLEP : ZHAHumidity","outputAtStartup":true,"x":120,"y":160,"wires":[[],["ca1a6b72.6730a8"]]},{"id":"ca1a6b72.6730a8","type":"function","z":"91feccf8.c1b43","name":"Bat2Lox","func":"var name=\"Sklep\"\nmsg.payload=name+\"-Batt \" + msg.payload.BatteryLevel;\nreturn msg;","outputs":1,"noerr":0,"x":260,"y":160,"wires":[["8480181f.4df158"]]},{"id":"8480181f.4df158","type":"udp out","z":"91feccf8.c1b43","name":"UDP2Loxone 55556 Conbee","addr":"loxone_IP","iface":"","port":"55556","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":520,"y":120,"wires":[]},{"id":"4a5b4a0a.37e0c4","type":"function","z":"91feccf8.c1b43","name":"Temp2Lox","func":"var name = \"Sklep\"\nvar cat = \"Temp\"\n\nvar value = (msg.payload/100).toFixed(1);\nmsg.payload=name+cat+\" \" + value;\n\nreturn msg;","outputs":1,"noerr":0,"x":290,"y":80,"wires":[["8480181f.4df158"]]},{"id":"8a91e089.0b19e","type":"function","z":"91feccf8.c1b43","name":"Humi2Lox","func":"var name = \"Sklep\"\nvar cat = \"Humi\"\nvar value = (msg.payload/100).toFixed(1);\n\nmsg.payload=name+cat+\" \" + value;\n\nreturn msg;\n","outputs":1,"noerr":0,"x":280,"y":120,"wires":[["8480181f.4df158"]]},{"id":"3364467a.87f6ba","type":"deconz-input","z":"91feccf8.c1b43","name":"WS1-Sklep","server":"98ad42dd.bf8fa","device":"00:15:8d:00:02:11:b4:b2-01-0500","device_name":"WS1 - Sklep : ZHAWater","state":"water","output":"always","outputAtStartup":true,"x":120,"y":220,"wires":[["8b36df82.ddca6"],[]]},{"id":"cd4684f6.47e3c8","type":"deconz-battery","z":"91feccf8.c1b43","name":"WS1-Sklep-Batt","server":"98ad42dd.bf8fa","device":"00:15:8d:00:02:11:b4:b2-01-0500","device_name":"WS1 - Sklep : ZHAWater","outputAtStartup":true,"x":140,"y":260,"wires":[[],["8744fef3.4541b"]]},{"id":"8744fef3.4541b","type":"function","z":"91feccf8.c1b43","name":"Bat2Lox","func":"var name=\"WS1\"\nmsg.payload=name+\"-Batt \" + msg.payload.BatteryLevel;\nreturn msg;","outputs":1,"noerr":0,"x":320,"y":260,"wires":[["d20825bd.21fd78"]]},{"id":"8b36df82.ddca6","type":"function","z":"91feccf8.c1b43","name":"Water2Lox","func":"var name = \"WS1\";\n\nvar value = msg.payload;\n\nif ( value === false )\n{\nmsg.payload = name+\"-OK\";\nreturn msg;\n} \n\nelse if (value === true) \n{\nmsg.payload = name+\"-FLOOD\";\nreturn msg;\n}","outputs":1,"noerr":0,"x":310,"y":220,"wires":[["d20825bd.21fd78"]]},{"id":"d20825bd.21fd78","type":"udp out","z":"91feccf8.c1b43","name":"UDP2Loxone 55556 Conbee","addr":"loxone_IP","iface":"","port":"55556","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":540,"y":240,"wires":[]},{"id":"a342e55f.2fa4a8","type":"deconz-input","z":"91feccf8.c1b43","name":"MO5","server":"98ad42dd.bf8fa","device":"00:15:8d:00:01:de:03:59-01-0406","device_name":"MO5 : ZHAPresence","state":"presence","output":"onupdate","outputAtStartup":false,"x":110,"y":320,"wires":[["cf724917.b98068"],[]]},{"id":"77bc9016.44412","type":"udp out","z":"91feccf8.c1b43","name":"UDP2Loxone 55556 Conbee","addr":"loxone_IP","iface":"","port":"55556","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":520,"y":340,"wires":[]},{"id":"f9e1ca5a.45c918","type":"deconz-battery","z":"91feccf8.c1b43","name":"MO5-batt","server":"98ad42dd.bf8fa","device":"00:15:8d:00:01:de:03:59-01-0406","device_name":"MO5 : ZHAPresence","outputAtStartup":true,"x":120,"y":360,"wires":[[],["bd57d866.583298"]]},{"id":"bd57d866.583298","type":"function","z":"91feccf8.c1b43","name":"Bat2Lox","func":"var name=\"MO5\"\nmsg.payload=name+\"-Batt \" + msg.payload.BatteryLevel;\nreturn msg;","outputs":1,"noerr":0,"x":300,"y":360,"wires":[["77bc9016.44412"]]},{"id":"cf724917.b98068","type":"function","z":"91feccf8.c1b43","name":"MO2Lox","func":"var name = \"MO5\";\n\nvar value = msg.payload;\n\nif ( value === false )\n{\nmsg.payload = name+\"-OK\";\nreturn msg;\n} \n\nelse if (value === true) \n{\nmsg.payload = name+\"-MOVE\";\nreturn msg;\n}","outputs":1,"noerr":0,"x":310,"y":320,"wires":[["77bc9016.44412"]]},{"id":"f8c334a0.98b8f8","type":"deconz-battery","z":"91feccf8.c1b43","name":"DO1-batt","server":"98ad42dd.bf8fa","device":"00:15:8d:00:01:a2:1a:19-01-0006","device_name":"DO1-Mail : ZHAOpenClose","outputAtStartup":true,"x":120,"y":460,"wires":[[],["f347ade8.daa3d"]]},{"id":"5e5a7655.72f428","type":"deconz-input","z":"91feccf8.c1b43","name":"DO1","server":"98ad42dd.bf8fa","device":"00:15:8d:00:01:a2:1a:19-01-0006","device_name":"DO1-Mail : ZHAOpenClose","state":"open","output":"always","outputAtStartup":true,"x":110,"y":420,"wires":[["92ed2472.10f558"],[]]},{"id":"597b2e00.6afd74","type":"udp out","z":"91feccf8.c1b43","name":"UDP2Loxone 55556 Conbee","addr":"loxone_IP","iface":"","port":"55556","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":500,"y":440,"wires":[]},{"id":"f347ade8.daa3d","type":"function","z":"91feccf8.c1b43","name":"Bat2Lox","func":"var name=\"DO1\"\nmsg.payload=name+\"-Batt \" + msg.payload.BatteryLevel;\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":460,"wires":[["597b2e00.6afd74"]]},{"id":"92ed2472.10f558","type":"function","z":"91feccf8.c1b43","name":"DO2Lox","func":"var name = \"DO1\";\n\nvar value = msg.payload;\n\nif ( value === false )\n{\nmsg.payload = name+\"-close\";\nreturn msg;\n} \n\nelse if (value === true) \n{\nmsg.payload = name+\"-open\";\nreturn msg;\n}","outputs":1,"noerr":0,"x":280,"y":420,"wires":[["597b2e00.6afd74"]]},{"id":"e058f740.fcccf8","type":"deconz-input","z":"91feccf8.c1b43","name":"SW4","server":"98ad42dd.bf8fa","device":"00:15:8d:00:02:24:3c:d3-01-0006","device_name":"SW4 : ZHASwitch","state":"buttonevent","output":"onchange","outputAtStartup":false,"x":110,"y":520,"wires":[["13832d70.e82083"],[]]},{"id":"442659d9.d52588","type":"udp out","z":"91feccf8.c1b43","name":"UDP2Loxone 55556 Conbee","addr":"loxone_IP","iface":"","port":"55556","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":540,"y":540,"wires":[]},{"id":"13832d70.e82083","type":"function","z":"91feccf8.c1b43","name":"Button2Lox","func":"var name = \"SW4\";\n\nvar value = msg.payload;\n\nif ( value == \"1002\" )\n{\nmsg.payload = name+\"-single\";\nreturn msg;\n} \n\nelse if (value == \"1004\") \n{\nmsg.payload = name+\"-double\";\nreturn msg;\n}\n\nelse if (value == \"1001\") \n{\nmsg.payload = name+\"-LP\";\nreturn msg;\n}\n\nelse if (value == \"1003\") \n{\nmsg.payload = name+\"-LR\";\nreturn msg;\n}","outputs":1,"noerr":0,"x":310,"y":520,"wires":[["442659d9.d52588"]]},{"id":"31ad16cc.dee63a","type":"function","z":"91feccf8.c1b43","name":"Bat2Lox","func":"var name=\"SW4\"\nmsg.payload=name+\"-Batt \" + msg.payload.BatteryLevel;\nreturn msg;\n","outputs":1,"noerr":0,"x":300,"y":560,"wires":[["442659d9.d52588"]]},{"id":"3a7a3e31.6daed2","type":"deconz-battery","z":"91feccf8.c1b43","name":"SW4-batt","server":"98ad42dd.bf8fa","device":"00:15:8d:00:02:24:3c:d3-01-0006","device_name":"SW4 : ZHASwitch","outputAtStartup":true,"x":120,"y":560,"wires":[[],["31ad16cc.dee63a"]]},{"id":"dc21844c.364c08","type":"deconz-input","z":"91feccf8.c1b43","name":"VS01","server":"98ad42dd.bf8fa","device":"00:15:8d:00:02:b0:99:85-01-0101","device_name":"Vibration Sensor : ZHAVibration","state":"0","output":"always","outputAtStartup":true,"x":110,"y":620,"wires":[["6cd0d254.aa93ec"],[]]},{"id":"274c1477.57932c","type":"udp out","z":"91feccf8.c1b43","name":"UDP2Loxone 55556 Conbee","addr":"loxone_IP","iface":"","port":"55556","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":510,"y":640,"wires":[]},{"id":"61975736.93de08","type":"function","z":"91feccf8.c1b43","name":"Bat2Lox","func":"var name=\"VS01\"\nmsg.payload=name+\"-Batt \" + msg.payload.BatteryLevel;\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":660,"wires":[["274c1477.57932c"]]},{"id":"6cd0d254.aa93ec","type":"function","z":"91feccf8.c1b43","name":"VS2Lox","func":"var name = \"VS01\";\n\nvar value = msg.payload.vibration;\n\nif ( value === false )\n{\nmsg.payload = name+\"-OK\";\nreturn msg;\n} \n\nelse if (value === true) \n{\nmsg.payload = name+\"-vibration\";\nreturn msg;\n}","outputs":1,"noerr":0,"x":290,"y":620,"wires":[["274c1477.57932c"]]},{"id":"8f0ea705.033b08","type":"deconz-battery","z":"91feccf8.c1b43","name":"VS01-Batt","server":"98ad42dd.bf8fa","device":"00:15:8d:00:02:b0:99:85-01-0101","device_name":"Vibration Sensor : ZHAVibration","outputAtStartup":true,"x":120,"y":660,"wires":[[],["61975736.93de08"]]},{"id":"98ad42dd.bf8fa","type":"deconz-server","z":"","name":"conbee","ip":"IP","port":"80","apikey":"APIKEY","ws_port":"443","secure":false,"polling":"5"}]

You need to change the name in each function block variable which then changes the UDP message towards Loxone.

Messages to detect in Loxone are following for each type:

Battery: Sklep-Batt \v (default values 0,0,100,100), not digital input

Temperature: SklepTemp \v (default values 0,0,100,100), not digital input

Humidity: SklepHumi \v (default values 0,0,100,100), not digital input

Motion: MO3-move, digital input

etc etc etc

After Node Red “deploy button” all message are generated and sent to Loxone, so you can create the inputs as you wish, also with renaming.

The enhancement would be to have only 1 function/sub-flow for everything and do the detection based on the name of the DeconZ source node or even better based on the name of the sensor in Phoscon. However, I have found out this is part of the msg. too late 🙂 So it comes probably later.

Adding of a new sensor requires: pairing, copy/pasting of respective node red nodes, changing devices, changing names, changing functions variable, setting up loxone UDP inputs.

5. Loxone and Philips HUE over web-sockets

Integration of Philips HUE is possible over web-sockets and native LightController function block in Loxone.

  • Set up a new light controller function block v1 or v2 and set the output to RGB

Now we need to make the controller available in Node Red, this is done via https://flows.nodered.org/node/node-red-contrib-loxone and NODE called Controll-IN.

Similarly as in Phoscon you need to establish a new connection towards Loxone, only blocks with enabled visualization will be available and I highly recommend creating dedicated users and group for any external integrations for Loxone.

 

When you get “got miniserver structure” green message all is OK and continue selecting the function block you created by name and selecting State based on white/color bulb

Configure the DeconZ-OUT NODE with selecting the paired bulb, setting command to object:json and payload in default

Now we have coming HSV string (1st payload) from LoxoneLightController and we have a bulb which requires JSON object in the following format (2nd payload). If you are interested in what it is in deep feel free to follow wiki article – https://en.wikipedia.org/wiki/HSL_and_HSV 🙂

White Bulb is easier as there is only a single integer coming from Loxone which needs to be translated to Brightness within the JSON.

The integration is done using my simple sub-flow located and described here https://flows.nodered.org/flow/e8ccc3a40cde8e169ed528d9bf51de33 this sub-flow detect if data are for white or colored lamp and transforms to HSV into 0-255 Brightness, 0-255 Saturation, 0-65535 Color.

[{"id":"7be55345.48bebc","type":"subflow","name":"Loxone2HUE","info":"","category":"","in":[{"x":380,"y":280,"wires":[{"id":"525c492b.7ab478"}]}],"out":[{"x":900,"y":280,"wires":[{"id":"ebbc239d.76c84","port":0},{"id":"467ba87f.00d8e8","port":0}]}],"env":[],"color":"#DDAA99"},{"id":"ebbc239d.76c84","type":"function","z":"7be55345.48bebc","name":"COLOR","func":"msg.payload = msg.payload.replace(\"hsv(\", \"\").replace(\")\", \"\").split(\",\");\n\nvar hue = Number(msg.payload[0]) * 65500 / 360;\nvar sat = Number(msg.payload[1]) * 255 /100;\nvar bri = Number(msg.payload[2]) * 255 /100 ;\nvar time = 5; \n\nif (bri == '0') {\n  return { payload: { on: false } };\n}\n\nmsg.payload = {\"on\":true,\"bri\":bri,\"hue\":hue,\"sat\":sat,\"transitiontime\":time};\nreturn msg;","outputs":1,"noerr":0,"x":740,"y":220,"wires":[[]]},{"id":"525c492b.7ab478","type":"switch","z":"7be55345.48bebc","name":"White or Color","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"hsv(","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":560,"y":280,"wires":[["ebbc239d.76c84"],["467ba87f.00d8e8"]]},{"id":"467ba87f.00d8e8","type":"function","z":"7be55345.48bebc","name":"WHITE","func":"var bri = msg.payload * 255 /100 ;\nvar time = 5;\n\nif (bri == '0') {\n  return { payload: { on: false } };\n}\n\nmsg.payload = {\"on\":true,\"bri\":bri,\"transitiontime\":time};\nreturn msg;","outputs":1,"noerr":0,"x":740,"y":340,"wires":[[]]}]

Complete flow is not needed I believe as the only part for the function is available on GIT, rest is anyway case-specific and cant is used, as configuration NODEs for both Loxone and DeconZ will need to have your own configurations (IP, API, TOKEN, USER, PASSWORD,…).

I will try to add more as I integrate more

Have fun and let me know! Here in Czech/English!

Jakub

CO2 senzor na báze SCD30

CO2 senzor na báze SCD30

Tento článok predstavuje jednoduchý návod ako uviesť do prevádzky senzor CO2, ktorý som predstavil na fóre. Samotný senzor SCD30 je doplnený o elektroniku ktorá rieši jednoduché ochrany napájania a komunikačnej zbernice, prevod z pwm na analog signál a realizuje rozhranie RS485, ktoré využíva aj Loxone modbus extension.

Datasheet k samotnému senzoru kde je popísaná komunikácia možno nájsť TU. Odporúčam ho naštudovať.

Krabička:

Krabičku na senzor som navrhol a následne vytlačil na 3D tlačiarni z materiálu PLA s hrúbkou jednej tlačenej vrstvy 0.2mm. Samotná krabička pozostáva z dvoch dielov, ktoré do seba zacvaknú, takže žiadne lepidlá a celé to ide bez problémov rozobrať a opätovne znovu zložiť.

Modely na stiahnutie: (doplním neskôr)

 

Pripojenie:

Zariadenie obsahuje tri svorkovnice. Prvá zľava slúži na napájanie pomocou 5V. V druhej sú signály A a B modbus zbernice na RS485. Tretí konektor do ktorého sa dajú pripojiť tri vodiče slúži na prípadné pripojenie analógového výstupu.  Prvý s označením DR sa zapájať nemusí. Je to iba vyvedený signál senzora SCD30 Data Ready. Prostredný vodič je analógový výstup s rozsahom 0V-3V kde 0V reprezentuje hodnotu 0 ppm Co2 a 3V reprezentujú 5000 ppm CO2. Analógový výstup je lineárny. Pre zábudlivých je väčšina svorkovníc označených aj z druhej strany plošného spoja.

ďalej sú cez šachtu prístupné dva piny, ktoré po prepojení (napríklad jumprom) pripoja na zbernicu RS485 terminačný odpor, ktorý sa používa v prípade,že by senzor bol posledným zariadením pripojeným na zbernici.

Oživenie:

Tý čo si kúpili senzor odomňa ho majú už oživený a po pripojení napájania začne senzor automaticky vykonávať meranie každé 2s. Toto meranie je možné prečítať potom cez modbus alebo na svorke analogového výstupu.

Samotný senzor po pripojení napájania je pripravený ako modbus slave zariadenie na adrese 0x61 kde čaká na jednotlive príkazy. Zariadenie môžeme cez vodiče A a B pripojiť priamo na loxone modbus extension, alebo pomocou usb -> RS485 prevodníka (aliexpress) pripojiť k PC.

 

To, že senzor príma alebo odosiela dáta môžeme vidieť cez štrbinku na boku krabičky kde počas spracovania údajov blikajú dve diódy červená ako Tx a zelená ako Rx.

Pre úplne nové senzory SCD30 priamo od výrobcu treba najskôr senzor uviesť do módu kontinuálneho merania až potom senzor začne merať koncentráciu co2 (na mnou dodaných senzoroch je tento krok už realizovaný). To, že senzor práve robí meranie možno vidieť podľa presvitajúceho oranžového svetielka z tela senzoru. Toto svetlo je dosť slabé preto je ho vidno iba v úplnej tme.

Aj keď samotný senzor SCD30 je veľmi presný a merane hodnoty kompenzuje podla nameranej teploty a vlhkosti, pre ešte väčšie zvýšenie presnosti je dobre nastaviť presnú nadmorskú výšku senzora. Nadmorská výška sa zapisuje pomocou modbus rozhrania ako funkcia 6 adresa 0x0038 a výška v metroch.

Takisto je možné upraviť frekvenciu merania (základne je nastavená na 2s) pripadne nastaviť offset teplomera a podobne. Všetky jednotlive registre sú podrobne popísane  TU aj s príkladmi.

Čítanie dát:

Všetky merané veličiny (co2, teplota, vlhkosť) sú prenášané ako 4 bajtový float vo formáte big endian. Veličiny možno nájsť na nasledovných adresách:

co2 – 0x0028

teplota – 0x002A

vlhkosť – 0x002C

Ja som údaje so senzora prečítal pomocou PC a prevodníka na RS485, keďže momentálne nemám k dispozícii miniserver. Ako program som použil modbus pool, ale sú aj iné free alternatívy ako napríklad comtest.

Program modbus pool umožňuje logovať údaje priamo do excelu. Ak niekoho zaujíma ako rastie koncentrácia co2 v spálni 16m2, 2 osoby a otvorené dvere do obývačky môže sa pozrieť do priloženého súboru test_co2_sob. Je tam vidno ako postupne narastala koncentrácia co2 a následne ráno sme spravili nárazové vetranie a ďalej spali pri zavretých dverách.

GSM modul (2. díl – hlasové volání)

GSM modul (2. díl – hlasové volání)

Toto je druhá část návodu na GSM modul postavený na Raspberry Pi a komunikující s Loxonem přes UDP. První část najdete zde:

GSM modul (1. díl – integrace do Loxone přes UDP)

Co Loxone naučíme v tomto druhém dílu

  • mluvit do telefonu (přes text-to-speech)
  • vlastně získáme  plnohodnotnou alternativu ke službě “Loxone Caller”
  • naučíme Loxone navíc i zvednout příchozí hovor a mluvit do telefonu

Co to neumí

  • poslouchat v telefonu (speech-to-text)
  • přemýšlet

Pokud byste chtěli něco, co vás umí poslouchat a reagovat na vaše požadavky, pořiďte si Siri, Alexu, Google Home nebo nějakého jiného robota s AI. Na integraci těchto robotů do Node Red a do Loxonu už taky nějaké nástroje existují.

Jaký hardware budete potřebovat

Viz minulý díl.

Jaký software budete potřebovat

Node Red

Někteří už tak jako tak máte Node Red nainstalovaný. Ostatní si dovolím odkázat na existující návody:

Ffmpeg a Mp3wrap

Mp3 wrap budeme potřebovat na slepování MP3 souborů s hlasovou zprávou, které Node Red stahuje z Googlu. Ffmpeg je potřeba na samotné přehrání MP3 souboru se zprávou do GSM modulu.

sudo apt-get install ffmpeg mp3wrap

Stačí nainstalovat, není potřeba nic nastavovat, o vše se postará Node Red.

Nody

Až budete mít nainstalovaný Node Red, spusťte si jej v prohlížeči  ( <IP_adresa>:1880 ) a přes Manage Palette (menu vpravo nahoře) si doinstalujte tyto nody:

  • node-red-contrib-function-npm
  • node-red-contrib-string
  • node-red-contrib-traffic
  • node-red-contrib-fs-ops
  • node-red-contrib-google-tts
  • node-red-contrib-loop-processing
  • node-red-contrib-md5

Flow

Až budete mít doinstalované Nody, vložte si do Node Red tento flow, ve kterém je celý program na řízení GSM modulu:

[{"id":"886ce1dc.59db3","type":"subflow","name":"Google TTS > MP3 file","info":"","category":"","in":[{"x":80,"y":120,"wires":[{"id":"d81f9a91.5459"},{"id":"858f31a3.8e3bf"}]}],"out":[{"x":2040,"y":340,"wires":[{"id":"390be0c6.c36c98","port":0}]},{"x":2040,"y":80,"wires":[{"id":"240cfaf8.ac223e","port":0},{"id":"3f0e743e.5e8794","port":2}]}],"outputLabels":["OUTPUT","ERROR","CACHEFULL"]},{"id":"5a4d9876.aad888","type":"md5","z":"886ce1dc.59db3","name":"","fieldToHash":"message","fieldTypeToHash":"msg","hashField":"hash","hashFieldType":"msg","x":670,"y":120,"wires":[["5f6402d0.9460fc"]]},{"id":"8c914dff.1f5e7","type":"http request","z":"886ce1dc.59db3","name":"","method":"GET","ret":"bin","url":"","tls":"","x":430,"y":340,"wires":[["61b277f6.633a98"]]},{"id":"61b277f6.633a98","type":"file","z":"886ce1dc.59db3","name":"","filename":"","appendNewline":false,"createDir":false,"overwriteFile":"true","x":570,"y":340,"wires":[["bc5fa4b5.ac6a88"]]},{"id":"7bf55fc2.c15c88","type":"fs-ops-delete","z":"886ce1dc.59db3","name":"","path":"","pathType":"str","filename":"filename","filenameType":"msg","x":750,"y":520,"wires":[["50ee971a.15b1b8"]]},{"id":"6a9d2543.e7f9e4","type":"fs-ops-access","z":"886ce1dc.59db3","name":"","path":"","pathType":"str","filename":"filename","filenameType":"msg","read":true,"write":false,"throwerror":false,"x":930,"y":120,"wires":[["45f43985.39b5e8"],["90e5f25d.6e7698"]]},{"id":"5f6402d0.9460fc","type":"function","z":"886ce1dc.59db3","name":".mp3","func":"msg.filename=global.get('directory')+\"\\/\"+msg.hash+\".mp3\";\nmsg.filearray = [];\nmsg.payload = msg.message;\nreturn msg;","outputs":1,"noerr":0,"x":790,"y":120,"wires":[["6a9d2543.e7f9e4"]]},{"id":"f68676ec.779608","type":"switch","z":"886ce1dc.59db3","name":"","property":"url","propertyType":"msg","rules":[{"t":"istype","v":"array","vt":"array"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":270,"y":340,"wires":[["99b91fec.690b18"],["8c914dff.1f5e7"]]},{"id":"5e8d3d23.9fdda4","type":"array-loop","z":"886ce1dc.59db3","name":"","key":"index","keyType":"msg","reset":true,"resetValue":"value-null","array":"urlarray","arrayType":"msg","x":330,"y":400,"wires":[["bc5fa4b5.ac6a88"],["2fd238a1.1492b8"]]},{"id":"f052ae05.bf6938","type":"http request","z":"886ce1dc.59db3","name":"","method":"GET","ret":"bin","url":"","tls":"","x":270,"y":460,"wires":[["20c0aef9.9cfda2"]]},{"id":"20c0aef9.9cfda2","type":"file","z":"886ce1dc.59db3","name":"","filename":"","appendNewline":false,"createDir":false,"overwriteFile":"true","x":410,"y":460,"wires":[["5e8d3d23.9fdda4"]]},{"id":"2fd238a1.1492b8","type":"function","z":"886ce1dc.59db3","name":".mp3","func":"msg.filename = global.get('directory')+\"\\/\"+msg.hash+\"[\"+msg.index.toString().padStart(2,\"0\")+\"].mp3\";\nmsg.filearray[msg.index] = msg.filename;\nmsg.url = msg.urlarray[msg.index];\nreturn msg;","outputs":1,"noerr":0,"x":130,"y":460,"wires":[["f052ae05.bf6938"]]},{"id":"99b91fec.690b18","type":"change","z":"886ce1dc.59db3","name":"","rules":[{"t":"move","p":"url","pt":"msg","to":"urlarray","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":160,"y":400,"wires":[["5e8d3d23.9fdda4"]]},{"id":"bc5fa4b5.ac6a88","type":"template","z":"886ce1dc.59db3","name":"mp3wrap command","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"mp3wrap ~/{{{global.directory}}}/{{{hash}}}.mp3 ~/{{{global.directory}}}/{{{hash}}}*mp3 ~/{{{global.directory}}}/silence.mp3","x":570,"y":400,"wires":[["1b9000e9.05a44f"]]},{"id":"1b9000e9.05a44f","type":"exec","z":"886ce1dc.59db3","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"mp3wrap","x":760,"y":400,"wires":[["50ee971a.15b1b8"],[],[]]},{"id":"50ee971a.15b1b8","type":"array-loop","z":"886ce1dc.59db3","name":"","key":"index","keyType":"msg","reset":false,"resetValue":"value-null","array":"filearray","arrayType":"msg","x":670,"y":460,"wires":[["d864b18d.9f796"],["794b0628.ddbbd"]]},{"id":"794b0628.ddbbd","type":"function","z":"886ce1dc.59db3","name":".mp3","func":"msg.filename = msg.filearray[msg.index];\nreturn msg;","outputs":1,"noerr":0,"x":610,"y":520,"wires":[["7bf55fc2.c15c88"]]},{"id":"7a2e347a.0044dc","type":"fs-ops-move","z":"886ce1dc.59db3","name":"","sourcePath":".","sourcePathType":"str","sourceFilename":"oldfilename","sourceFilenameType":"msg","destPath":".","destPathType":"str","destFilename":"filename","destFilenameType":"msg","link":false,"x":980,"y":460,"wires":[["45f43985.39b5e8"]]},{"id":"d864b18d.9f796","type":"function","z":"886ce1dc.59db3","name":"rename","func":"msg.oldfilename = global.get('directory')+\"\\/\"+msg.hash+\"_MP3WRAP.mp3\";\nmsg.filename = global.get('directory')+\"\\/\"+msg.hash+\".mp3\";\nreturn msg;","outputs":1,"noerr":0,"x":840,"y":460,"wires":[["7a2e347a.0044dc"]]},{"id":"45f43985.39b5e8","type":"template","z":"886ce1dc.59db3","name":"command","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"du -s {{{global.directory}}} | cut -f1 | tr -d '\\n'","x":1180,"y":300,"wires":[["7cfa1f4d.f07aa8"]]},{"id":"7cfa1f4d.f07aa8","type":"exec","z":"886ce1dc.59db3","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"du","x":1310,"y":300,"wires":[["390be0c6.c36c98"],[],[]]},{"id":"390be0c6.c36c98","type":"function","z":"886ce1dc.59db3","name":"Cache size","func":"msg.cachesize = parseInt(msg.payload);\nif (msg.cachesize >= global.get('cachelimit')) {\n msg.cachefull = true;\n} else {\n msg.cachefull = false;\n}\nglobal.set('cachefull', msg.cachefull);\nreturn msg;","outputs":1,"noerr":0,"x":1490,"y":300,"wires":[["9cfafe99.3843b8"]]},{"id":"240cfaf8.ac223e","type":"trigger","z":"886ce1dc.59db3","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"10","extend":false,"units":"s","reset":"RESET","bytopic":"all","name":"","x":1650,"y":20,"wires":[[]]},{"id":"9cfafe99.3843b8","type":"change","z":"886ce1dc.59db3","name":"RESET","rules":[{"t":"set","p":"payload","pt":"msg","to":"RESET","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1640,"y":60,"wires":[["240cfaf8.ac223e"]]},{"id":"40cb3ff0.01a9a","type":"switch","z":"886ce1dc.59db3","name":"","property":"number","propertyType":"msg","rules":[{"t":"eq","v":"test","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":410,"y":120,"wires":[["dfae422e.5139"],["ca4f9c14.129e38"]]},{"id":"919d3cc0.047968","type":"http request","z":"886ce1dc.59db3","name":"","method":"GET","ret":"bin","url":"","tls":"","x":610,"y":80,"wires":[["b0c5a4c2.b70148"]]},{"id":"6ab5e1b2.31064","type":"exec","z":"886ce1dc.59db3","command":"","addpay":true,"append":"","useSpawn":"true","timer":"","oldrc":false,"name":"ffmpeg","x":1550,"y":120,"wires":[[],[],["3f0e743e.5e8794","7f448bb.85f7bf4"]]},{"id":"857bdd0b.40af2","type":"template","z":"886ce1dc.59db3","name":"test command","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"ffmpeg -i {{{filename}}} -f s16le -acodec pcm_s16le -ac 1 -ar 8000 -","x":1380,"y":120,"wires":[["6ab5e1b2.31064"]]},{"id":"3f0e743e.5e8794","type":"switch","z":"886ce1dc.59db3","name":"","property":"payload.code","propertyType":"msg","rules":[{"t":"eq","v":"255","vt":"num"},{"t":"eq","v":"0","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":3,"x":1710,"y":120,"wires":[["9cfafe99.3843b8"],["9cfafe99.3843b8"],[]]},{"id":"b0c5a4c2.b70148","type":"file","z":"886ce1dc.59db3","name":"","filename":"","appendNewline":false,"createDir":false,"overwriteFile":"true","x":750,"y":80,"wires":[["97dd19e0.2b6e48"]]},{"id":"97dd19e0.2b6e48","type":"template","z":"886ce1dc.59db3","name":"command","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"du -s {{{global.directory}}} | cut -f1 | tr -d '\\n'","x":880,"y":80,"wires":[["566b4bed.0ff224"]]},{"id":"566b4bed.0ff224","type":"exec","z":"886ce1dc.59db3","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"du","x":1010,"y":80,"wires":[["5b0a765c.b69d48"],[],[]]},{"id":"90e5f25d.6e7698","type":"google-tts","z":"886ce1dc.59db3","name":"","inputField":"payload","inputFieldType":"msg","outputField":"url","outputFieldType":"msg","languageField":"language","languageFieldType":"global","speedField":"3","speedFieldType":"num","x":140,"y":340,"wires":[["f68676ec.779608"]]},{"id":"dfae422e.5139","type":"google-tts","z":"886ce1dc.59db3","name":"","inputField":"test","inputFieldType":"str","outputField":"url","outputFieldType":"msg","languageField":"language","languageFieldType":"global","speedField":"3","speedFieldType":"num","x":340,"y":80,"wires":[["2aad085e.7fd5"]]},{"id":"2aad085e.7fd5","type":"function","z":"886ce1dc.59db3","name":".mp3","func":"msg.filename=global.get('directory')+\"\\/test.mp3\";\nmsg.filearray = [];\nmsg.payload = msg.message;\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":80,"wires":[["919d3cc0.047968"]]},{"id":"7f448bb.85f7bf4","type":"fs-ops-delete","z":"886ce1dc.59db3","name":"","path":"","pathType":"str","filename":"filename","filenameType":"msg","x":1690,"y":200,"wires":[[]]},{"id":"d81f9a91.5459","type":"change","z":"886ce1dc.59db3","name":"","rules":[],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":40,"wires":[["240cfaf8.ac223e"]]},{"id":"858f31a3.8e3bf","type":"fs-ops-mkdir","z":"886ce1dc.59db3","name":"","path":"","pathType":"str","dirname":"directory","dirnameType":"global","mode":"755","fullpath":"","fullpathType":"msg","x":260,"y":120,"wires":[["40cb3ff0.01a9a"]]},{"id":"5b0a765c.b69d48","type":"function","z":"886ce1dc.59db3","name":"Cache size","func":"msg.cachesize = parseInt(msg.payload);\nif (msg.cachesize >= global.get('cachelimit')) {\n msg.cachefull = true;\n} else {\n msg.cachefull = false;\n}\nglobal.set('cachefull', msg.cachefull);\nreturn msg;","outputs":1,"noerr":0,"x":1190,"y":140,"wires":[["857bdd0b.40af2"]]},{"id":"ca4f9c14.129e38","type":"fs-ops-access","z":"886ce1dc.59db3","name":"","path":"directory","pathType":"global","filename":"silence.mp3","filenameType":"str","read":true,"write":false,"throwerror":false,"x":250,"y":180,"wires":[["5a4d9876.aad888"],["af657cfb.1864c8"]]},{"id":"37ed82b.1fe1afe","type":"exec","z":"886ce1dc.59db3","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"ffmpeg","x":630,"y":180,"wires":[["5a4d9876.aad888"],[],[]]},{"id":"af657cfb.1864c8","type":"template","z":"886ce1dc.59db3","name":"silence command","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"ffmpeg -f lavfi -i anullsrc=r=24000:cl=mono -t 1 -b:a 32k -acodec libmp3lame {{{global.directory}}}/silence.mp3","x":470,"y":180,"wires":[["37ed82b.1fe1afe"]]},{"id":"4bfe1136.14a238","type":"subflow","name":"/dev/ttyUSB2","info":"","category":"","in":[],"out":[{"x":300,"y":100,"wires":[{"id":"9d86fe98.cc1438","port":0}]}],"icon":"node-red/serial.png"},{"id":"9d86fe98.cc1438","type":"serial in","z":"4bfe1136.14a238","name":"/dev/ttyUSB2","serial":"d5b55732.e05ae","x":150,"y":100,"wires":[[]]},{"id":"b0491a09.bf712","type":"subflow","name":"/dev/ttyUSB2","info":"","category":"","in":[{"x":120,"y":120,"wires":[{"id":"41d6ed41.2b20e4"}]}],"out":[{"x":420,"y":120,"wires":[{"id":"41d6ed41.2b20e4","port":0}]}],"icon":"node-red/serial.png"},{"id":"41d6ed41.2b20e4","type":"serial request","z":"b0491a09.bf712","name":"/dev/ttyUSB2","serial":"d5b55732.e05ae","x":270,"y":120,"wires":[[]]},{"id":"d5b55732.e05ae","type":"serial-port","z":"","serialport":"/dev/ttyUSB2","serialbaud":"115200","databits":"8","parity":"none","stopbits":"1","waitfor":"","newline":"\\r","bin":"false","out":"char","addchar":"","responsetimeout":"10000"},{"id":"71bc8c93.144294","type":"subflow","name":"Dial","info":"","category":"","in":[{"x":80,"y":140,"wires":[{"id":"e7c4da10.763418"}]}],"out":[{"x":1600,"y":140,"wires":[{"id":"66a57697.062ea8","port":0}]},{"x":1600,"y":200,"wires":[{"id":"6022d2ba.83418c","port":0}]},{"x":1600,"y":280,"wires":[{"id":"b77ad44c.c2c0d","port":0}]},{"x":1600,"y":360,"wires":[{"id":"674e4f99.0a778","port":0}]}],"outputLabels":["CONNECTED","ENDED","TIMEOUT","ERROR"]},{"id":"3e699fb2.881938","type":"function","z":"71bc8c93.144294","name":"ATD Call","func":"var num = msg.number;\nvar at_cmd = \"ATD\"+num+\"\\;\"; \n\nmsg.payload=at_cmd+\"\\r\\n\";\n//msg.payload.msg =msg.payload.message;\n\nreturn msg;","outputs":"1","noerr":0,"x":220,"y":200,"wires":[["d3a75c82.2f53f"]]},{"id":"db123915.c17c9","type":"switch","z":"71bc8c93.144294","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"0","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":200,"wires":[["9646d1a9.79bb98","2dbb462a.6c8d9a"],["674e4f99.0a778"]]},{"id":"d3a75c82.2f53f","type":"subflow:b0491a09.bf712","z":"71bc8c93.144294","name":"","x":390,"y":200,"wires":[["db123915.c17c9"]]},{"id":"732e9c21.c8beec","type":"subflow:4bfe1136.14a238","z":"71bc8c93.144294","name":"","x":390,"y":240,"wires":[["647332d1.87bb94"]]},{"id":"647332d1.87bb94","type":"switch","z":"71bc8c93.144294","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"CONN","vt":"str"},{"t":"cont","v":"CEND","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":240,"wires":[["abeb6474.f259b8"],["abeb6474.f259b8"]]},{"id":"e308fb3c.93ded8","type":"comment","z":"71bc8c93.144294","name":"Set timeout","info":"Set timeout for outgoing voice call.","x":730,"y":40,"wires":[]},{"id":"d951f290.fcc66","type":"switch","z":"71bc8c93.144294","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"CONN","vt":"str"},{"t":"cont","v":"CEND","vt":"str"},{"t":"cont","v":"TIMEOUT","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":1070,"y":200,"wires":[["66a57697.062ea8"],["6022d2ba.83418c"],["72d51b37.e6912c"]]},{"id":"9646d1a9.79bb98","type":"trigger","z":"71bc8c93.144294","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"60","extend":true,"units":"s","reset":"BLOCK","bytopic":"all","name":"","x":730,"y":80,"wires":[["993c16c0.a74d98"]]},{"id":"64babea9.a8bbb","type":"traffic","z":"71bc8c93.144294","name":"","property_allow":"payload","filter_allow":"ATD","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"BLOCK","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":910,"y":200,"wires":[["d951f290.fcc66","2114d454.1300d4"]]},{"id":"2114d454.1300d4","type":"change","z":"71bc8c93.144294","name":"BLOCK","rules":[{"t":"set","p":"payload","pt":"msg","to":"BLOCK","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":900,"y":120,"wires":[["64babea9.a8bbb","9646d1a9.79bb98"]]},{"id":"e7c4da10.763418","type":"function","z":"71bc8c93.144294","name":"AT+CHUP Hang-up","func":"var at_cmd = \"AT+CHUP\"; \n\nmsg.payload=at_cmd+\"\\r\\n\";\n\nreturn msg;","outputs":"1","noerr":0,"x":230,"y":140,"wires":[["4eba397a.82d2"]]},{"id":"4eba397a.82d2","type":"subflow:b0491a09.bf712","z":"71bc8c93.144294","name":"","x":410,"y":140,"wires":[["7e37ad0b.9f100c"]]},{"id":"7e37ad0b.9f100c","type":"switch","z":"71bc8c93.144294","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"0","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":140,"wires":[["3e699fb2.881938"],["674e4f99.0a778"]]},{"id":"72d51b37.e6912c","type":"function","z":"71bc8c93.144294","name":"AT+CHUP Hang-up","func":"var at_cmd = \"AT+CHUP\"; \n\nmsg.payload=at_cmd+\"\\r\\n\";\n\nreturn msg;","outputs":"1","noerr":0,"x":1150,"y":280,"wires":[["766abd9b.345eec"]]},{"id":"766abd9b.345eec","type":"subflow:b0491a09.bf712","z":"71bc8c93.144294","name":"","x":1330,"y":280,"wires":[["b77ad44c.c2c0d"]]},{"id":"993c16c0.a74d98","type":"change","z":"71bc8c93.144294","name":"TIMEOUT","rules":[{"t":"set","p":"payload","pt":"msg","to":"TIMEOUT","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":80,"wires":[["64babea9.a8bbb"]]},{"id":"674e4f99.0a778","type":"change","z":"71bc8c93.144294","name":"ERROR","rules":[{"t":"set","p":"payload","pt":"msg","to":"ERROR","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1280,"y":360,"wires":[[]]},{"id":"66a57697.062ea8","type":"change","z":"71bc8c93.144294","name":"CONNECTED","rules":[{"t":"set","p":"payload","pt":"msg","to":"CONNECTED","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1240,"y":160,"wires":[[]]},{"id":"6022d2ba.83418c","type":"change","z":"71bc8c93.144294","name":"ENDED","rules":[{"t":"set","p":"payload","pt":"msg","to":"ENDED","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1220,"y":200,"wires":[[]]},{"id":"b77ad44c.c2c0d","type":"change","z":"71bc8c93.144294","name":"TIMEOUT","rules":[{"t":"set","p":"payload","pt":"msg","to":"TIMEOUT","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1480,"y":280,"wires":[[]]},{"id":"abeb6474.f259b8","type":"change","z":"71bc8c93.144294","name":"","rules":[{"t":"set","p":"number","pt":"msg","to":"number","tot":"global"},{"t":"set","p":"message","pt":"msg","to":"message","tot":"global"},{"t":"set","p":"filename","pt":"msg","to":"filename","tot":"global"},{"t":"set","p":"cachefull","pt":"msg","to":"cachefull","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":240,"wires":[["64babea9.a8bbb"]]},{"id":"2dbb462a.6c8d9a","type":"change","z":"71bc8c93.144294","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"ATD","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":200,"wires":[["64babea9.a8bbb"]]},{"id":"824c0efa.febe88","type":"tab","label":"GSM","disabled":false,"info":""},{"id":"24dd16ad.6162e2","type":"function","z":"824c0efa.febe88","name":"AT+CMGS= Send 'To' Number","func":"var num = msg.number;\nvar at_cmd = \"AT+CMGS=\\\"\"+num+\"\\\"\"; \nmsg.message = msg.payload;\nmsg.payload = at_cmd+\"\\r\";\n\nreturn msg;","outputs":"1","noerr":0,"x":730,"y":1320,"wires":[["d25cb01.3629e5"]]},{"id":"dc690b21.cef218","type":"function","z":"824c0efa.febe88","name":"Send Message","func":"var sms_msg = msg.message;\n\nmsg.payload=sms_msg+\"\\x1A\";\n\nreturn msg;","outputs":1,"noerr":0,"x":1260,"y":1320,"wires":[["d725d3a4.818d08"]]},{"id":"d9ab3334.716ae8","type":"debug","z":"824c0efa.febe88","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":570,"y":1780,"wires":[]},{"id":"4915182e.2a126","type":"switch","z":"824c0efa.febe88","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"+CMTI:","vt":"str"},{"t":"cont","v":"+CMGR","vt":"str"},{"t":"cont","v":"+CUSD:","vt":"str"},{"t":"cont","v":"+CLIP:","vt":"str"},{"t":"cont","v":"+CSQ:","vt":"str"},{"t":"cont","v":"^RSSI:","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":7,"x":370,"y":1620,"wires":[["f9ba8001.448898"],["ddc88293.0f8f1"],["3649d387.302404"],["95452788.7329f"],["85bb3839.2ab35"],["c66b5319.7d04c8"],["d9ab3334.716ae8"]]},{"id":"3e4786aa.427c62","type":"udp in","z":"824c0efa.febe88","name":"","iface":"","port":"10007","ipv":"udp4","multicast":"false","group":"","datatype":"utf8","x":200,"y":420,"wires":[["8f7f53c2.158d4","30cc3e8.6376bc2"]]},{"id":"d69c3271.e96e9","type":"switch","z":"824c0efa.febe88","name":"check identifier","property":"identifier","propertyType":"msg","rules":[{"t":"eq","v":"gsm","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":340,"y":1240,"wires":[["a3651d4a.f019c"]]},{"id":"7d95427f.3d4204","type":"switch","z":"824c0efa.febe88","name":"command","property":"command","propertyType":"msg","rules":[{"t":"eq","v":"sms","vt":"str"},{"t":"eq","v":"hangup","vt":"str"},{"t":"eq","v":"callout","vt":"str"},{"t":"eq","v":"ussdout","vt":"str"},{"t":"eq","v":"voice","vt":"str"}],"checkall":"true","repair":false,"outputs":5,"x":140,"y":1340,"wires":[["4dd7532f.8d221c"],["b37db75b.ce506"],["91fb032a.6eb018"],["c870ecb1.472a9"],["c0d5c8b7.f1722"]]},{"id":"b37db75b.ce506","type":"function","z":"824c0efa.febe88","name":"AT+CHUP Hang-up","func":"var at_cmd = \"AT+CHUP\"; \n\nmsg.payload=at_cmd+\"\\r\\n\";\n\nreturn msg;","outputs":"1","noerr":0,"x":430,"y":1360,"wires":[["d725d3a4.818d08"]]},{"id":"3649d387.302404","type":"string","z":"824c0efa.febe88","name":"+CUSD USSD","methods":[{"name":"between","params":[{"type":"str","value":"+CUSD: 2,\""},{"type":"str","value":"\","}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":580,"y":1620,"wires":[["a5bc5961.eba5d"]]},{"id":"f1664278.0b0278","type":"string","z":"824c0efa.febe88","name":"rem timestamp","methods":[{"name":"delLeftMost","params":[{"type":"str","value":";"}]},{"name":"delLeftMost","params":[{"type":"str","value":";"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":220,"y":1160,"wires":[["279fab20.7b4fcc"]]},{"id":"279fab20.7b4fcc","type":"string","z":"824c0efa.febe88","name":"parse identifier","methods":[{"name":"getLeftMost","params":[{"type":"str","value":" "}]}],"prop":"payload","propout":"identifier","object":"msg","objectout":"msg","x":400,"y":1160,"wires":[["6cf08c5b.0bffbc"]]},{"id":"6cf08c5b.0bffbc","type":"string","z":"824c0efa.febe88","name":"parse command","methods":[{"name":"delLeftMost","params":[{"type":"str","value":" "}]},{"name":"getLeftMost","params":[{"type":"str","value":" "}]}],"prop":"payload","propout":"command","object":"msg","objectout":"msg","x":580,"y":1160,"wires":[["d6055438.98b948"]]},{"id":"d6055438.98b948","type":"string","z":"824c0efa.febe88","name":"parse number","methods":[{"name":"delLeftMost","params":[{"type":"str","value":" "}]},{"name":"delLeftMost","params":[{"type":"str","value":" "}]},{"name":"getLeftMost","params":[{"type":"str","value":" "}]}],"prop":"payload","propout":"number","object":"msg","objectout":"msg","x":760,"y":1160,"wires":[["576530c4.03073"]]},{"id":"576530c4.03073","type":"string","z":"824c0efa.febe88","name":"parse message","methods":[{"name":"delLeftMost","params":[{"type":"str","value":" "}]},{"name":"delLeftMost","params":[{"type":"str","value":" "}]},{"name":"delLeftMost","params":[{"type":"str","value":" "}]}],"prop":"payload","propout":"message","object":"msg","objectout":"msg","x":940,"y":1160,"wires":[["573ef3aa.abc7e4"]]},{"id":"95452788.7329f","type":"string","z":"824c0efa.febe88","name":"+CLIP","methods":[{"name":"between","params":[{"type":"str","value":"+CLIP: \""},{"type":"str","value":"\",145,\"\",,\"\",0"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":550,"y":1660,"wires":[["aa762e4.9bf9ad"]]},{"id":"dfb5d7ce.6e4b88","type":"function","z":"824c0efa.febe88","name":"gsm callin","func":"msg.payload=\"gsm callin \"+msg.payload;\n\nreturn msg;","outputs":"1","noerr":0,"x":940,"y":1660,"wires":[["c83ab0fb.791018"]]},{"id":"c870ecb1.472a9","type":"function","z":"824c0efa.febe88","name":"AT+CUSD Send USSD","func":"var num = msg.number;\nvar at_cmd = \"AT+CUSD=1,\\\"\"+num+\"\\\",15\"; \n\nmsg.payload=at_cmd+\"\\r\\n\";\n\nreturn msg;","outputs":"1","noerr":0,"x":410,"y":1480,"wires":[["d725d3a4.818d08"]]},{"id":"a5bc5961.eba5d","type":"function","z":"824c0efa.febe88","name":"gsm ussdin","func":"msg.payload=\"gsm ussdin \"+msg.payload;\nreturn msg;","outputs":1,"noerr":0,"x":970,"y":1620,"wires":[["c83ab0fb.791018"]]},{"id":"5fe323bf.de6ac4","type":"comment","z":"824c0efa.febe88","name":"Settings: UDP IP and ports","info":"","x":190,"y":360,"wires":[]},{"id":"aa762e4.9bf9ad","type":"string","z":"824c0efa.febe88","name":"rem +countrycode","methods":[{"name":"chompLeft","params":[{"type":"global","value":"pluscountrycode"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":730,"y":1660,"wires":[["dfb5d7ce.6e4b88"]]},{"id":"1559b72e.806601","type":"function","z":"824c0efa.febe88","name":"gsm signal","func":"msg.payload=\"gsm signal \"+msg.payload;\n\nreturn msg;","outputs":"1","noerr":0,"x":730,"y":1700,"wires":[["c83ab0fb.791018"]]},{"id":"85bb3839.2ab35","type":"string","z":"824c0efa.febe88","name":"+CSQ","methods":[{"name":"getRightMost","params":[{"type":"str","value":"+CSQ: "}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":550,"y":1700,"wires":[["1559b72e.806601"]]},{"id":"c66b5319.7d04c8","type":"string","z":"824c0efa.febe88","name":"^RSSI","methods":[{"name":"getRightMost","params":[{"type":"str","value":"^RSSI: "}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":550,"y":1740,"wires":[["1559b72e.806601"]]},{"id":"f9ba8001.448898","type":"string","z":"824c0efa.febe88","name":"+CMTI","methods":[{"name":"getRightMost","params":[{"type":"str","value":"\","}]}],"prop":"payload","propout":"msgindex","object":"msg","objectout":"flow","x":570,"y":1540,"wires":[["9682ab88.8f09"]]},{"id":"9682ab88.8f09","type":"function","z":"824c0efa.febe88","name":"AT+CMGR Read message","func":"var at_cmd = \"AT+CMGR=\"; \n\nmsg.payload=at_cmd+flow.get('msgindex')+\"\\r\\n\";\n\nreturn msg;","outputs":"1","noerr":0,"x":780,"y":1540,"wires":[["d725d3a4.818d08"]]},{"id":"575e1145.d8c04","type":"comment","z":"824c0efa.febe88","name":"Comment on AT+CNMI","info":"AT+CNMI=<mode>,<mt>,<bm>,<ds>,<bfr>\n\n<mode>=2 Buffer unsolicited result codes in case the serial link is busy and flush them to the serial after reservation. Otherwise forward them directly to the serial.\n\n<mt>=1 If SMS-DELIVER is stored, indication of the memory location is routed to the serial using the following unsolicited result code \n+CMTI: <memr>,<index>\n\n<bm>=0 Cell Broadcast Messages are not sent to the serial.\n\n<ds>=2 If SMS-STATUS-REPORT is stored, then the following unsolicited result code is sent to serial:\n+CDSI: <memr>,<index>\n\n<bfr>=0 Buffer of unsolicited result codes defined within this command is flushed to the serial.\n","x":860,"y":1080,"wires":[]},{"id":"fbce1dff.050fb8","type":"inject","z":"824c0efa.febe88","name":"Initial setup","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":150,"y":780,"wires":[["492a4fce.e7aa5","9771e036.e0e2a","8dd7ff72.2c0bc","fc07a7be.931878","7d3fae8a.b12dc8"]]},{"id":"7b9bbf8.ae5144","type":"change","z":"824c0efa.febe88","name":"AT+CLIP=1 (Enable Calling Line Identification Presentation)","rules":[{"t":"set","p":"payload","pt":"msg","to":"AT+CLIP=1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":840,"wires":[["f21c6d2c.3bc378"]]},{"id":"d53a257.c3c1e58","type":"change","z":"824c0efa.febe88","name":"AT+CMGF=1 (Enable SMS Text Mode)","rules":[{"t":"set","p":"payload","pt":"msg","to":"AT+CMGF=1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":880,"wires":[["f21c6d2c.3bc378"]]},{"id":"392cc8f.dd1bcb8","type":"change","z":"824c0efa.febe88","name":"AT+CSCS=\"GSM\" (Set character set to GSM)","rules":[{"t":"set","p":"payload","pt":"msg","to":"AT+CSCS=\"GSM\"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":720,"y":920,"wires":[["f21c6d2c.3bc378"]]},{"id":"c8b642e9.b27388","type":"change","z":"824c0efa.febe88","name":"AT+CPMS=\"SM\",\"SM\",\"SM\" (Select Message Storage SIM)","rules":[{"t":"set","p":"payload","pt":"msg","to":"AT+CPMS=\"SM\",\"SM\",\"SM\"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":960,"wires":[["f21c6d2c.3bc378"]]},{"id":"e51a384.fbb8548","type":"change","z":"824c0efa.febe88","name":"AT+CNMI=2,1,0,2,0 (New Message Indications to serial)","rules":[{"t":"set","p":"payload","pt":"msg","to":"AT+CNMI=2,1,0,2,0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":1040,"wires":[["f21c6d2c.3bc378"]]},{"id":"f21c6d2c.3bc378","type":"function","z":"824c0efa.febe88","name":"Add Newline","func":"msg.payload = msg.payload + \"\\r\\n\";\nreturn msg;","outputs":1,"noerr":0,"x":1230,"y":860,"wires":[["4e5f56b2.fe7948"]]},{"id":"e4ddbe42.8ed0d","type":"change","z":"824c0efa.febe88","name":"AT^USSDMODE=0 (Only for Huawei modems: enable encode/decode USSD)","rules":[{"t":"set","p":"payload","pt":"msg","to":"AT^USSDMODE=0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":810,"y":800,"wires":[["f21c6d2c.3bc378"]]},{"id":"4e808758.6bcbe8","type":"traffic","z":"824c0efa.febe88","name":"+CMGR:","property_allow":"payload","filter_allow":"CMGR:","ignore_case_allow":false,"negate_allow":false,"send_allow":true,"property_stop":"payload","filter_stop":"^.*\\n0\\r","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":false,"differ":false,"x":320,"y":1860,"wires":[["5fd3ae4b.3e4468"]]},{"id":"4c478826.a5b1f8","type":"join","z":"824c0efa.febe88","name":"","mode":"custom","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"","joinerType":"str","accumulate":false,"timeout":"1","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1250,"y":1840,"wires":[["5e004dc9.7ac8c4"]]},{"id":"690fdfcf.c6c568","type":"switch","z":"824c0efa.febe88","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"+CMGR: ","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":630,"y":1860,"wires":[["36150823.7d4c3"],["cfcc2b3e.1257b"]]},{"id":"36150823.7d4c3","type":"string","z":"824c0efa.febe88","name":"parse num","methods":[{"name":"between","params":[{"type":"str","value":"READ\",\""},{"type":"str","value":"\""}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":790,"y":1840,"wires":[["acca8ac0.82d12"]]},{"id":"d732975a.2eeab8","type":"lower-case","z":"824c0efa.febe88","name":"","x":1030,"y":1900,"wires":[["4c478826.a5b1f8"]]},{"id":"cfcc2b3e.1257b","type":"function-npm","z":"824c0efa.febe88","name":"remove-accents-diacritics","func":"const removeAccents = require('remove-accents-diacritics');\n// import removeAccents from 'remove-accents-diacritics';\n \nmsg.payload = removeAccents.remove(msg.payload);\n\nreturn msg;","outputs":1,"noerr":0,"x":830,"y":1900,"wires":[["d732975a.2eeab8"]]},{"id":"acca8ac0.82d12","type":"string","z":"824c0efa.febe88","name":"rem +countrycode","methods":[{"name":"chompLeft","params":[{"type":"global","value":"pluscountrycode"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":970,"y":1840,"wires":[["6f0577a7.47f8f8"]]},{"id":"6f0577a7.47f8f8","type":"change","z":"824c0efa.febe88","name":"move","rules":[{"t":"move","p":"payload","pt":"msg","to":"topic","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1130,"y":1840,"wires":[["4c478826.a5b1f8"]]},{"id":"5fd3ae4b.3e4468","type":"string","z":"824c0efa.febe88","name":"trim whitespace","methods":[{"name":"trim","params":[]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":480,"y":1860,"wires":[["690fdfcf.c6c568"]]},{"id":"5e004dc9.7ac8c4","type":"function","z":"824c0efa.febe88","name":"gsm <command>","func":"var outputMsgs = [];\nvar words = msg.payload.split(\" \");\nfor (var w in words) {\n outputMsgs.push({payload:\"gsm \"+words[w]+\" \"+msg.topic});\n}\nreturn [ outputMsgs ];","outputs":1,"noerr":0,"x":1050,"y":1780,"wires":[["dfa38d25.8e3c88"]]},{"id":"dfa38d25.8e3c88","type":"delay","z":"824c0efa.febe88","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1230,"y":1780,"wires":[["c83ab0fb.791018"]]},{"id":"a3651d4a.f019c","type":"string","z":"824c0efa.febe88","name":"trim whitespace","methods":[{"name":"trim","params":[]}],"prop":"message","propout":"message","object":"msg","objectout":"msg","x":520,"y":1240,"wires":[["bbaa0320.24bc68"]]},{"id":"ddc88293.0f8f1","type":"function","z":"824c0efa.febe88","name":"AT+CMGD Delete message","func":"var at_cmd = \"AT+CMGD=\"; \n\nmsg.payload=at_cmd+flow.get('msgindex')+\"\\r\\n\";\n\nreturn msg;","outputs":"1","noerr":0,"x":780,"y":1580,"wires":[["b32d96a8.ee73a8"]]},{"id":"b32d96a8.ee73a8","type":"delay","z":"824c0efa.febe88","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":980,"y":1580,"wires":[["d725d3a4.818d08"]]},{"id":"573ef3aa.abc7e4","type":"switch","z":"824c0efa.febe88","name":"check number","property":"number","propertyType":"msg","rules":[{"t":"neq","v":"0","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":160,"y":1240,"wires":[["d69c3271.e96e9"]]},{"id":"21823ac5.8a6b9e","type":"change","z":"824c0efa.febe88","name":"AT^CVOICE=0 (Enable Voice)","rules":[{"t":"set","p":"payload","pt":"msg","to":"AT^CVOICE=0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":1000,"wires":[["f21c6d2c.3bc378"]]},{"id":"c0d5c8b7.f1722","type":"link out","z":"824c0efa.febe88","name":"voice out","links":["202ce488.41afac"],"x":215,"y":1440,"wires":[]},{"id":"a7dc0b77.96d208","type":"inject","z":"824c0efa.febe88","name":"AT (Check Serial Port)","topic":"","payload":"AT","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":440,"y":2580,"wires":[["1490260b.143aba"]]},{"id":"3ba2751f.412612","type":"inject","z":"824c0efa.febe88","name":"AT+CGMI (Manufacturer Info)","topic":"","payload":"AT+CGMI","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":460,"y":2620,"wires":[["1490260b.143aba"]]},{"id":"627536b1.3fcb78","type":"inject","z":"824c0efa.febe88","name":"AT+CGMM (Model Number)","topic":"","payload":"AT+CGMM","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":460,"y":2660,"wires":[["1490260b.143aba"]]},{"id":"d503df61.563938","type":"inject","z":"824c0efa.febe88","name":"AT+CGMR (Software Version)","topic":"","payload":"AT+CGMR","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":460,"y":2700,"wires":[["1490260b.143aba"]]},{"id":"7c9485d6.e2155c","type":"inject","z":"824c0efa.febe88","name":"AT+CSQ (Signal Strength)","topic":"","payload":"AT+CSQ","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":450,"y":2740,"wires":[["1490260b.143aba"]]},{"id":"f78e064d.df95e","type":"inject","z":"824c0efa.febe88","name":"AT+CREG? (Registration Status)","topic":"","payload":"AT+CREG?","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":470,"y":2780,"wires":[["1490260b.143aba"]]},{"id":"9071075f.b6a4b","type":"inject","z":"824c0efa.febe88","name":"AT+CGACT? (Connection Status)","topic":"","payload":"AT+CGACT?","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":470,"y":2820,"wires":[["1490260b.143aba"]]},{"id":"733bc254.cc1214","type":"inject","z":"824c0efa.febe88","name":"AT+COPS? (Operator Info)","topic":"","payload":"AT+COPS?","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":450,"y":2860,"wires":[["1490260b.143aba"]]},{"id":"9232c2d4.5537a","type":"inject","z":"824c0efa.febe88","name":"AT+CGDCONT? (Connection Profiles)","topic":"","payload":"AT+CGDCONT?","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":490,"y":2900,"wires":[["1490260b.143aba"]]},{"id":"1490260b.143aba","type":"function","z":"824c0efa.febe88","name":"Add Newline","func":"msg.payload = msg.payload + \"\\r\\n\";\nreturn msg;","outputs":1,"noerr":0,"x":950,"y":2720,"wires":[["a4879e70.37ffb8"]]},{"id":"38da53f3.6b4c54","type":"inject","z":"824c0efa.febe88","name":"AT+CMGL=\"ALL\" (List all messages)","topic":"","payload":"AT+CMGL=\"ALL\"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":480,"y":3000,"wires":[["1490260b.143aba"]]},{"id":"800a16f8.3de9d","type":"inject","z":"824c0efa.febe88","name":"AT+CMGD=1,4 (Delete all messages)","topic":"","payload":"AT+CMGD=1,4","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":490,"y":3040,"wires":[["1490260b.143aba"]]},{"id":"536b9465.84bc1c","type":"comment","z":"824c0efa.febe88","name":"Useful commands","info":"Other useful commands not implemented in the main flow.","x":190,"y":2580,"wires":[]},{"id":"6773314.398d65","type":"inject","z":"824c0efa.febe88","name":"AT^CVOICE? (Audio coding)","topic":"","payload":"AT^CVOICE?","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":460,"y":3080,"wires":[["1490260b.143aba"]]},{"id":"202ce488.41afac","type":"link in","z":"824c0efa.febe88","name":"voice in","links":["c0d5c8b7.f1722"],"x":115,"y":2020,"wires":[["ed669c66.1fdf68"]]},{"id":"e52aa524.b7cc8","type":"link in","z":"824c0efa.febe88","name":"UDP (in)","links":["30cc3e8.6376bc2","47a3a759.2e6ad","f777bb22.3ceeb","2cda8177.042ece"],"x":95,"y":1160,"wires":[["f1664278.0b0278"]]},{"id":"5968071f.7ef108","type":"exec","z":"824c0efa.febe88","command":"killall ffmpeg","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":550,"y":2480,"wires":[[],[],[]]},{"id":"4830a54e.1e784c","type":"inject","z":"824c0efa.febe88","name":"start","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":390,"y":2480,"wires":[["5968071f.7ef108"]]},{"id":"492a4fce.e7aa5","type":"change","z":"824c0efa.febe88","name":"ATE0 (Disable Command Echo)","rules":[{"t":"set","p":"payload","pt":"msg","to":"ATE0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":670,"y":760,"wires":[["f21c6d2c.3bc378"]]},{"id":"df424b8c.25669","type":"function","z":"824c0efa.febe88","name":"ATA (Pick up call)","func":"var at_cmd = \"ATA\"; \n\nmsg.payload=at_cmd+\"\\r\\n\";\n\nreturn msg;","outputs":1,"noerr":0,"x":330,"y":2220,"wires":[["e2c0e664.541f3"]]},{"id":"5fb5737e.641d2c","type":"function","z":"824c0efa.febe88","name":"AT^DDSETEX=2","func":"var at_cmd = \"AT^DDSETEX=2\"; \n\nmsg.payload=at_cmd+\"\\r\\n\";\n\nreturn msg;","outputs":1,"noerr":0,"x":870,"y":2220,"wires":[["c704952c.4eb54"]]},{"id":"aff017e.0d8c0e8","type":"subflow:71bc8c93.144294","z":"824c0efa.febe88","name":"","x":290,"y":2280,"wires":[["51924960.40ede8"],["b2349a57.c06c18"],["b2349a57.c06c18"],["b2349a57.c06c18"]]},{"id":"91fb032a.6eb018","type":"subflow:71bc8c93.144294","z":"824c0efa.febe88","name":"","x":350,"y":1420,"wires":[["b37db75b.ce506"],[],[],[]]},{"id":"51cbff3.20c0e8","type":"function","z":"824c0efa.febe88","name":"AT+CLCC (Check incomming calls)","func":"var at_cmd = \"AT+CLCC\"; \n\nmsg.payload=at_cmd+\"\\r\\n\";\n\nreturn msg;","outputs":1,"noerr":0,"x":440,"y":2160,"wires":[["797e27be.e8fb3"]]},{"id":"9545a969.fa92a","type":"string","z":"824c0efa.febe88","name":"parse num","methods":[{"name":"between","params":[{"type":"str","value":"1,1,4,0,0,\""},{"type":"str","value":"\""}]}],"prop":"payload","propout":"incoming","object":"msg","objectout":"msg","x":830,"y":2160,"wires":[["9aafbebe.b4b48"]]},{"id":"9aafbebe.b4b48","type":"string","z":"824c0efa.febe88","name":"rem countrycode","methods":[{"name":"chompLeft","params":[{"type":"global","value":"countrycode"}]}],"prop":"incoming","propout":"incoming","object":"msg","objectout":"msg","x":1010,"y":2160,"wires":[["4e9a7417.8c6854"]]},{"id":"4e9a7417.8c6854","type":"switch","z":"824c0efa.febe88","name":"","property":"number","propertyType":"msg","rules":[{"t":"eq","v":"incoming","vt":"msg"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":150,"y":2220,"wires":[["df424b8c.25669"],["aff017e.0d8c0e8"]]},{"id":"4c1ce00e.dbdbf8","type":"switch","z":"824c0efa.febe88","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"^CEND","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":390,"y":2440,"wires":[["5968071f.7ef108"]]},{"id":"9771e036.e0e2a","type":"change","z":"824c0efa.febe88","name":"Change audio cache directory (inside HOME) and its limit (in kB)","rules":[{"t":"set","p":"cachelimit","pt":"global","to":"10240","tot":"num"},{"t":"set","p":"directory","pt":"global","to":"audiocache","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":620,"wires":[[]]},{"id":"8dd7ff72.2c0bc","type":"change","z":"824c0efa.febe88","name":"Change TTS language and country code (with and without +)","rules":[{"t":"set","p":"language","pt":"global","to":"cs-CZ","tot":"str"},{"t":"set","p":"countrycode","pt":"global","to":"420","tot":"str"},{"t":"set","p":"pluscountrycode","pt":"global","to":"+420","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":660,"wires":[[]]},{"id":"ed669c66.1fdf68","type":"subflow:886ce1dc.59db3","z":"824c0efa.febe88","name":"","x":350,"y":2020,"wires":[["63caf751.4192b","5c2d28b0.92212"],["da7c760.7ca0b08","cd5aa741.f242f8","e7ec47bf.365df8","5c2d28b0.92212"]]},{"id":"da7c760.7ca0b08","type":"change","z":"824c0efa.febe88","name":"gsm voice error","rules":[{"t":"set","p":"payload","pt":"msg","to":"gsm voice error","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":920,"y":1980,"wires":[["c83ab0fb.791018"]]},{"id":"5867e387.4e1ffc","type":"change","z":"824c0efa.febe88","name":"gsm voice cachefull","rules":[{"t":"set","p":"payload","pt":"msg","to":"gsm voice cachefull","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":930,"y":2020,"wires":[["c83ab0fb.791018"]]},{"id":"e7ec47bf.365df8","type":"function","z":"824c0efa.febe88","name":"gsm sms","func":"msg.payload=\"gsm sms \"+msg.number+\" \"+msg.message;\n\nreturn msg;","outputs":"1","noerr":0,"x":920,"y":2100,"wires":[["47a3a759.2e6ad"]]},{"id":"9d53728d.404bc8","type":"function","z":"824c0efa.febe88","name":"gsm callout","func":"msg.payload=\"gsm callout \"+msg.number;\n\nreturn msg;","outputs":"1","noerr":0,"x":930,"y":2060,"wires":[["47a3a759.2e6ad"]]},{"id":"cd5aa741.f242f8","type":"delay","z":"824c0efa.febe88","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":780,"y":2060,"wires":[["9d53728d.404bc8"]]},{"id":"47a3a759.2e6ad","type":"link out","z":"824c0efa.febe88","name":"Flow beginning","links":["e52aa524.b7cc8"],"x":1135,"y":2080,"wires":[]},{"id":"d41001a1.877208","type":"exec","z":"824c0efa.febe88","command":"","addpay":true,"append":"","useSpawn":"true","timer":"","oldrc":false,"name":"ffmpeg","x":630,"y":2380,"wires":[["c946946d.28e458"],[],["ba03adce.3a50c8","d0bded62.379ca8","6779d865.3684c"]]},{"id":"ba03adce.3a50c8","type":"switch","z":"824c0efa.febe88","name":"","property":"payload.code","propertyType":"msg","rules":[{"t":"eq","v":"255","vt":"num"},{"t":"eq","v":"0","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":3,"x":790,"y":2400,"wires":[[],[],["e64c4ba5.bc0be8","48357e80.52348","ff6788b7.5fff88"]]},{"id":"e64c4ba5.bc0be8","type":"function","z":"824c0efa.febe88","name":"AT+CHUP Hang-up","func":"var at_cmd = \"AT+CHUP\"; \n\nmsg.payload=at_cmd+\"\\r\\n\";\n\nreturn msg;","outputs":"1","noerr":0,"x":970,"y":2460,"wires":[["2d1108ed.1dc718"]]},{"id":"bbaa0320.24bc68","type":"change","z":"824c0efa.febe88","name":"","rules":[{"t":"set","p":"number","pt":"global","to":"number","tot":"msg"},{"t":"set","p":"message","pt":"global","to":"message","tot":"msg"},{"t":"set","p":"command","pt":"global","to":"command","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":1240,"wires":[["7d95427f.3d4204"]]},{"id":"63caf751.4192b","type":"change","z":"824c0efa.febe88","name":"","rules":[{"t":"set","p":"filename","pt":"global","to":"filename","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":190,"y":2160,"wires":[["51cbff3.20c0e8"]]},{"id":"5c2d28b0.92212","type":"switch","z":"824c0efa.febe88","name":"","property":"cachefull","propertyType":"msg","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":770,"y":2020,"wires":[["5867e387.4e1ffc"]]},{"id":"d0bded62.379ca8","type":"switch","z":"824c0efa.febe88","name":"","property":"cachefull","propertyType":"msg","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":810,"y":2300,"wires":[["307e2441.9d8844"]]},{"id":"307e2441.9d8844","type":"fs-ops-delete","z":"824c0efa.febe88","name":"","path":"","pathType":"str","filename":"filename","filenameType":"msg","x":970,"y":2300,"wires":[[]]},{"id":"d725d3a4.818d08","type":"subflow:b0491a09.bf712","z":"824c0efa.febe88","name":"","x":1350,"y":1480,"wires":[[]]},{"id":"7cebcd29.4c418c","type":"delay","z":"824c0efa.febe88","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":300,"y":2380,"wires":[["bc82b195.9cc01"]]},{"id":"b2349a57.c06c18","type":"change","z":"824c0efa.febe88","name":"","rules":[],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":2280,"wires":[["d0bded62.379ca8","e7ec47bf.365df8"]]},{"id":"bc82b195.9cc01","type":"template","z":"824c0efa.febe88","name":"ffmpeg command","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"ffmpeg -re -stream_loop -1 -i {{{filename}}} -f s16le -acodec pcm_s16le -ac 1 -ar 8000 -","x":470,"y":2380,"wires":[["d41001a1.877208","ef8e4a68.107108"]]},{"id":"d4bc1a8e.04af08","type":"serial in","z":"824c0efa.febe88","name":"/dev/ttyUSB1","serial":"b64dd80.eff27a8","x":230,"y":220,"wires":[["92008d02.c0c89"]]},{"id":"fd57ebb8.063668","type":"serial out","z":"824c0efa.febe88","name":"/dev/ttyUSB1","serial":"b64dd80.eff27a8","x":230,"y":160,"wires":[]},{"id":"1e46fb80.0fe955","type":"link in","z":"824c0efa.febe88","name":"/dev/ttyUSB1 (out)","links":["c946946d.28e458"],"x":95,"y":160,"wires":[["fd57ebb8.063668","92008d02.c0c89"]]},{"id":"c946946d.28e458","type":"link out","z":"824c0efa.febe88","name":"/dev/ttyUSB1","links":["1e46fb80.0fe955"],"x":775,"y":2340,"wires":[]},{"id":"a44b6a4f.9ece9","type":"comment","z":"824c0efa.febe88","name":"Settings: Serial ports","info":"","x":170,"y":80,"wires":[]},{"id":"7b1238b6.0537d","type":"debug","z":"824c0efa.febe88","name":"/dev/ttyUSB2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":570,"y":280,"wires":[]},{"id":"596a306a.a17638","type":"subflow:b0491a09.bf712","z":"824c0efa.febe88","name":"","x":1090,"y":1320,"wires":[["dc690b21.cef218"]]},{"id":"797e27be.e8fb3","type":"subflow:b0491a09.bf712","z":"824c0efa.febe88","name":"","x":670,"y":2160,"wires":[["9545a969.fa92a"]]},{"id":"e2c0e664.541f3","type":"subflow:b0491a09.bf712","z":"824c0efa.febe88","name":"","x":510,"y":2220,"wires":[["51924960.40ede8"]]},{"id":"c704952c.4eb54","type":"subflow:b0491a09.bf712","z":"824c0efa.febe88","name":"","x":1050,"y":2220,"wires":[["7cebcd29.4c418c"]]},{"id":"2d1108ed.1dc718","type":"subflow:b0491a09.bf712","z":"824c0efa.febe88","name":"","x":1150,"y":2460,"wires":[[]]},{"id":"8d35941c.c9336","type":"subflow:b0491a09.bf712","z":"824c0efa.febe88","name":"","x":1550,"y":860,"wires":[[]]},{"id":"c83ab0fb.791018","type":"link out","z":"824c0efa.febe88","name":"UDP (out)","links":["e03bae3b.7d3168"],"x":1495,"y":1780,"wires":[]},{"id":"770dea12.523d94","type":"udp out","z":"824c0efa.febe88","name":"","addr":"192.168.1.77","iface":"","port":"10007","ipv":"udp4","outport":"10002","base64":false,"multicast":"false","x":610,"y":420,"wires":[]},{"id":"e03bae3b.7d3168","type":"link in","z":"824c0efa.febe88","name":"UDP (out)","links":["c83ab0fb.791018","87c4f897.571158"],"x":435,"y":420,"wires":[["770dea12.523d94","8f7f53c2.158d4"]]},{"id":"7a8b776c.658818","type":"inject","z":"824c0efa.febe88","name":"gsm sms 123456789 This is short message.","topic":"","payload":"gsm sms 123456789 This is short message.","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":310,"y":480,"wires":[["30cc3e8.6376bc2"]]},{"id":"4dd7532f.8d221c","type":"function-npm","z":"824c0efa.febe88","name":"removeAccents","func":"const removeAccents = require('remove-accents-diacritics');\n// import removeAccents from 'remove-accents-diacritics';\n \nmsg.payload = removeAccents.remove(msg.message);\n\nreturn msg;","outputs":1,"noerr":0,"x":380,"y":1320,"wires":[["4d7f3f5a.1f092"]]},{"id":"4d7f3f5a.1f092","type":"split","z":"824c0efa.febe88","name":"","splt":"160","spltType":"len","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":530,"y":1320,"wires":[["24dd16ad.6162e2"]]},{"id":"d25cb01.3629e5","type":"delay","z":"824c0efa.febe88","name":"1 msg/s","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":940,"y":1320,"wires":[["596a306a.a17638"]]},{"id":"8f7f53c2.158d4","type":"debug","z":"824c0efa.febe88","name":"UDP","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":650,"y":480,"wires":[]},{"id":"92008d02.c0c89","type":"debug","z":"824c0efa.febe88","name":"/dev/ttyUSB1","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":290,"y":280,"wires":[]},{"id":"30cc3e8.6376bc2","type":"link out","z":"824c0efa.febe88","name":"UDP (in)","links":["e52aa524.b7cc8"],"x":335,"y":420,"wires":[]},{"id":"4511c4ae.cf160c","type":"comment","z":"824c0efa.febe88","name":"Settings: Global variables","info":"","x":190,"y":560,"wires":[]},{"id":"48357e80.52348","type":"change","z":"824c0efa.febe88","name":"gsm voice error","rules":[{"t":"set","p":"payload","pt":"msg","to":"gsm voice error","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":960,"y":2380,"wires":[["87c4f897.571158"]]},{"id":"87c4f897.571158","type":"link out","z":"824c0efa.febe88","name":"UDP (out)","links":["e03bae3b.7d3168"],"x":1095,"y":2380,"wires":[]},{"id":"ff6788b7.5fff88","type":"function","z":"824c0efa.febe88","name":"gsm sms","func":"msg.payload=\"gsm sms \"+msg.number+\" \"+msg.message;\n\nreturn msg;","outputs":"1","noerr":0,"x":940,"y":2420,"wires":[["2cda8177.042ece"]]},{"id":"2cda8177.042ece","type":"link out","z":"824c0efa.febe88","name":"Flow beginning","links":["e52aa524.b7cc8"],"x":1095,"y":2420,"wires":[]},{"id":"ef8e4a68.107108","type":"trigger","z":"824c0efa.febe88","op1":"","op2":"1","op1type":"nul","op2type":"str","duration":"10","extend":true,"units":"min","reset":"reset","bytopic":"all","name":"","x":770,"y":2500,"wires":[["e64c4ba5.bc0be8"]]},{"id":"6779d865.3684c","type":"change","z":"824c0efa.febe88","name":"reset","rules":[{"t":"set","p":"payload","pt":"msg","to":"reset","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":2440,"wires":[["ef8e4a68.107108"]]},{"id":"2f9ff422.7b518c","type":"subflow:b0491a09.bf712","z":"824c0efa.febe88","name":"","x":510,"y":160,"wires":[[]]},{"id":"7d3fae8a.b12dc8","type":"delay","z":"824c0efa.febe88","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":360,"y":840,"wires":[["7b9bbf8.ae5144","e4ddbe42.8ed0d","d53a257.c3c1e58","392cc8f.dd1bcb8","c8b642e9.b27388","21823ac5.8a6b9e","e51a384.fbb8548"]]},{"id":"fc07a7be.931878","type":"change","z":"824c0efa.febe88","name":"ATV0 (Set Limited Response Format)","rules":[{"t":"set","p":"payload","pt":"msg","to":"ATV0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":690,"y":720,"wires":[["f21c6d2c.3bc378"]]},{"id":"a4879e70.37ffb8","type":"subflow:b0491a09.bf712","z":"824c0efa.febe88","name":"","x":1110,"y":2720,"wires":[[]]},{"id":"c658e45b.aa4e78","type":"inject","z":"824c0efa.febe88","name":"AT (Test serial)","topic":"","payload":"\"AT\\r\\n\"","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":440,"y":100,"wires":[["2f9ff422.7b518c"]]},{"id":"51924960.40ede8","type":"delay","z":"824c0efa.febe88","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":700,"y":2220,"wires":[["5fb5737e.641d2c"]]},{"id":"e9b6999b.c9f1a8","type":"subflow:4bfe1136.14a238","z":"824c0efa.febe88","name":"","x":230,"y":2440,"wires":[["4c1ce00e.dbdbf8"]]},{"id":"b828d445.f74b1","type":"subflow:4bfe1136.14a238","z":"824c0efa.febe88","name":"","x":150,"y":1680,"wires":[["4e808758.6bcbe8","7760dd5f.fe8f64"]]},{"id":"92464499.11fc28","type":"subflow:4bfe1136.14a238","z":"824c0efa.febe88","name":"","x":510,"y":220,"wires":[["7b1238b6.0537d"]]},{"id":"7760dd5f.fe8f64","type":"string","z":"824c0efa.febe88","name":"trim whitespace","methods":[{"name":"trim","params":[]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":200,"y":1620,"wires":[["4915182e.2a126"]]},{"id":"4e5f56b2.fe7948","type":"delay","z":"824c0efa.febe88","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"2","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1390,"y":860,"wires":[["8d35941c.c9336"]]},{"id":"b64dd80.eff27a8","type":"serial-port","z":"","serialport":"/dev/ttyUSB1","serialbaud":"115200","databits":"8","parity":"none","stopbits":"1","waitfor":"","newline":"32000","bin":"bin","out":"count","addchar":"","responsetimeout":"10000"}]

Flow vložíte jednoduše klávesovou zkratkou Ctrl-I.

Disclaimer: Neumím programovat. Proto na parsování používám všechny ty string nody. Určitě by na to šla použít nějaká funkce, ale nechtělo se mi to učit.

Nastavení nodů

Modem stardardně vytvoří 3 sériové porty (ttyUSB0, ttyUSB1, ttyUSB2). My budeme používat druhý port (ttyUSB1) na audio při hovoru a třetí port (ttyUSB2) na přijímání a odesílání AT příkazů a přijímání SMS. Oba porty se nastavují na začátku. Pozor, ttyUSB2 se nastavuje uvnitř subflow, klikněte na node ttyUSB2 a ještě na “edit flow template” a pak ještě jednou na node ttyUSB2.

Každý port má jiné nastavení komunikace. Je nutné to nastavit správně, jinak audio (ttyUSB1) a odesílání příkazů (ttyUSB2) nebudou fungovat správně.

ttyUSB1 (audio):

ttyUSB2 (příkazy):

 

Sériový port ttyUSB2 (příkazy) můžete otestovat odesláním příkazu AT (viz modrý inject node). V podokně debugu (ikona brouka vpravo nahoře) pak sledujte, jestli jste na příkaz dostali nějakou odpověď. Pokud uvidíte “0”, trefili jste správný port. Technická poznámka: v modemu je zapnutý “limited response format”, proto neuvidíte klasickou odpověď “OK”, ale jenom její číselnou alternativu “0”.

Sériový port ttyUSB1 (audio) si otestujete až při samotném hovoru. Po aktivaci zeleného debug nodu (musíte si ho zapnout) byste při hovoru (vlastně i při samotném vytáčení) měli vidět přehršel čísel (to je samotný zvuk v bufferu).

Dále si musíte nastavit UDP nody. V prvním nodu udp-in si nastavíte místní port, na kterém bude poslouchat Node Red. Mám nastavené, aby Node Red poslouchal na portu 10007. Můžete si to změnit, ale poznamenejte si to.

V druhém nodu udp-out si nastavíte vzdálenou IP adresu Loxonu a vzdálený port, na kterém bude Loxone poslouchat. Mám to nastavené tak, aby Loxone poslouchal na portu 10007. Můžete si to klidně změnit, ale poznamenejte si to, budete to potřebovat při nastavování Loxonu.

Oba UDP nody mám nastavené tak, že Loxone i Node Red poslouchají na stejných portech, ale to samozřejmě není nutné, můžete si vybrat porty odlišné.

Jako poslední si nastavíme globální proměnné. MP3 soubory s audiem se ukládají na úložiště v Raspberry (do domovské složky). V případě potřeby si můžete jméno adresáře upravit (standardně audiocache) a můžete si nastavit maximální velikost této cache (standardně 10MB). Dále si v případě potřeby můžete změnit jazyk převodu TTS a mezinárodní předvolbu pro příchozí a odchozí hovory.

Co ten flow v Node Redu dělá

Flow nejdřív udělá prvotní nastavení modemu. Potom se stará o překlad AT příkazů, kterými se ovládá modem, do podoby user friendly UDP příkazů, kterými komunikuje s Loxonem (tyto UDP příkazy si popíšeme níže). Pro nastavení a provoz GSM modulu vůbec nepotřebujete znát samotné AT příkazy. Pokud byste si chtěli hrát nebo něco testovat, nechal jsem vám úplně dole i nějaké samostatné AT příkazy (viz “useful commands”).

Celý flow je udělaný tak, abyste ho jednou nastavili a potom už na něho nemuseli sahat. Všechno ostatní se bude dělat v Loxonu:

  • Konfigurace autorizovaných telefonních čísel
  • Nastavení příchozích SMS příkazů
  • Obsah odchozích SMS zpráv
  • Obsah odchozích hlasových zpráv
  • Veškerá logika co a jak se bude ovládat atd.

Jediné, co je potřeba v Node Redu hlídat:

  1. Pokud k Raspberry Pi připojíte další USB zařízení, tak se vám pravděpodobně změní sériové porty a budete muset překonfigurovat nody serial-in a serial-out.
  2. Na převod text-to-speech se používá Google. Nepoužíváme ale standardní Google API (to je placené), ale pro převod na řeč využíváme (zneužíváme) webové služby translate.google.com (na tom je postavený node-red-contrib-google-tts). Je to neoficiální oklika, která může přestat fungovat. Původně jsem hledal offline řešení, ale jediné offline řešení pro Linux jsem našel program “festival”. Výsledky byly katastrofální. Tak jsem na TTS zkoušel různá cloudová API. Těm buď chyběla čeština (Amazon, IBM Watson) nebo byla placená (Microsoft a další). Nakonec jsme jako jediné použitelné a neplacené řešení našel Google.

Nastavení v Loxone Config

První sadu příkazů jsem popsal v prvním dílu (https://www.vodnici.net/wiki/gsm-modul-integrace-do-loxone-pres-udp/). Všechny příákazy z prvního dílu (vč. callout) zůstávají funkční. V tomto dílu představím příkazy týkající se hlasového volání.

Node Red z Loxonu přijímá tyto UDP příkazy:

  • gsm voice <volané číslo> <text hlasové zprávy>
  • gsm voice test

Node Red do Loxonu posílá tyto UDP příkazy:

  • gsm voice error
  • gsm voice cachefull

Výstupy z Loxonu

gsm voice <volané číslo> <text hlasové zprávy>

Hlasové volání na uvedené číslo (číslo bez mezinárodní předvolby). Číslo příjemce musí být odděleno z obou stran mezerami. Samotný text hlasové zprávy může obsahovat mezery. Můžete a měli byste používat interpunkci, aby hlasu bylo rozumět. Délka hlasové zprávy není omezena (teoretický limit je 200*999 znaků, místo na disku pro výslednou MP3 s hlasem zprávy a 10 minutový limit pro délku hovoru).

Node Red vytočí volané číslo a pokud to volaný zvedne, tak mu přečte text zprávy. Pokud to típnete (třeba jste zrovna někde na jednání) nebo pokud to nezvednete (timeout pro vyzvánění je stanovený na 1 minutu), tak se nic neděje, Node Red vám pošle text zprávy SMSkou. Z textu původní hlasové zprávy se odstraní interpunkce, zpráva se rozdělí na úseky dlouhé 160 znaků a SMSka (SMSky) se odešle na volané číslo.

Před samotným vytáčením hovoru ještě Node Red kontroluje, jestli mu náhodou to stejné číslo zrovna nevolá v příchozím hovoru. Pokud tam ten příchozí hovor je, tak ho rovnou zvedne a přečte text zprávy (k čemu to je dobré uvidíte níže).

Pro úplnost dodám, že Node Red opakuje hlasovou zprávu ve smyčce, maximální délka hovoru je pro jistotu omezena na 10 minut.

Příklad syntaxe:

gsm voice 123456789 Tvůj barák hoří, zavolej si hasiče!

Na odeslání hlasové zprávy využijeme UDP logger, který jsme si vytvořili pro potřeby odesílání SMS v minulém díle. Vytváření a odesílání hlasového volání je úplně stejné jako vytváření a odesílání SMS (viz příkaz gsm sms <číslo> <zpráva> v prvním díle). Využíváme blok Status napojený na UDP logger, jediný rozdíl je v tom, že v syntaxi příkazu je “voice” místo “sms”. Odchozí hlasové zprávy můžete používat například na alarmy, kdy chcete, aby vám Loxone sám zavolal a řekl vám, co se děje.

Následující příklad je trochu složitější, ukážeme si jak zkombinovat příchozí hovor do Loxonu s hlasovou zprávou z Loxonu:

Takže co tu máme. CALLIN příchozí hovor do Loxonu, dvě autorizovaná čísla. CALLIN funguje jako “virtuální tlačítko”, které pošle impuls při každém zazvonění telefonu. Viz předchozí díl.

Blok Vícenásobný stisk znamená, že pokud telefon típnu po prvním nebo po druhém nebo po třetím zvonění, tak se mi rozsvítí světlo na chodbě (otevře se brána nebo co je vám libo). Pokud ale hovor do Loxonu netípnu, tak se aktivuje blok Status. Blok status do Node Redu odešle požadavek na hlasovou zprávu pro telefonní číslo, které zrovna Loxonu volá. Node Red zjistí, že se obě čísla shodují a ten příchozí hovor rovnou zvedne a přečte vám text hlasové zprávy. Toto řešení můžete používat na rychlé zjištění stavu nějakého čidla nebo celkového stavu domu. Výhoda je jasná: voláte vy, platíte vy a šetříte kredit na SIMkartě v Loxonu. Takže si v tomto případě můžete dovolit dlouhé hlasové zprávy.

Status blok “VOICE stav topení” je napojený na UDP logger a stará se o samotné odeslání hlasové zprávy. Na vstupy můžete přivést digitální signál (vstup AI2 se stavem topení), analogový signál (AI1 obsahující číslo, na které se má zavolat) i textová data (na vstup AI3 je přiveden textový výstup statusu “Teplota ZZ”). Na vstup AI4 je přiveden spouštěč. Nastavení bloku VOICE stav topení:

a samozřejme napojení na UDP logger. Můžeme využít ten, co jsme si vytvořili pro potřeby odesílání SMS:

 

Nastavení bloku Status “Teplota ZZ” je jednoduché. Tento blok není napojený na UDP logger, není na něj přivedený žádný spouštěč. Zrušte jeho zobrazení ve vizualizaci a jako text můžete dát třeba toto. Nebojte se desetinných čísel, Google TTS je zvládá s přehledem.

Ten druhý blok Status jsem tam dal jenom jako ukázku řetězení. Můžete si takto poskládat opravdu dlouhou zprávu obsahující všechny důležité stavy a čidla v domě.

gsm voice test

Jednoduchý příkaz, který otestuje dostupnost služby Google TTS (důvody proč je dobré ji testovat jsem uvedl výše). Pokud je možné stáhnout z Googlu přehratelnou MP3, nic se nestane. Pokud dojde k chybě, pošle vám Node Red UDP zprávu “gsm voice error”.

V Loxone Config si vytvořte Virtuální výstup příkazu, kde si nastavíte

Instrukce při zapnutí

gsm voice test

 

Vstupy do Loxonu

Opět standardně použijeme Virtuální UDP vstupy. Asi bych zase doporučil ty čachry s validací, abychom dostali “digitální impuls” (viz předchozí díl).

gsm voice error

Může znamenat buď:

  • chybu při převodu textu na řeč Google TTS (nedostupný internet, zablokovaný Google, nepřehratelná mptrojka…)
  • chybu při přehrávání MP3 souboru do telefonu přes ffmpeg

V každém případě je na volané číslo text původní hlasové zprávy v SMSce.

gsm voice cachefull

Cache pro audio soubory dosáhla limitu, který jste si nastavili na začátku. Pár slov k tomu, proč tam ta cache je a jak funguje. Cache je tam jako pojistka proti nedostupnosti internetu a Google TTS. Při prvním požadavku na převod TTS se odešle požadavek na Google, odkud se pak stáhne výsledná MP3 s hlasem. Pokud budete později potřebovat hlasovou zprávu  se zcela identickým obsahem, tak se žádný požadavek na Google neposílá, ale vezme se MP3 soubor z cache. Doporučuju proto, aby důležité zprávy alarmu neobsahovaly žádné dynamické proměnné (“Tvůj barák hoří, zavolej si hasiče!”). Poté, co si je nastavíte v Loxonu, tak si je na zkoušku aktivujte, aby se hlas zprávy uložil do cache. Pak budete mít jistotu, že se hlasové volání v budoucnu realizuje i když nepůjde internet nebo nebude fungovat Google TTS. Zprávy s dynamickými proměnnými (“Teplota v zimní zahradě je <v1.1> stupňů Celsia.”) se budou při každé změně proměnné stahovat znova. Takže pokud budete často používat různé hlasové zprávy s dynamickými proměnnými, budete potřebovat větší cache. Pro úplnost dodávám, že Google posílá hlas ve MP3, mono, 32 kBit/s. Takže těch 10MB cache by mělo vystačit na cca 42 minut hlasových zpráv.

Co se stane, když cache dosáhne limitu? Jednak se odešle UDP zpráva (gsm voice cachefull), zároveň se smaže aktuální hlasová zpráva, která překročení limitu zavinila. Samozřejmě až poté, co byla přehrána do telefonu. Staré zprávy (to jsou ty důležité, které jste si převedli do audia jako první) se nemažou.

GSM modul (1. díl – integrace do Loxone přes UDP)

GSM modul (1. díl – integrace do Loxone přes UDP)

K čemu to je

GSM modul se hodí jako alternativní kanál pro komunikaci s Loxonem, zvláště v těchto případech:

  • Loxone nemá připojení k internetu (např. někde na chatě apod.).
  • Nechce se Vám (neumíte) nakonfigurovat bezpečné internetové připojení k Loxonu (přes VPN).
  • Chcete se rychle dozvědět o kritických událostech v domě (alarm, stisknutí tísňového tlačítka apod). Nechcete se spoléhat na nějaké push notifikace a chtěli byste, aby vám Loxone rovnou poslal SMS nebo zavolal.
  • Chcete rychle něco ovládat mobilem (příjezdová brána) přes prozvonění a nechce se vám listovat v Loxone app.
  • Chcete umožnit třetím osobám, které nemají v telefonu Loxone aplikaci, aby něco na dálku ovládali (přes zavolání nebo přes SMS)
  • Nechce se vám platit za službu Loxone Caller…

Samozřejmě provoz GSM modulu není (na rozdíl od internetu) zadarmo, platíte za SMSky. Vybírejte tarif s levnými SMS a dlouhou dobou platnosti kreditu.

Co to umí

  • odesílat a přijímat hovory
  • odesílat a přijímat SMS zprávy
  • odesílat a přijímat USSD kódy

Výhodou oproti dedikovaným GSM modulům (např. od alarmů) je to, že nejste nijak omezeni co se týče počtu vstupů a výstupů. Můžete (zavoláním a SMS zprávami) ovládat všechno, co máte v domě. A stejně tak máte neomezené možnosti toho, co vám bude Loxone posílat SMS zprávami. Při odesílání SMS z Loxonu nejste omezeni několika předem nadefinovanými SMS zprávami, ale můžete si obsah SMS dynamicky skládat v samotném Loxonu. Detailní možnosti použití viz níže.

Co to neumí:

  • Neumí to mluvit. Takže vám to sice zavolá, ale pokud hovor zvednete, tak vám to nic neřekne. Možná by to šlo zprovoznit pomocí nějakého text-to-speech nodu pro Node Red, ale nezkoušel jsem to, protože jsem nedokázal zjistit, jak poslat audio stream přes USB/Serial do GSM modulu.
  • Neumí to tónovou volbu (zadání číselného kódu přes klávesnici telefonu). Nezkoušel jsem to a ani nevím, co by k tomu bylo potřeba.

 

Jaký hardware budete potřebovat

  • Raspberry Pi nebo jakýkoliv jiný stroj, na kterém dokážete zprovoznit Node Red a který má jeden volný USB port. V mém případě se jedná o Unipi Neuron (PLC postavené na Raspberry). Neuron má řadu neduhů, občas tady na něj svorně nadáváme, ale tady si neodpustím menší reklamu. Je to super mít v rozvaděči krabičku, která zvládne běh Node Red a která má 4 USB porty, ke kterým se v Node Red snadno dostanete přes serial-in a serial-out.
  • USB modem s podporou hlasového volání. V mém případě Huawei E353 (https://www.aliexpress.com/item/HiLink-Huawei-E353-3G-usb-Modem-3g-dongle-3g-usb-stick-3g-huawei-modem-pk-e3131/32773440894.html ). Myslím, že pokud sáhnete po jakémkoliv modemu od Huawei, tak bude mít podporu hlasu.

Toť vše. Z hlediska HW není potřeba nic řešit. Vložíte SIM do modemu (karta nesmí mít nastavený PIN kód). Píchnete modem do USB a je to.

Poznámka pod čarou 1: Zkoušel jsem postavit celé řešení na Arduinu (Arduino Uno + ethernet shield + GSM shield). Přes Arduino se dá udělat přeposílání AT příkazů přes UDP, ale nikdy na Arduinu neuděláte parsování AT příkazů jako to mám v Node Red. A nakonec stejně narazíte na problém s napájením “žravého” GSM shieldu… Jak říká Jára Cimrman: Tudy ne, přátelé. Tudy cesta nevede.

Poznámka pod čarou 2: Pokud byste náhodou chtěli mít víc GSM modulů, není problém. Stačí upravit Node Red flow třeba tak, aby každý GSM modul poslouchal na jiném UDP portu.

 

Jaký software budete potřebovat

Přesunuto do druhého dílu.

 

Nastavení v Loxone Config

Node Red z Loxonu přijímá tyto UDP příkazy:

  • gsm callout <volané číslo>
  • gsm hangup
  • gsm sms <číslo příjemce> <text zprávy>
  • gsm ussdout <USSD kód>

Node Red do Loxonu posílá tyto UDP příkazy:

  • gsm callin <volající číslo>
  • gsm signal <síla signálu v dBm>
  • gsm <sms příkaz> <číslo odesílatele>
  • gsm ussdin <text USSD zprávy>

Probereme si nastavení Loxone Config po jednotlivých UDP příkazech.

 

Virtuální výstupy

Jako první si udělejte nový Virtuální výstup, kde si nastavíme

Adresa

/dev/udp/192.168.1.78/10007

kde 10007 je port, na kterém poslouchá Node Red.

 

gsm callout <volané číslo>

UDP příkaz na zavolání čísla. Pokud by v té době už nějaký příchozí nebo odchozí hovor probíhal, tak se nejdřív ten starý hovor položí a teprve pak začné nové odchozí vyzvánění. Hovor bude vyzvánět maximálně 1 minutu a potom se sám položí (nastaveno v Node Red). Volané číslo je v devítimístném formátu bez předčíslí.

V Loxone Config si vytvořte Virtuální výstup příkazu, kde si nastavíte

Instrukce při zapnutí

gsm callout <v>

Doporučuji vytvořit si konstantu, do které si uložíte vaše telefonní číslo (9-místný formát bez předčíslí). Bude se vám to hodit. Na jednoduché otestování můžete použít blok analogové paměti. Spouštět ho můžete fyzickým nebo virtuálním tlačítkem – níže uvedený příklad je vlastně příkladem tísňového tlačítka. Jak vidíte, na ovládání gsm callout můžete použít impuls. Po uvolnění tlačítka se analogová paměť zresetuje, na Node Red se sice odešle UDP příkaz “gsm callout 0”, ale v reálu se žádná nula nevytočí.

Připomínám, že Loxone (zatím) neumí mluvit. Zavolá vám, ale neřekne vám, proč volá. Takže doporučuju kombinovat gsm callout s odesláním SMS, abyste vědělli, proč vám Loxone volá.

 

gsm hangup

Jednoduchý UDP příkaz bez dalších parametrů. Položí jakýkoliv odchozí či příchozí hovor. Příklad využití: Loxone položí příchozí hovor (viz gsm callin) aby vám potvrdil, že přijal váš požadavek.

V Loxone Config si vytvořte Virtuální výstup příkazu, kde si nastavíte

Instrukce při zapnutí

gsm hangup

 

gsm sms <číslo příjemce> <text zprávy>

Odeslání SMS zprávy na uvedené číslo (opět číslo bez mezinárodní předvolby). Číslo příjemce musí být odděleno z obou stran mezerami. Samotná zpráva může obsahovat mezery. Příklad:

gsm sms 123456789 Ahoj, jak se mas?

Bohužel v Loxone neexistuje žádný “virtuální textový výstup”, takže si musíme pomoct přes UDP logger. V Loxone Config si vytvořte nový Logger, kde si nastavíte

Adresa loggeru

/dev/udp/<IP adresa stroje s Node Redem>/10007

v příkladu níže je 192.168.1.78 adresa mého stroje s Node Redem a 10007 je port, na kterém Node Red poslouchá.

Samotné sestavení textu SMS zprávy uděláme přes blok Status. Tento status nebude vidět ve vizualizaci, takže Vizualizace>Použít>zrušit zaškrtnutí. Blok má celkem 4 analogové vstupy. Na tyto vstupy můžete přivést analogovou hodnotu, digitální hodnotu (0/1) a dokonce i textovou hodnotu (např. výstup jiného bloku Status). Blok Status má jenom 4 vstupy. Pokud by Vám to nestačilo, můžete bloky Status řetězit (výstup jednoho bloku půjde do vstupu dalšího bloku). Na jeden ze vstupů si pošleme telefonní číslo, kam budeme SMS posílat. Na další vstupy si přivedeme cokoliv, u čeho chceme sledovat stav přes SMS (stav topení, teplota, stavy alarmu…).

Zároveň doporučuji přivést na jeden ze vstupů i nějaký spouštěč (impuls), tak abyste mohli řídit nejenom to, co se bude v SMS odesílat (např. stav topení), ale i kdy se to bude odesílat (tímto impulsem může být například i příchozí SMS příkaz – viz příklad níže). Pokud byste chtěli odesílat SMS opakovaně v určitých intervalech (například opakovaná SMS při alarmu), můžete si pomoct přes nějaký generátor impulsů přivedený na vstup bloku Status.

Uvnitř bloku Status si ve sloupci “Text statusu” nadefinujeme text UDP zprávy (a tedy i text samotné SMS zprávy) v souladu s naší syntaxí. Takže například:

gsm sms <v1> Topeni je vypnute.

Kde <v1> je telefonní číslo (například jako konstanta) přivedené na vstup 1.

Zároveň si nadefinujeme podmínky, za kterých se bude tato zpráva odesílat. Upozorňuji, že SMS se odešle vždy, když se má daný text statusu zobrazit. Text statusu se zobrazí vždy, když jsou splněny nadefinované podmínky na vstupech. A podmínky na vstupech se kontrolují i v okamžiku, kdy se Loxone spustí! Pokud byste měli jako jedinou podmínku změnu stavu sledované veličiny, tak by se SMS odesílala i při každém spuštění Loxonu. Proto je potřeba přivést do bloku kromě sledovaného stavu (stav topení je na vstupu 1) i nějaký další spouštěč (v mém příkladě je spouštěč na vstupu 4).

No a potom stačí k bloku Status přiřadit námi nadefinovaný UDP logger. “Minimální časový interval” doporučuji stáhnout na nulu (pro případ, že byste chtěli rychle za sebou poslat SMS na více čísel). Aby se SMS neodesílaly příliš často je potřeba ohlídat podmínkami uvnitř samotného bloku Status.

 

gsm ussdout <USSD kód>

Odeslání USSD kódu. Využití: zjišťování stavu kreditu na SIM kartě. USSD kód samozřejmě může obsahovat hvězdičky, mřížky atd.

V Loxone Config si vytvořte Virtuální výstup příkazu. Tady je příklad pro zjištění kreditu přes Kaktus.

Instrukce při zapnutí:

gsm ussdout *103#

 

Virtuální UDP vstupy

Udělejte nový Virtuální UDP vstup, kde si nastavíme

Adresa odesílatele

<vaše adresa stroje s Node Red>

UDP port

<port, na kterém poslouchá Loxone>

 

gsm signal <síla signálu v dBm>

Modem pravidelně a sám od sebe informuje o stavu signálu. Proč toho nevyužít. Takže první vstup je síla signálu.

Přidáme nový Virtuální UDP příkaz. Nastavíme

Rozeznání příkazu

gsm signal \v

Modem posílá sílu signálu v rozmezí 0 až 13, to je potřeba převést na dBm pomocí “Oprava” a případně můžete zapnout i validaci:

 

gsm ussdin <text USSD zprávy>

Toto je USSD zpráva, kterou modem pošle jako odpověď na váš předchozí dotaz gsm ussdout. Využití: ověření stavu kreditu. Toto fakt není radno podceňovat. GSM modem bude mít na starosti kritické věci jako alarm a určitě nechceme, aby nám tam došel kredit. Buďto si pořiďte nějaký tarif nebo si nastavte kontrolu kreditu přes příkazy gsm ussdout a gsm ussdin.

Node Red odešle USSD zprávu celou, je proto potřeba z ní vyparsovat proměnné, které nás zajímají. Zapněte si UDP monitor. Pošlete si na GSM modul dotaz “gsm ussdout <kód na zjištění kreditu>”. Do UDP monitoru dostanete zprávu od operátora. Pro každou proměnnou si udělejte Virtuální UDP příkaz a parsujte podle toho, jak vypadá zpráva od operátora. Já mám Kaktus, zpráva vypadá takto

Tvoje cislo +420XXXXXXXXX ma kredit 79.00 Kc, Platnost SIM do 15.11.2019.

Takže “Rozeznání příkazu” pro jednotlivé Virtuální UDP příkazy vypadá takto:

Kredit

\ikredit\i \v

Den platnosti

\iPlatnost SIM do \i\v

Měsíc platnosti

\iPlatnost SIM do \i\w.\v

Rok platnosti

\iPlatnost SIM do \i\w.\w.\v

 

Doporučuji nastavit validaci pro případ, že operátor změní formát zprávy a parsování selže.

Pokud chci vědět, za kolik dní mi kredit vyprší, musím použít PicoC (blok Program), kde vstup 1 je den platnosti, vstup 2 je měsíc a vstup 3 je rok. Na výstupu mi polezou zbývající dny platnosti:

int nEvents;
while(TRUE)
{
nEvents = getinputevent();
if (nEvents & 0xe)
{
int day = getinput(0);
int month = getinput(1);
int year = getinput(2);
int currentTime = getcurrenttime();
int deltaDays = (gettimeval(year, month, day, 0, 0, 0, 0) - gettimeval(getyear(currentTime, 1), getmonth(currentTime, 1), getday(currentTime, 1), 0, 0, 0, 1)) / (60*60*24);

setoutput(0,deltaDays);
}
sleep(60000);
}

Poznámka: nejsem programátor, prosím někoho o kontrolu. Občas mi to zlobí a hodnota na výstupu se neaktualizuje v případě změny na vstupu.

No a v tuhle chvíli si už můžeme poskládat notifikační SMS, aby nás Loxone upozornil SMSkou v případě, že bude docházet kredit nebo se bude blížit doba vypršení kreditu:

Pro lepší pochopení tam máte ukázané o hodnoty jednotlivých vstupů a výstupů. Většinu bloků jsme si popsali. Je tam:

  • gsm ussdout na dotaz na kredit
  • gsm ussdin, které z odpovědi operátora parsují: kredit, den, měsíc a rok vypršení platnosti.
  • Program (PicoC) na konverzi zbývajících dnů platnosti.
  • Pak tam jsou dva bloky Impulz v daném čase, které vždy jednou za den mají za úkol “Zjistit kredit” (třeba v 5:59) a “Odeslat SMS” (třeba v 6:00).
  • Blok Status “Nízký kredit” odesílá SMS při nízkém kreditu nebo nízké zbývající době platnosti:

 

Pokud klesne kredit pod stanovený limit (v příkladu 20 Kč) nebo zbývající dny klesnou pod stanovený limit (30 dní), odešle se při následujícím impulzu (viz blok Impulz v daném čase na vstupu 4) varovná SMS. Každý den se bude SMS opakovat, dokud kredit nedobijete (nebo dokud varovné SMS nespotřebují veškerý zbývající kredit :-)).

 

gsm callin <volající číslo>

Příchozí hovor. Node Red je nastavený tak, že při každém zvonění odesílá UDP zprávu. UDP zprávu přijmeme pomocí (analogového) virtuálního UDP vstupu, který nakonfugurujeme takto:

Rozeznání příkazu

gsm callin \v

A nastavte validaci podle obrázku. Min a max na krajní dovolené hodnoty (nezapomínejte, že budeme posílat defítimístné číslo). Standardní hodnota 0 a časový limit 1s. Virtuální vstup se pak bude chovat jako “analogový impuls”. Jednu sekundu bude posílat volající číslo a pak vstup se zresetuje na hodnotu 0.

Máme tedy volající číslo a teď je potřeba ho ověřit. Hledal jsem způsob, jak to udělat a nakonec jsem skončil u bloku Vzorec (pokud byste měli lepší řešení, dejte vědět).

EDIT: Úplně jsme přehlídl blok Rovnost.

Na vstupy přiveďte samotný virtuální UDP vstup a autorizované telefonní číslo, které máte uložené jako konstantu. Tady je příklad dvou autorizovaných čísel:

 

K čemu je tam ten bloky Zpoždění zapnutí a vypnutí? Loxone má nepříjemnou vlastnost, že při startu mají na kratičkou chvíli všechny analogové konstanty a všechny analogové virtuální vstupy hodnotu nula (to znamená volající číslo odpovídá autorizovanému a odešle se impuls na rozsvícení světla na chodbě). Blok Zpoždění zapnutí a vypnutí slouží k tomu, že zablokuje jakýkoliv impuls kratší než 0,5s. Připomínám, že impuls posílaný Virtuálním UDP vstupem callin má délku 1s, takže bez problémů projde. Blok Zpoždění zapnutí a vypnutí je třeba nastavit takto:

Ve schématu máte i gsm hangup, který hovor zavěsí jako potvrzení toho, že Loxone přijal vaši instrukci. Nezapomeňte, že pokud telefonát nepoloží ani Loxone, ani volající osoba, tak z Node Redu budou do Loxonu chodit další opakované UDP zprávy (impulsy) při každém zvonění.

 

gsm <sms příkaz> <číslo odesílatele>

Příchozí příkazy přes SMS. Nejlepší asi bude, když vysvětlím, co se v Node Red stane, pokud na GSM modul přijde SMS zpráva. SMS zpráva se rozdělí na jednotlivá slova (rozdělovačem je mezera) a tato slova jsou v původním pořadí odesílána v jednotlivých UDP zprávách v intervalech 1s. Takže máte sérii UDP zpráv:

gsm <slovo1> <číslo odesílatele>
gsm <slovo2> <číslo odesílatele>
....

Kromě toho se všechna písmena převedou na malá a odstraní se případná diakritika (abyste se při psaní SMS nemuseli trápit jestli máte správnou velikost písmen).

Nastavení v Loxonu je jednoduché. vytvořte si Virtuální UDP příkaz (vstup), ve kterém si nastavíte

Rozeznání příkazu

gsm <prikaz> \v

například

gsm topeni1 \v

 

Váš příkaz může být jakékoliv slovo:

  • z písmen, číslic a znaků
  • bez mezer
  • pouze malá písmena
  • bez diakritiky
  • slova “signal” a “callin” nepoužívejte, aby nedocházelo ke kolizi s jinými příkazy.

Dále si ve virtuálním UDP příkazu nastavte validaci stejným způsobem, jako jsem to popsal u vstupu “gsm callin”. Aby vám UDP příkaz fungoval jako “analogový impuls”.

Toť vše. Stačí vytvořit Virtuální UDP s vaším příkazem a můžete ho hned začít používat v SMS zprávách. V jedné zprávě můžete poslat víc příkazů, oddělených mezerníkem. Loxone je bude provádět postupně v daném pořadí (s prodlevou 1s). Například já mám příkazy “topeni0” na vypnutí topení, “topeni1” na zapnutí a “topenistav” jako dotaz na aktuální stav. Pokud pošlu SMS “topeni1 topenistav”, tak mi Loxone zapne topení a zpátky mi pošle potvrzovací SMS s aktuálním stavem topení.

Validace čísla odesílatele probíhá úplně stejně jako u gsm callin, přes bloky Vzorec a Zpoždění zapnutí a vypnutí (přiznám se, není to moc elegantní, uvítám návrhy na lepší řešení):

Blok Status posílá SMS o stavu topení zpátky na číslo, ze kterého mu přišel dotaz. Nastavení máte uvedené nahoře, když jsem popisoval příkaz gsm sms. Nezapomeňte napojit celý blok na UDP logger, který jsme si vytvořili dříve.

 

 

No a toť vše.