Domotique et objets connectés à faire soi-même

Node-RED. Dashboard pour objet connecté. Jauges, graphiques, notifications, template HTML (Partie 2)

Dashboard Angular / HTML pour node-red. jauges, champ de saisie template

Dans ce second tutoriel consacré à la création d’un dashboard (tableau de bord) pour objet connecté à l’aide du module Dashboard pour Node-RED, nous allons nous intéresser à l’ajout des afficheurs graphiques. Jauges, graphiques, notifications, template HTML / Angular.

 

Tutoriel actualisé le 27 juillet 2020

Le module Dashboard propose 4 types d’afficheurs (jauge, graphique, champ texte, notification furtive), le composant ui-control qui permet de changer de panneau (tab) par programmation, et enfin un champ qui permet d’afficher du code HTML libre (déjà vu dans la 1ère partie).

Sonde de température MySensors DHT22 pour générer des mesures à afficher

Pour illustrer le fonctionnement des différents composants proposés par le plugin node-red-dashboard, je vous propose d’utiliser des mesures en provenance d’une sonde de température DHT22 MySensors. Nous allons simplement reprendre la sonde DHT22 créée pour ce projet.

Créer la page MySensors

Ouvrez l’onglet Dashboard et ajoutez un nouveau Tab. Nommez le MySensors par exemple. Ajoutez 2 groupes :

Le Dashboard ressemble à ça maintenant.

Changer de page par programmation (ui-control)

Ajoutons maintenant un composant ui-control qui permet de changer de page (tab) par programmation. Il accepte en entrée un payload sous 2 formes :

Pour cela, ajoutez une fonction et collez ce code

var msg = {};
msg.payload = {tab:"MySensors"};    // ou/or 1

return msg;

On peut déclencher le passage à une autre page depuis un bouton de commande par exemple.

Connection et extraction des mesures de la sonde MySensors DHT22

Maintenant, connectons Node-RED à la gateway MySensors pour récupérer les mesures. Si vous débutez sur le sujet, commencez par lire cet article. Ce flow (code ci-dessous) utilise le flow de décodage des messages MySensors. Un premier filtre permet d’extraire la mesure de température du noeud qui nous intéresse. Le second filtre permet d’extraire la mesure d’humidité.

Code du flow de connexion et d’extraction des mesures

