Page 1 sur 2

[Résolu] Node RED : Recherche fonction

Publié : 27 janv. 2020, 08:37
par Gaz
Bonjour,
Je suis totalement novice dans node red et j'aimerais envoyer 3 valeurs (pour le moment) dans Domoticz via MQQTT sur des dummy spécifiques.
Je suis à la recherche d'une fonction qui me permet de d'exploiter les données recut dans le payload pour les envoyer sur le bon device de Domoticz.

Voici comment arrivent les données :

Code : Tout sélectionner

 
balance1/poids : msg : Object
object
topic: "balance1/poids"
payload: "-10.53↵22.1↵48.0↵"
qos: 0
retain: false
_topic: "balance1/poids"
_msgid: "7e6adb74.a3b8a4" 
J'ai mis un split pour decomposer les données, cela m'a bien permis d'avoir 3 payload avec les 3 valeurs différentes :

Code : Tout sélectionner

27/01/2020 à 08:14:28node: console debug 2
balance1/poids : msg : Object
object
topic: "balance1/poids"
payload: "-10.53 "
qos: 0
retain: false
_topic: "balance1/poids"
parts: object
_msgid: "f05be4e8.267c88"

27/01/2020 à 08:14:28node: console debug 2
balance1/poids : msg : Object
object
topic: "balance1/poids"
payload: "22.1 "
qos: 0
retain: false
_topic: "balance1/poids"
parts: object
_msgid: "928245d8.175368"

27/01/2020 à 08:14:28node: console debug 2
balance1/poids : msg : Object
object
topic: "balance1/poids"
payload: "47.9 "
qos: 0
retain: false
_topic: "balance1/poids"
parts: object
_msgid: "66df6983.1b1f18"
Je pense que maintenant, j'ai besoin d'une fonction avec un bout de code, mais je ne trouve pas d'exemple, ou j'utilise pas les bon termes dans mes recherches.

Avez-vous des pistes ? Merci d'avance.

Re: Node RED : Recherche fonction

Publié : 28 janv. 2020, 20:53
par Jeff
Tu peux essayer une fonction comme cela suivi par un bloc "http" avant envoi :

Code : Tout sélectionner

msg.url = "http://192.168.1.200:8080/json.htm?type=command&param=udevice&idx=177&nvalue=0&svalue="+msg.payload;
return msg;
Tu peux aussi conditionner mais à mon avis ton split doit changer le nom du topic ou du payload pour conditionner sur quel device tu envois la valeur

Code : Tout sélectionner

//msg.payload = msg.payload.weather;

var str = String(msg.payload.weather);

if ((msg.payload = str.indexOf("Clear") === 0) || (msg.payload = str.indexOf("Sunny") === 0))
{
var url= "http://192.168.1.103/control?cmd=NEXTION,q0.picc=1";
}

else if ((msg.payload = str.indexOf("Overcast") === 0) || (msg.payload = str.indexOf("Cloudy") === 0))
{
var url= "http://192.168.1.103/control?cmd=NEXTION,q0.picc=2";
}

Re: Node RED : Recherche fonction

Publié : 29 janv. 2020, 08:17
par Gaz
Merci Jeff pour ce debut.
J'ai regardé rapidement ce que tu m'a proposé, la premiere solution fonctionne mais cela envoi que la premiere valeur du payload (-10.53) c'est déjas super. Je suppose qu'il doit bien detecter qu'il y a plusieurs valeurs puisque il fait un decoupage.
Dans la même idée est il possible de lui dire d'envoyer par exemple la valeur comprise entre " et ↵ puis entre ↵et ↵ sur une autre device puis ↵ et ↵" ?

Pour la deuxième solution, je vais re-regarder ce soir, pour le moment j'ai pas réussi à sortir quelque chose.

Re: Node RED : Recherche fonction

Publié : 29 janv. 2020, 21:47
par Jeff
Bien content que tu ai réussi un envoi simple.
Ton Split a 3 sorties ?

