Décodage trame Dragino LHT52 (Sonde Temp & Hum.) via Node Red

Bonjour,

J’essaie de mon monter un réseau lora privatif avec une Gateway RAK7268V2 et je démarre avec une sonde Dragino LHT52.
Pour la partie Lora, tout est ok, je reçois bien les trames et elles sont transférées à HA via MQTT.
Là où je bloque, c’est pour leur décodage…
De ce que j’ai compris la trame avec fPort=2 contient les données, en voici un exemple :

applicationID: « 1 »
applicationName: « draginolht52 »
devEUI: « xxxxxxxxxxxxxxxxx »
deviceName: « draginolht52 »
timestamp: 1761949127
fCnt: 1
fPort: 2
data: « B9QCk3//AWkFNcU= »
data_encode: « base64 »
object: object
adr: true
rxInfo: array\[1\]

D’après ce que j’ai lu et compris, on peut s’appuyer sur le code que fourni Dragino :

J’ai pris le contenu du fichier decoder Chirpstack pour le mettre dans ma fonction NodeRed


Seul souci, au moment du décodage dans le Java script, le code attent 11 bytes de data alors que j’en ai 16 :face_with_raised_eyebrow:
J’ai tenté d’envoyer les 16 bytes dans le décodage… mais le résultat est loin d’être satisfaisant :frowning:
2e souci, ce code fait appel à une fonction « str_pad » que je ne sais comment l’ajouter à mon NodeRed.

En cherchant sur divers forum, j’ai vu que Dragino fournissait un flux json tout fait ici :

Mais quand je l’importe puis le lance, cela bloque car il manque la définition de pas mal de fonctions.

Dernière tentative, je vois dans le mode d’emploi :

Que l’on peut faire le décodage à la main mais mes valeurs ne me semblent pas cohérentes : pas le même nombre de digits…

Bref, je patauge un peu, en bon débutant que je suis :sweat_smile:
Si une bonne âme peut m’aider, cela serait top !

D’avance Merci bcp
Laurent

Bonjour ,

Je m’étais renseigné il y a quelques temps pour une potentielle installation d’un réseau Lora privé, projet finalement avorté mais j’avais pas mal potassé le sujet.

De mémoire, le decoder fourni par le fabricant, ici Dragino, n’est pas directement utilisable dans un nœud fonction Node Red, il faut l’adapter.

Je n’y connais presque rien en code, donc j’ai été demander de l’aide à l’IA qui a adapté le code pour le mettre dans le nœud fonction, et j’ai testé avec le message MQTT que tu as envoyé. Voilà le rendu que j’obtiens :

{
  "TempC_SHT": 20.04,        ==> semble OK
  "Hum_SHT": 65.9,           ==> semble OK
  "TempC_DS": 327.67,        ==> valeur par défaut d'un capteur interne non utlisé ?
  "Ext": 1,
  "Systimestamp": 1761949125,  ==> soit le vendredi 31 octobre 2025 23:18:45
  "Node_type": "LHT52"        ==> semble OK
}

Est-ce que le résultat obtenu te semble cohérent ?
Si oui je te partagerai le code que notre ami l’IA nous a généré pour ta fonction.

1 « J'aime »

Salut

Alors normalement tout dépend du serveur Lora que tu utilises mais normalement tu peux importer le javascript de décodage fourni par Dragino directement dans le serveur Lora et comme ça tu récupéres en MQTT des données en clair et ensuite un simple template sensor fait le bout :slight_smile:

Vincèn

Bonjour Integra,

Tu m’intéresses :blush: car les données semblent bonnes !
Et TempC_DS, ca doit etre pour la sonde externe en doigt de gant qui n’est pas utilisée :wink:

Bien entendu, je suis intéressé par le code généré mais aussi comment tu as formulé ta requête IA :wink:

Hate de te lire !
Laurent

Bonjour @LaurentLaBricole,

Désolé pour cette réponse tardive, je n’étais pas disponible de la journée.

Oui elles me semblaient cohérentes en tout cas, donc le decoder doit être bon.

Et en effet j’en étais arrivé à la même conclusion, capteur non utilisé donc valeur par défaut => 327,67°C pour TempC_DS.

Alors pour convertir le decoder en format utilisable dans Node Red, j’ai d’abord demandé à ChatGPT, il m’a bien converti le code mais les valeurs étaient comment dire… hautement improbables… (657°C). Idem avec Le Chat.

Avant de rentrer plus en profondeur dans le code proposé pour essayer de comprendre et d’abandonner rapidement devant mes lacunes en code, j’ai demandé à Grok et là du premier coup ça fonctionnait.