[{"id":"3d21e1ce.01afee","type":"tcp in","z":"df9159f.e304ea8","name":"MySensors Gateway","server":"client","host":"192.168.1.20","port":"5003","datamode":"stream","datatype":"utf8","newline":"","topic":"","base64":false,"x":210,"y":640,"wires":[["4fc18f88.1911"]]},{"id":"4fc18f88.1911","type":"function","z":"df9159f.e304ea8","name":"Decode MySensor Message","func":"/* MySensors v2 Message Decoder\n*  Payload : JSON object\n*  www.projetsdiy.fr - oct. 2016\n*/\nvar mySensorsMessage = {}\nvar newPayload = {};\nvar timestamp = new Date();\nvar message = msg.payload.toString();\nmessage = message.replace(/(\\r\\n|\\n|\\r)/gm, \"\");\nvar tokens = message.split(\";\")\nif(tokens.length == 6)\n{\n    mySensorsMessage.nodeId =       parseInt(tokens[0]);\n    mySensorsMessage.childSensorId= parseInt(tokens[1]);\n    mySensorsMessage.messageType =  parseInt(tokens[2]);\n    mySensorsMessage.ack =          parseInt(tokens[3]);\n    mySensorsMessage.subType =      parseInt(tokens[4]);\n    mySensorsMessage.value =        Number(tokens[5]);\n\n    var messageType = mySensorsMessage.messageType;\n    var subType = mySensorsMessage.subType;\n    var labelPresentation = [\"S_DOOR\",\"S_MOTION\",\"S_SMOKE\",\"S_LIGHT\",\"S_BINARY\",\"S_DIMMER\",\"S_COVER\",\"S_TEMP\",\"S_HUM\",\"S_BARO\",\"S_WIND\",\"S_RAIN\",\"S_UV\",\"S_WEIGHT\",\"S_POWER\",\"S_HEATER\",\"S_DISTANCE\",\"S_LIGHT_LEVEL\",\"S_ARDUINO_NODE\",\"S_ARDUINO_REPEATER_NODE\",\"S_LOCK\",\"S_IR\",\"S_WATER\",\"S_AIR_QUALITY\",\"S_CUSTOM\",\"S_DUST\",\"S_SCENE_CONTROLLER\",\"S_RGB_LIGHT\",\"S_RGBW_LIGHT\",\"S_COLOR_SENSOR\",\"S_HVAC\",\"S_MULTIMETER\",\"S_SPRINKLER\",\"S_WATER_LEAK\",\"S_SOUND\",\"S_VIBRATION\",\"S_MOISTURE\",\"S_INFO\",\"S_GAS\",\"S_GPS\",\"S_WATER_QUALITY\"];\n    var labelSet = [\"V_TEMP\",\"V_HUM\",\"V_STATUS\",\"V_LIGHT\",\"V_PERCENTAGE\",\"V_DIMMER\",\"V_PRESSURE\",\"V_FORECAST\",\"V_RAIN\",\"V_RAINRATE\",\"V_WIND\",\"V_GUST\",\"V_DIRECTION\",\"V_UV\",\"V_WEIGHT\",\"V_DISTANCE\",\"V_IMPEDANCE\",\"V_ARMED\",\"V_TRIPPED\",\"V_WATT\",\"V_KWH\",\"V_SCENE_ON\",\"V_SCENE_OFF\",\"V_HVAC_FLOW_STATE\",\"V_HVAC_SPEED\",\"V_LIGHT_LEVEL\",\"V_VAR1\",\"V_VAR2\",\"V_VAR3\",\"V_VAR4\",\"V_VAR5\",\"V_UP\",\"V_DOWN\",\"V_STOP\",\"V_IR_SEND\",\"V_IR_RECEIVE\",\"V_FLOW\",\"V_VOLUME\",\"V_LOCK_STATUS\",\"V_LEVEL\",\"V_VOLTAGE\",\"V_CURRENT\",\"V_RGB\",\"V_RGBW\",\"V_ID\",\"V_UNIT_PREFIX\",\"V_HVAC_SETPOINT_COOL\",\"V_HVAC_SETPOINT_HEAT\",\"V_HVAC_FLOW_MODE\",\"V_TEXT\",\"V_CUSTOM\",\"V_POSITION\",\"V_IR_RECORD\",\"V_PH\",\"V_ORP\",\"V_EC\",\"V_VAR\",\"V_VA\",\"V_POWER_FACTOR\"]\n    var labelInternal = [\"I_BATTERY_LEVEL\",\"I_TIME\",\"I_VERSION\",\"I_ID_REQUEST\",\"I_ID_RESPONSE\",\"I_INCLUSION_MODE\",\"I_CONFIG\",\"I_FIND_PARENT\",\"I_FIND_PARENT_RESPONSE\",\"I_LOG_MESSAGE\",\"I_CHILDREN\",\"I_SKETCH_NAME\",\"I_SKETCH_VERSION\",\"I_REBOOT\",\"I_GATEWAY_READY\",\"I_REQUEST_SIGNING\",\"I_GET_NONCE\",\"I_GET_NONCE_RESPONSE\",\"I_HEARTBEAT\",\"I_PRESENTATION\",\"I_DISCOVER\",\"I_DISCOVER_RESPONSE\",\"I_HEARTBEAT_RESPONSE\",\"I_LOCKED\",\"I_PING\",\"I_PONG\",\"I_REGISTRATION_REQUEST\",\"I_REGISTRATION_RESPONSE\",\"I_DEBUG\"]\n    \n    switch (messageType) {\n        case 0:     // Presentation\n            newPayload.timestamp = timestamp;\n            newPayload.mode =       \"Presentation\";\n            newPayload.type =       labelPresentation[subType];\n            break;\n        case 1:     // Set\n            newPayload.timestamp = timestamp;\n            newPayload.nodeId=      mySensorsMessage.nodeId;\n            newPayload.sensorId=    mySensorsMessage.childSensorId;\n            newPayload.mode=        \"Set\";\n            newPayload.type=        subType;\n            newPayload.typeLabel=   labelSet[subType];\n            newPayload.value=       mySensorsMessage.value;\n            break;\n        case 2:     // Req\n            newPayload.timestamp = timestamp;\n            newPayload.nodeId=      mySensorsMessage.nodeId;\n            newPayload.sensorId=    mySensorsMessage.childSensorId;\n            newPayload.mode=        \"Req\";\n            newPayload.type=        subType;\n            newPayload.typeLabel=   labelSet[subType];\n            newPayload.value=       mySensorsMessage.value;\n            break;  \n        case 3:     // Internal\n            newPayload.timestamp = timestamp;\n            newPayload.nodeId=      mySensorsMessage.nodeId;\n            newPayload.sensorId=    mySensorsMessage.childSensorId;\n            newPayload.mode=        \"Internal\";\n            newPayload.type=        subType;\n            newPayload.typeLabel=   labelInternal[subType];\n            newPayload.value=       mySensorsMessage.value;\n            break;    \n        case 4:     // Stream - OTA firmware update\n            newPayload.timestamp = timestamp;\n            newPayload.nodeId=      mySensorsMessage.nodeId;\n            newPayload.mode=        \"stream\";\n            break;\n        default:\n            break;\n    }\n\n    msg.payload = newPayload; \n} else {\n    msg.payload = \"Error! Nothing to decode\"\n}  \n\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":560,"wires":[["e32665a5.08e548","ff9b32b9.a232c"]]},{"id":"e32665a5.08e548","type":"function","z":"df9159f.e304ea8","name":"Filtre : température noeud 3","func":"if (msg.payload.nodeId == 3 && msg.payload.type === 0) {\n    var msg;\n    msg.payload = msg.payload.value;\n    msg.topic = \"temperature\"\n    return msg;\n}    ","outputs":1,"noerr":0,"x":640,"y":620,"wires":[["f80bd8b2.372db8","3f202da1.ad8562","a1e15601.1df708"]]},{"id":"ff9b32b9.a232c","type":"function","z":"df9159f.e304ea8","name":"Filtre : humidité noeud 3","func":"if (msg.payload.nodeId == 3 && msg.payload.type === 1) {\n    var msg;\n    msg.payload = msg.payload.value;\n    msg.topic = \"humidity\"\n    return msg;\n}    ","outputs":1,"noerr":0,"x":630,"y":660,"wires":[["cdcc69de.3c1538","5e7f2a5b.57ba14","a1e15601.1df708"]]}]

