Descripción
Disponemos de este descalcificador instalado en el garaje:

Usando una cámara IP vamos a capturar la imagen de lo que sale en la pantalla del descalcificador. Como interface de usuario tendremos un M5Stack basado en ESP32. Así pues, cada vez que pulsemos un botón del dispositivo IoT (M5Stack) este se publicará en un broker de mensajes MQTT. Se capturará el mensaje en NodeRED donde usando un OCR instalado en local se decodificará la imagen. Concretamente usamos una aplicación de HP llamada Tesseract. Esta información se mandará de vuelta a la pantalla del M5Stack para que la visualice el usuario.
El esquema del escenario quedaría así:

Para los que no conozcaís M5Stack tiene esta pinta:

Flow de NodeRED

Dependencias
Hay que tener instalado el node: node-red-contrib-tesseract

Código del flow
[{"id":"f60a422b.eb35","type":"tab","label":"Local Vision","disabled":false,"info":""},{"id":"f3509ca4.226c3","type":"inject","z":"f60a422b.eb35","name":"manual test","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":470,"y":160,"wires":[["e66284f1.cb7528"]]},{"id":"e66284f1.cb7528","type":"exec","z":"f60a422b.eb35","command":"sudo docker run --rm jrottenberg/ffmpeg -y -rtsp_transport tcp -i 'rtsp://admin:ges2ges.@10.2.8.95/h264/ch1/sub/av_stream' -filter:v \"crop=704:536:0:20\" -vframes 1 -f image2pipe -vcodec png -","addpay":"","append":"","useSpawn":"false","timer":"60","oldrc":false,"name":"ffmpeg","x":650,"y":240,"wires":[["5e01ca97.09aef4","9fca843.eb6ac78"],["d6c548dd.75efe8"],["364d77a6.cf24b8"]]},{"id":"5e01ca97.09aef4","type":"file","z":"f60a422b.eb35","name":"debug: image.png","filename":"/data/image.png","appendNewline":true,"createDir":false,"overwriteFile":"true","encoding":"none","x":930,"y":300,"wires":[[]]},{"id":"d6c548dd.75efe8","type":"debug","z":"f60a422b.eb35","name":"ffmeg error","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":910,"y":360,"wires":[]},{"id":"524fcf3b.f1e45","type":"mqtt in","z":"f60a422b.eb35","name":"display/button","topic":"display/button","qos":"2","datatype":"auto","broker":"d32bbf31.d1fa5","nl":false,"rap":true,"rh":0,"x":130,"y":240,"wires":[["b3e6e19e.fa369","56a95d95.b7bb74"]]},{"id":"5379112c.7d096","type":"switch","z":"f60a422b.eb35","name":"Button A?","property":"payload.button","propertyType":"msg","rules":[{"t":"eq","v":"A","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":480,"y":240,"wires":[["e66284f1.cb7528"]]},{"id":"b3e6e19e.fa369","type":"debug","z":"f60a422b.eb35","name":"MQTT RX msgs","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":160,"y":340,"wires":[]},{"id":"56a95d95.b7bb74","type":"json","z":"f60a422b.eb35","name":"","property":"payload","action":"","pretty":false,"x":330,"y":240,"wires":[["5379112c.7d096"]]},{"id":"364d77a6.cf24b8","type":"debug","z":"f60a422b.eb35","name":"ffmeg output code","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"msg","x":930,"y":420,"wires":[]},{"id":"9fca843.eb6ac78","type":"tesseract","z":"f60a422b.eb35","name":"OCR","language":"eng","x":750,"y":100,"wires":[["74506b90.ce8d14","75a9c4a0.c0abac"]]},{"id":"75a9c4a0.c0abac","type":"debug","z":"f60a422b.eb35","name":"debug ocr","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"msg","x":1040,"y":100,"wires":[]},{"id":"3fd0b4a1.c0f19c","type":"mqtt out","z":"f60a422b.eb35","name":"display/text","topic":"display/text","qos":"0","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"d32bbf31.d1fa5","x":1070,"y":200,"wires":[]},{"id":"74506b90.ce8d14","type":"function","z":"f60a422b.eb35","name":"clean string","func":"\nreturn {\n payload: msg.payload.replace(/\\s{2,10}/g, ' ').trim()\n};","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":890,"y":200,"wires":[["3fd0b4a1.c0f19c","75a9c4a0.c0abac"]]},{"id":"d32bbf31.d1fa5","type":"mqtt-broker","name":"local MQTT broker","broker":"localhost","port":"1883","clientid":"","usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":""}]