Re: Node RED : Recherche fonction

Publié : 29 janv. 2020, 22:17
par Gaz
Oui 3 sorties dans le debug de Node Red mais une sortie sur le dessin.
split.png
split.png (36.54 Kio) Consulté 7572 fois
debug.png
debug.png (119 Kio) Consulté 7572 fois
Properties Split.png
Properties Split.png (98.13 Kio) Consulté 7572 fois

Re: Node RED : Recherche fonction

Publié : 30 janv. 2020, 12:28
par domcars0
Salut,
Comme tu utilises Node red tu peux y ajouter un broker MQTT (puisque tu veux faire du MQTT) sur lequel ton domoticz viendra se connecter. Avec cela il devient inutile de faire des requêtes http vers ton serveur domoticz et avoir ainsi un pur service MQTT.

Exemple d'un broker nodered sur lequel est connecté domoticz:
MQTTDomoticz.png
MQTTDomoticz.png (59.92 Kio) Consulté 7540 fois
Voici par exemple le code de la fonction Temp/Hum/Baro :

Code : Tout sélectionner

/*** Set your Domoticz Sensor IDX here ***/
var outTemp_idx = 8 ; //95
/*** END Configuration ****/



var weather =msg.payload;
var newMsg;

// console.log(weather);
if ( weather.outTemp_C === undefined || outTemp_idx === null )
    return null;

var baro = parseFloat(weather.barometer_mbar).toFixed(2);
var humidity = parseFloat(weather.outHumidity).toFixed(1);
var temp = parseFloat(weather.outTemp_C).toFixed(1);
var battery = parseInt(weather.outTempBatteryStatus);
var humstat;

switch ( battery ) {
    case 0:
        battery = 100;
        break;
    default:
        battery = 10;
        break;
}

if ( 35 < humidity && humidity < 55 )
    humstat = 1;
else if ( 25 <= humidity && humidity  <= 65 )
    humstat = 0;
else if ( humidity < 25 )
    humstat = 2;
else if (humidity > 65 )
    humstat = 3;
    
//console.log('out Temp = ' + weather.outTemp_C);
//console.log('Out Humidity = '+  weather.outHumidity);
//console.log('Barometer = '+  weather.barometer_mbar);
// Format de sValue = Temp;HUm;Hum_Stat;Bar;Prevision (see https://www.domoticz.com/wiki/MQTT)
newMsg = {'command': 'udevice','idx' : outTemp_idx,'battery': battery,'nvalue' : 0, 'svalue':temp+';'+humidity+';'+humstat+';'+baro+';0' };
var outTemp = {"payload" : newMsg };
return outTemp;

Il faut bien sûr également configurer un materiel de type Client-MQTT sur ton Domoticz
ConfDomoticzMQTT.png
ConfDomoticzMQTT.png (40.17 Kio) Consulté 7528 fois
Si tes 3 valeurs de sortie du SPLIT vont vers le même device Domoticz ça ne pose pas de problème. Tu crées une fonction qui va récupérer chaque valeur et l'envoyer vers le device (voir l'exemple de Temp/Hum/Baro) (en trois flux distinct) .
C'est plus compliqué si chaque valeur va vers un device dédié car apparemment on ne peut pas distinguer (par une caractéristique qui lui serait propre) les 3 sorties les une des autres :-(
Je me demande dans ce cas si il ne serait pas plus judicieux de garder le message d'origine (avec les 3 valeurs séparées par un <ret-char>) et de splitter cette valeur toi même dans une fonction dans laquelle tu peut alors parfaitement distinguer chacune des 3 valeurs et les envoyer vers le device adéquat. (Chu pas sur de bien me faire comprendre ? :-( )

Re: Node RED : Recherche fonction