Afficher une jauge (ou donut, compass, level)

Il ne reste plus qu’à afficher les mesures dans une jauge. Ajoutez un composant jauge sur le flow. On dispose de 4 types de présentation :

Ici nous choisirons le type jauge. Les autres paramètres importants sont :

Ce qui donne ceci

Afficher un graphique (chart)

Le module dashboard propose 2 types de graphiques :

Il est possible d’avoir plusieurs données sur un même graphique. Il suffit de “brancher” les flows sur le Node Chart. Le module Dashboard se charge de créer une donnée pour chaque payload entrant. Il faut essayer de mettre des mesures avec une plage assez proche (ou encore mieux de même nature) pour que le rendu soit correct.

Les autres paramètres du Node Chart :

Ce qui donne le graphique suivant

Zone de texte et notification furtive

Nous allons terminé la présentation du module Dashboard avec l’affichage d’un texte dans un champ et dans une notification furtive. Commençons par préparer la chaine de texte à afficher

Assembler plusieurs payload en une seule chaine de caractère

Node-RED est un système asynchrone, c’est à dire que les opérations ne se terminent pas forcément en même temps. Dans le cas présent (oui j’aurais pu le faire autrement, mais c’est un problème récurrent de Node-RED), j’ai extrait la température et l’humidité séparément. C’est nécessaire pour afficher simplement la mesure dans une jauge, mais ça ne nous arrange pas pour afficher le tout dans une notification. Voici comment faire.

Dans chaque filtre, j’ai ajouté un topic (par exemple température et humidity). On créé une variable de context; A chaque fois qu’un payload se présente dans le Node, on test le topic et on range la valeur dans l’objet de context. Ensuite on test si le context contient une valeur pour la température et l’humidité (et si elle n’est pas undefined). Si c’est le cas, on construit une chaine correctement formatée qu’il ne suffira plus qu’à afficher. Par exemple Température : 21.4°C – Humidité : 52.3%.