Prompt classique du style : Voici un code utilisable dans Chrisptack pour décoder des data d’un message MQTT, adapte moi ce code pour une utilisation dans un noeud fonction de Node Red

À noter, j’ai utilisé le decoder au format .txt pour Chirpstack que tu as ciblé dans ton premier lien.

Sans plus de suspens voici le code que tu peux essayer dans ta fonction sous Node Red pour obtenir les valeurs des fPorts 2, 3, 4 et 5 :

// Fonction helper pour padding hex (inchangée)
function str_pad(byte) {
    var zero = '0';
    var hex = byte.toString(16);
    var tmp = 2 - hex.length;
    return zero.substr(0, tmp) + hex;
}

// Fonction de décodage adaptée (similaire à l'original, mais sans variables inutilisé)
function Decode(fPort, bytes) {
    var decode = {};
    if (fPort == 2) {
        if (bytes.length == 11) {
            decode.TempC_SHT = parseFloat(((bytes[0] << 24 >> 16 | bytes[1]) / 100).toFixed(2));
            decode.Hum_SHT = parseFloat(((bytes[2] << 24 >> 16 | bytes[3]) / 10).toFixed(1));
            decode.TempC_DS = parseFloat(((bytes[4] << 24 >> 16 | bytes[5]) / 100).toFixed(2));
            decode.Ext = bytes[6];
            decode.Systimestamp = (bytes[7] << 24 | bytes[8] << 16 | bytes[9] << 8 | bytes[10]);
            decode.Node_type = "LHT52";
            return decode;
        } else {
            decode.Status = "RPL data or sensor reset";
            decode.Node_type = "LHT52";
            return decode;
        }
    }
    if (fPort == 3) {
        decode.Status = "Data retrieved, your need to parse it by the application server";
        decode.Node_type = "LHT52";
        return decode;
    }
    if (fPort == 4) {
        decode.DS18B20_ID = str_pad(bytes[0]) + str_pad(bytes[1]) + str_pad(bytes[2]) + str_pad(bytes[3]) +
                            str_pad(bytes[4]) + str_pad(bytes[5]) + str_pad(bytes[6]) + str_pad(bytes[7]);
        decode.Node_type = "LHT52";
        return decode;
    }
    if (fPort == 5) {
        decode.Sensor_Model = bytes[0];
        decode.Firmware_Version = str_pad((bytes[1] << 8) | bytes[2]);
        decode.Freq_Band = bytes[3];
        decode.Sub_Band = bytes[4];
        decode.Bat_mV = bytes[5] << 8 | bytes[6];
        decode.Node_type = "LHT52";
        return decode;
    }
    // Cas par défaut si fPort non géré
    decode.Status = "fPort non supporté";
    return decode;
}

// Corps principal du nœud function
var payload = msg.payload; // L'objet JSON de l'uplink MQTT

if (payload && payload.data && payload.fPort) {
    // Décoder le base64 en Buffer, puis en tableau d'octets (uint8)
    var base64Data = payload.data;
    var buffer = Buffer.from(base64Data, 'base64');
    var bytes = Array.from(buffer); // Convertir en array pour compatibilité avec le code original
    
    var fPort = payload.fPort;
    
    // Appeler la fonction de décodage
    var decoded = Decode(fPort, bytes);
    
    // Remplacer msg.payload par les données décodées
    msg.payload = decoded;
} else {
    // Erreur si les champs requis manquent
    msg.payload = { error: "Données MQTT invalides (data ou fPort manquant)" };
}

return msg;
1 « J'aime »

Merci @Integra, cela fonctionne parfaitement !

J’ai juste un petit sujet autour de la création du sensor dans HA pour remonter Temp & Humidité.
Impossible de tout mettre dans le même capteur. Je pensais pouvoir le faire via les « attributs » du sensor mais ça ne veut pas.
J’ai donc fait de la découpe, 1 sensor par donnée et cela fonctionne très bien :partying_face:

Mille Merci à vous 2 ! @vincen @Integra

2 « J'aime »

Parfait excellente nouvelle !

Il n’y a pas de raison que tu ne puisses pas ajouter toutes les infos du capteur en attributs, en tout cas je ne vois rien sur le principe qui empêcherait cela :thinking: .

Si tu le souhaites n’hésite pas à partager le message décodé reçu par le broker MQTT et le sensor que tu as déclaré en conséquence,on pourra essayer de voir comment gérer les infos en attributs.

Sinon oui un sensor par valeur dans le pire des cas ça fonctionne également.