Publié : 30 janv. 2020, 19:44
par Gaz
Merci beaucoup domcars0,
la partie MQTT est déjas en place et fonctionne parfaitement, je ne l'avais pas précisé et je te remercie de l'avoir expliqué, cela pourra servir à d'autre.

Je vais effectivement essayer ton code, c'est une piste.
C'est plus compliqué si chaque valeur va vers un device dédié car apparemment on ne peut pas distinguer (par une caractéristique qui lui serait propre) les 3 sorties les une des autres :-(
Et c'est effectivement mon cas, 3 valeurs pour 3 devices différents.
Je me demande dans ce cas si il ne serait pas plus judicieux de garder le message d'origine (avec les 3 valeurs séparées par un <ret-char>) et de splitter cette valeur toi même dans une fonction dans laquelle tu peut alors parfaitement distinguer chacune des 3 valeurs et les envoyer vers le device adéquat. (Chu pas sur de bien me faire comprendre ? :-( )
Cette option me plais bien. C'est quoi le <ret-char> ?
As tu aussi un exemple pour cette fonction de split ? Je pense que ma solution est bien là.

Re: Node RED : Recherche fonction

Publié : 31 janv. 2020, 14:22
par domcars0
Ce que j’appelle le <ret-char> c'est le "retour chariot" , ce que tu appelles me semble t'il "↵".
En javascript le split exist c'est la methode string.split().

T'as essayé un truc du genre :
var str = msg.payload;
var result = str.split('↵'); // Je suis pas sur que javascript va accepter ce caractère zarbi ↵
console.log('Valeurs = '+result[0]+' , '+result[1]+' , '+result[2]);
Si ça marche , le reste est simple , on envoie result[0] vers le device A , result[1] vers le device B et result[2] vers le device C;
en regardant le format du message à envoyer vers ces devices (see https://www.domoticz.com/wiki/MQTT) ,

Probablement un truc du genre
newMsg = {'command': 'udevice','idx' : deviceA_idx,','nvalue' : 0, 'svalue':result[0] };
var outTemp = {"payload" : newMsg };
return outTemp;

En ecrivant ce bout de code je constate que probablement tu risques d'avoir besoin de 3 "fonctions". La premiere renverra result[0] vers device A, la seconde result[1] vers device B et la 3eme result[2] vers device C? A moins qu'il y ai un moyen d'envoyer 3 payload sur une même sortie ? Je connais pas bien nodered.

Re: Node RED : Recherche fonction

Publié : 31 janv. 2020, 20:55
par Gaz
Alors ça avance pas vite mais ça avance :D
Ton code me sortais rien, mais certainement un problème de language car pas d'erreur.
var str = msg.payload;
var result = str.split('↵'); // Je suis pas sur que javascript va accepter ce caractère zarbi ↵
console.log('Valeurs = '+result[0]+' , '+result[1]+' , '+result[2]);
Mais grace à toi j'ai fait ceci dans une fonction et j'ai mis 3 sorties :

Code : Tout sélectionner

var output = msg.payload.split("\r\n")

var A = parseInt(output[0]);
var B = parseInt(output[1]);
var C = parseInt(output[2]);
var msg1 = {payload:A};
var msg2 = {payload:B};
var msg3 = {payload:C};
return [ msg1, msg2, msg3 ];

1.png
1.png (117.72 Kio) Consulté 7463 fois
J'ai bien une valeur par sortie mais ça split après la virgule, là je comprend pas !
Une idée ?

Re: Node RED : Recherche fonction

Publié : 01 févr. 2020, 00:52
par domcars0
Qu'entends tu par "ça split après la virgule"?
Les valeurs me semblent tout à fait correctes?
Ah je viens de comprendre , tu veux dire que ça vire les decimales? C'est normal, pourquoi castes tu (parseInt) les sorties de string vers int (entier)?


Il te reste plus qu'à construire les message de sortie.

Je ne savais pas que le broker MQTT acceptait des tableaux de msg, finalement une seule fonction suffit!