context.data = context.data || new Object();

switch (msg.topic) {
    case "Temperature":
        context.data.temperature = msg.payload;
        msg = null;
        break;
    case "Humidity":
        context.data.humidity = msg.payload;
        msg = null;
        break;
    default:
        msg = null;
        break;

}

if(context.data.temperature !== null && context.data.humidity !== null && context.data.temperature !== undefined && context.data.humidity !== undefined) {
    msgOut = ""; //new Object();
    msgOut = "Température : " 
    msgOut += context.data.temperature.toString(); 
    msgOut+= "°C - Humidité : "; 
    msgOut+= context.data.humidity.toString();
    msgOut+= "%";
    context.data=null;
    var msg = {};
    msg.payload = msgOut;
    return msg;
}

Afficher un texte sur le Dashboard

Le Node Text permet d’afficher très simplement du texte contenu dans un payload. On le configure comme ceci :

Ce qui donne

Afficher une notification furtive

Nous allons terminer ce tutoriel par la notification furtive. On peut choisir parmi 4 positions :

Remarque. Sur tablette, smartphone ou si la fenêtre du navigateur est réduite, le message est affiché en bas de l’écran (sur toute la largeur).

On définit également la durée d’apparition du message furtif. Par défaut, 3 secondes.

Ce qui donne pour terminer un affichage plutôt sympa !

Créer un widget personnalisé avec le node template HTML / Angular

Pour en savoir plus sur la création de widget avec du code HTML / Angular, lisez cet article détaillé

Code complet du flow Node-RED

Importez simplement ce code dans un flow si vous ne voulez pas réaliser toutes les étapes. Ce flow contient également la 1ère partie de ce tutoriel.

 

[{"id":"6eecf682.454f38","type":"ui_button","z":"df9159f.e304ea8","name":"Bouton","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"label":"Bouton","color":"#fffff","icon":"fa-star","payload":"true","payloadType":"bool","topic":"Button","x":360,"y":100,"wires":[["1e96adb5.fd25e2"]]},{"id":"2a0c052c.dfe4ca","type":"ui_dropdown","z":"df9159f.e304ea8","name":"Liste de choix","label":"Choisissez ce que vous voulez","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"options":[{"label":"Choix 1 : chaine","value":"Choix1","type":"str"},{"label":"Choix 2 : numérique","value":4,"type":"num"},{"label":"Choix 3 : bool","value":true,"type":"bool"}],"payload":"","topic":"Liste de choix","x":340,"y":140,"wires":[["1e96adb5.fd25e2"]]},{"id":"61be9b53.3a5ff4","type":"debug","z":"df9159f.e304ea8","name":"Dashboard Log","active":true,"console":"false","complete":"payload","x":900,"y":240,"wires":[]},{"id":"e7869632.cb19b8","type":"ui_switch","z":"df9159f.e304ea8","name":"Interrupteur","label":"switch","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"topic":"Interrupteur","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":350,"y":180,"wires":[["1e96adb5.fd25e2"]]},{"id":"6f4d5597.73fb0c","type":"ui_slider","z":"df9159f.e304ea8","name":"Slider","label":"slider","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"topic":"Slider","min":0,"max":10,"step":1,"x":370,"y":220,"wires":[["1e96adb5.fd25e2"]]},{"id":"93c06deb.61b61","type":"ui_numeric","z":"df9159f.e304ea8","name":"","label":"numeric","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"topic":"Numérique","format":"{{value}}","min":0,"max":10,"x":360,"y":260,"wires":[["1e96adb5.fd25e2"]]},{"id":"8f5cb4d9.8208a8","type":"ui_text_input","z":"df9159f.e304ea8","name":"","label":"Champ saisie de Texte","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"mode":"text","delay":"0","topic":"Champ saisie de Texte","x":320,"y":300,"wires":[["1e96adb5.fd25e2"]]},{"id":"3375a2e.57b475e","type":"ui_form","z":"df9159f.e304ea8","name":"","label":"Un formulaire Node-RED","group":"febe591f.8ca1f8","order":0,"width":0,"height":0,"options":[{"label":"Du texte","value":"Texte","type":"text","required":true},{"label":"Un nombre","value":"Nombre","type":"number","required":false},{"label":"Un email","value":"email","type":"email","required":false},{"label":"Un mot de passe","value":"Mot de passe","type":"password","required":false},{"label":"Une case à cocher","value":"Case à cocher","type":"checkbox","required":false},{"label":"Un interrupteur","value":"Interrupteur","type":"switch","required":false}],"formValue":{"Texte":"","Nombre":"","email":"","Mot de passe":"","Case à cocher":false,"Interrupteur":false},"payload":"","topic":"Formulaire","x":310,"y":460,"wires":[["1e96adb5.fd25e2"]]},{"id":"1e96adb5.fd25e2","type":"function","z":"df9159f.e304ea8","name":"Enregistre les événements","func":"// Créé une variable pour stocker le journal du dashboard si inexistante\n// initialise the counter to 0 if it doesn't exist already\nvar dashboardLog = context.get('dashboardLog')|| [];\n\ndashboardLog.push(msg);\nif (dashboardLog.length > 20){\n    // Supprime le plus anciens message si > 20\n    // Delete oldest message if > 20\n    dashboardLog.shift();\n    dashboardLog.length = 20;\n} \n\n// Enregistre les messages du dashboard pour le prochain affichage\n// store the value back\ncontext.set('dashboardLog',dashboardLog);\n\n// Affiche le journal des messages\n// make it part of the outgoing msg object\nmsg = {};\nmsg.payload = dashboardLog;\nreturn msg;\n","outputs":1,"noerr":0,"x":660,"y":280,"wires":[["61be9b53.3a5ff4","7a421874.47f638"]]},{"id":"7a421874.47f638","type":"ui_template","z":"df9159f.e304ea8","group":"842b8d23.22294","name":"Journal des événement du Dashboard","order":1,"width":"8","height":"10","format":"<ul>\n <li ng-repeat=\"x in msg.payload\">\n <font color=\"red\">{{x.topic}}</font>\n    <ul>\n        <li>{{x.payload}}</li>\n    </ul>\n </li>\n</ul>","storeOutMessages":true,"fwdInMessages":true,"x":970,"y":320,"wires":[[]]},{"id":"87bf88d.1fbd678","type":"ui_text_input","z":"df9159f.e304ea8","name":"","label":"Champ saisie email","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"mode":"email","delay":300,"topic":"Champ saisie email","x":330,"y":340,"wires":[["1e96adb5.fd25e2"]]},{"id":"55e7b58f.cafe6c","type":"ui_text_input","z":"df9159f.e304ea8","name":"","label":"Champ saisie mot de passe","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"mode":"password","delay":300,"topic":"Champ saisie mot de passe","x":300,"y":380,"wires":[["1e96adb5.fd25e2"]]},{"id":"21feb1b7.018a5e","type":"ui_text_input","z":"df9159f.e304ea8","name":"","label":"Sélecteur de couleur","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"passthru":true,"mode":"color","delay":300,"topic":"Sélecteur de couleur","x":320,"y":420,"wires":[["1e96adb5.fd25e2"]]},{"id":"baf63f2d.83977","type":"ui_text","z":"df9159f.e304ea8","group":"67f72709.c415f8","order":0,"width":0,"height":0,"name":"","label":"Dernière mesure","format":"{{msg.payload}}","layout":"row-spread","x":1140,"y":820,"wires":[]},{"id":"1d7d4ce7.8a5523","type":"ui_toast","z":"df9159f.e304ea8","position":"top right","displayTime":"5","name":"Notification","x":1130,"y":780,"wires":[]},{"id":"5e686a19.a16694","type":"ui_ui_control","z":"df9159f.e304ea8","name":"ui control","x":900,"y":500,"wires":[[]]},{"id":"4bb4277.686a0d8","type":"ui_button","z":"df9159f.e304ea8","name":"","group":"2a5abbd3.afa284","order":0,"width":0,"height":0,"label":"Aller aux capteurs MySensors","color":"","icon":"","payload":"","payloadType":"str","topic":"Vers Tab capteurs MySensors","x":310,"y":500,"wires":[["1e96adb5.fd25e2","ae9daf53.dbc43"]]},{"id":"ae9daf53.dbc43","type":"function","z":"df9159f.e304ea8","name":"Aller à MySensors","func":"var msg = {};\nmsg.payload = {tab:\"MySensors\"};    // ou/or 1\n\n\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":500,"wires":[["5e686a19.a16694"]]},{"id":"3d21e1ce.01afee","type":"tcp in","z":"df9159f.e304ea8","name":"MySensors Gateway","server":"client","host":"192.168.1.20","port":"5003","datamode":"stream","datatype":"utf8","newline":"","topic":"","base64":false,"x":190,"y":640,"wires":[["4fc18f88.1911"]]},{"id":"4fc18f88.1911","type":"function","z":"df9159f.e304ea8","name":"Decode MySensor Message","func":"/* MySensors v2 Message Decoder\n*  Payload : JSON object\n*  www.projetsdiy.fr - oct. 2016\n*/\nvar mySensorsMessage = {}\nvar newPayload = {};\nvar timestamp = new Date();\nvar message = msg.payload.toString();\nmessage = message.replace(/(\\r\\n|\\n|\\r)/gm, \"\");\nvar tokens = message.split(\";\")\nif(tokens.length == 6)\n{\n    mySensorsMessage.nodeId =       parseInt(tokens[0]);\n    mySensorsMessage.childSensorId= parseInt(tokens[1]);\n    mySensorsMessage.messageType =  parseInt(tokens[2]);\n    mySensorsMessage.ack =          parseInt(tokens[3]);\n    mySensorsMessage.subType =      parseInt(tokens[4]);\n    mySensorsMessage.value =        Number(tokens[5]);\n\n    var messageType = mySensorsMessage.messageType;\n    var subType = mySensorsMessage.subType;\n    var labelPresentation = [\"S_DOOR\",\"S_MOTION\",\"S_SMOKE\",\"S_LIGHT\",\"S_BINARY\",\"S_DIMMER\",\"S_COVER\",\"S_TEMP\",\"S_HUM\",\"S_BARO\",\"S_WIND\",\"S_RAIN\",\"S_UV\",\"S_WEIGHT\",\"S_POWER\",\"S_HEATER\",\"S_DISTANCE\",\"S_LIGHT_LEVEL\",\"S_ARDUINO_NODE\",\"S_ARDUINO_REPEATER_NODE\",\"S_LOCK\",\"S_IR\",\"S_WATER\",\"S_AIR_QUALITY\",\"S_CUSTOM\",\"S_DUST\",\"S_SCENE_CONTROLLER\",\"S_RGB_LIGHT\",\"S_RGBW_LIGHT\",\"S_COLOR_SENSOR\",\"S_HVAC\",\"S_MULTIMETER\",\"S_SPRINKLER\",\"S_WATER_LEAK\",\"S_SOUND\",\"S_VIBRATION\",\"S_MOISTURE\",\"S_INFO\",\"S_GAS\",\"S_GPS\",\"S_WATER_QUALITY\"];\n    var labelSet = [\"V_TEMP\",\"V_HUM\",\"V_STATUS\",\"V_LIGHT\",\"V_PERCENTAGE\",\"V_DIMMER\",\"V_PRESSURE\",\"V_FORECAST\",\"V_RAIN\",\"V_RAINRATE\",\"V_WIND\",\"V_GUST\",\"V_DIRECTION\",\"V_UV\",\"V_WEIGHT\",\"V_DISTANCE\",\"V_IMPEDANCE\",\"V_ARMED\",\"V_TRIPPED\",\"V_WATT\",\"V_KWH\",\"V_SCENE_ON\",\"V_SCENE_OFF\",\"V_HVAC_FLOW_STATE\",\"V_HVAC_SPEED\",\"V_LIGHT_LEVEL\",\"V_VAR1\",\"V_VAR2\",\"V_VAR3\",\"V_VAR4\",\"V_VAR5\",\"V_UP\",\"V_DOWN\",\"V_STOP\",\"V_IR_SEND\",\"V_IR_RECEIVE\",\"V_FLOW\",\"V_VOLUME\",\"V_LOCK_STATUS\",\"V_LEVEL\",\"V_VOLTAGE\",\"V_CURRENT\",\"V_RGB\",\"V_RGBW\",\"V_ID\",\"V_UNIT_PREFIX\",\"V_HVAC_SETPOINT_COOL\",\"V_HVAC_SETPOINT_HEAT\",\"V_HVAC_FLOW_MODE\",\"V_TEXT\",\"V_CUSTOM\",\"V_POSITION\",\"V_IR_RECORD\",\"V_PH\",\"V_ORP\",\"V_EC\",\"V_VAR\",\"V_VA\",\"V_POWER_FACTOR\"]\n    var labelInternal = [\"I_BATTERY_LEVEL\",\"I_TIME\",\"I_VERSION\",\"I_ID_REQUEST\",\"I_ID_RESPONSE\",\"I_INCLUSION_MODE\",\"I_CONFIG\",\"I_FIND_PARENT\",\"I_FIND_PARENT_RESPONSE\",\"I_LOG_MESSAGE\",\"I_CHILDREN\",\"I_SKETCH_NAME\",\"I_SKETCH_VERSION\",\"I_REBOOT\",\"I_GATEWAY_READY\",\"I_REQUEST_SIGNING\",\"I_GET_NONCE\",\"I_GET_NONCE_RESPONSE\",\"I_HEARTBEAT\",\"I_PRESENTATION\",\"I_DISCOVER\",\"I_DISCOVER_RESPONSE\",\"I_HEARTBEAT_RESPONSE\",\"I_LOCKED\",\"I_PING\",\"I_PONG\",\"I_REGISTRATION_REQUEST\",\"I_REGISTRATION_RESPONSE\",\"I_DEBUG\"]\n    \n    switch (messageType) {\n        case 0:     // Presentation\n            newPayload.timestamp = timestamp;\n            newPayload.mode =       \"Presentation\";\n            newPayload.type =       labelPresentation[subType];\n            break;\n        case 1:     // Set\n            newPayload.timestamp = timestamp;\n            newPayload.nodeId=      mySensorsMessage.nodeId;\n            newPayload.sensorId=    mySensorsMessage.childSensorId;\n            newPayload.mode=        \"Set\";\n            newPayload.type=        subType;\n            newPayload.typeLabel=   labelSet[subType];\n            newPayload.value=       mySensorsMessage.value;\n            break;\n        case 2:     // Req\n            newPayload.timestamp = timestamp;\n            newPayload.nodeId=      mySensorsMessage.nodeId;\n            newPayload.sensorId=    mySensorsMessage.childSensorId;\n            newPayload.mode=        \"Req\";\n            newPayload.type=        subType;\n            newPayload.typeLabel=   labelSet[subType];\n            newPayload.value=       mySensorsMessage.value;\n            break;  \n        case 3:     // Internal\n            newPayload.timestamp = timestamp;\n            newPayload.nodeId=      mySensorsMessage.nodeId;\n            newPayload.sensorId=    mySensorsMessage.childSensorId;\n            newPayload.mode=        \"Internal\";\n            newPayload.type=        subType;\n            newPayload.typeLabel=   labelInternal[subType];\n            newPayload.value=       mySensorsMessage.value;\n            break;    \n        case 4:     // Stream - OTA firmware update\n            newPayload.timestamp = timestamp;\n            newPayload.nodeId=      mySensorsMessage.nodeId;\n            newPayload.mode=        \"stream\";\n            break;\n        default:\n            break;\n    }\n\n    msg.payload = newPayload; \n} else {\n    msg.payload = \"Error! Nothing to decode\"\n}  \n\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":560,"wires":[["e32665a5.08e548","ff9b32b9.a232c"]]},{"id":"e32665a5.08e548","type":"function","z":"df9159f.e304ea8","name":"Filtre : température noeud 3","func":"if (msg.payload.nodeId == 3 && msg.payload.type === 0) {\n    var msg;\n    msg.payload = msg.payload.value;\n    msg.topic = \"Temperature\"\n    return msg;\n}    ","outputs":1,"noerr":0,"x":640,"y":620,"wires":[["3f202da1.ad8562","a1e15601.1df708","f89448e5.9519d8"]]},{"id":"3f202da1.ad8562","type":"ui_gauge","z":"df9159f.e304ea8","name":"Gauge : Température","group":"67f72709.c415f8","order":0,"width":0,"height":0,"gtype":"gage","title":"Température DHT22","label":"MySensors v2","format":"{{value}}°C","min":0,"max":"50","colors":["#66ccff","#ff8000","#ca3838"],"x":940,"y":600,"wires":[]},{"id":"ff9b32b9.a232c","type":"function","z":"df9159f.e304ea8","name":"Filtre : humidité noeud 3","func":"if (msg.payload.nodeId == 3 && msg.payload.type === 1) {\n    var msg;\n    msg.payload = msg.payload.value;\n    msg.topic = \"Humidity\"\n    return msg;\n}    ","outputs":1,"noerr":0,"x":630,"y":660,"wires":[["cdcc69de.3c1538","a1e15601.1df708","f89448e5.9519d8"]]},{"id":"cdcc69de.3c1538","type":"ui_gauge","z":"df9159f.e304ea8","name":"Gauge : Humidité","group":"67f72709.c415f8","order":0,"width":"0","height":"0","gtype":"gage","title":"Humidité DHT22","label":"MySensors v2","format":"{{value}}%","min":0,"max":"100","colors":["#1a25ab","#e6e600","#ca3838"],"x":930,"y":640,"wires":[]},{"id":"a1e15601.1df708","type":"function","z":"df9159f.e304ea8","name":"Attendre temperature & humidité","func":"context.data = context.data || new Object();\n\nswitch (msg.topic) {\n    case \"Temperature\":\n        context.data.temperature = msg.payload;\n        msg = null;\n        break;\n    case \"Humidity\":\n        context.data.humidity = msg.payload;\n        msg = null;\n        break;\n    default:\n        msg = null;\n    \tbreak;\n\n}\n\nif(context.data.temperature !== null && context.data.humidity !== null && context.data.temperature !== undefined && context.data.humidity !== undefined) {\n\tmsgOut = \"\"; //new Object();\n    msgOut = \"Température : \" \n    msgOut += context.data.temperature.toString(); \n    msgOut+= \"°C - Humidité : \"; \n    msgOut+= context.data.humidity.toString();\n    msgOut+= \"%\";\n    context.data=null;\n    var msg = {};\n    msg.payload = msgOut;\n\treturn msg;\n} \n//else return msg;","outputs":1,"noerr":0,"x":980,"y":720,"wires":[["1d7d4ce7.8a5523","baf63f2d.83977"]]},{"id":"f89448e5.9519d8","type":"ui_chart","z":"df9159f.e304ea8","name":"Graph : Température & Humidité","group":"45ccf5ba.b188ac","order":0,"width":"6","height":"9","label":"Température & Humidité","chartType":"line","legend":"true","xformat":"%H:%M","interpolate":"linear","nodata":"Rien à afficher","ymin":"0","ymax":"80","removeOlder":"12","removeOlderUnit":"3600","x":970,"y":680,"wires":[[],[]]},{"id":"2a5abbd3.afa284","type":"ui_group","z":"","name":"Eléments d'entrée","tab":"99f501d2.56c31","order":1,"disp":true,"width":"8"},{"id":"febe591f.8ca1f8","type":"ui_group","z":"","name":"Formulaire","tab":"99f501d2.56c31","order":2,"disp":true,"width":"8"},{"id":"842b8d23.22294","type":"ui_group","z":"df9159f.e304ea8","name":"Journal des événements du Dashboard","tab":"99f501d2.56c31","order":3,"disp":true,"width":"8"},{"id":"67f72709.c415f8","type":"ui_group","z":"","name":"Mesures","tab":"70b0ee04.be689","order":1,"disp":true,"width":"6"},{"id":"45ccf5ba.b188ac","type":"ui_group","z":"","name":"Graphiques","tab":"70b0ee04.be689","order":2,"disp":true,"width":"6"},{"id":"99f501d2.56c31","type":"ui_tab","z":"","name":"Ecran Principal","icon":"home","order":2},{"id":"70b0ee04.be689","type":"ui_tab","z":"","name":"MySensors","icon":"dashboard","order":3}]
Avez-vous aimé cet article ?
[Total: 1 Moyenne: 5]
Quitter la version mobile