Theengs Gateway, utilisation en mode MQTTtoMQTT decoding avec un script Shelly

Bonjour,

J’utilise un script Shelly pour récupérer les publications bluetooth de mes ShellyBLU Button1.

//0.0.2 debug
let debug = false;
//let genTopic = 'shellies/script/bluetooth/';
let genTopic = 'TheengsGateway/undecoded/';
let uuidsBan = ['fe9f', 'fea0', 'fdf7', '3802'];
//let uuidsBan = ['fea0'];
let nutsName = {
                 "11:11:11:11:11:11": "Nut 01",
                 "22:22:22:22:22:22": "Nut 02",
                 "33:33:33:33:33:33": "Nut 03",
                 "44:44:44:44:44:44": "Nut 04",
                 "55:55:55:55:55:55": "Shelly Rouge",
                 "66:66:66:66:66:66": "Shelly Bleu",
                 "77:77:77:77:77:77": "Shelly Blanc",
                 "88:88:88:88:88:88": "Shelly Noir"
               };
let macList = Object.keys(nutsName);

function isMacValid(mac) {
  if (mac.length !== 17) {
    return false;
  }
  for (let i=0; i<17; i++) {
    if (i%3 === 2) {
      if (mac.at(i) !== 0x3a) { //0x3a = :
        return false;
      }
    } else {
      //0x30 = 0, 0x39 = 9, 0x61 = a et 0x66 = f
      if (mac.at(i) < 0x30 || (mac.at(i) > 0x39 && mac.at(i) < 0x61) || mac.at(i) > 0x66) {
        return false;
      }
    }
  }
  return true;
}

function ScanCB(status, response) {
    //if (status !== BLE.Scanner.SCAN_RESULT || !response.service_data) return; //exit if Scan status stopped or no Sevice Data
    if (status !== BLE.Scanner.SCAN_RESULT) return; //exit if Scan status stopped
    //if (!isMacValid(response.addr)) return;
    if (macList.indexOf(response.addr) === -1) return;
    //try{
        let uuids = Object.keys(response.service_data);
        uuids.forEach(function (uuid) {
            //if (uuidsBan.indexOf(uuid) !== -1) return;
            //if (uuid === 'fea0') return;
            let manuuuids = Object.keys(response.manufacturer_data);
            let manudata;
            if (typeof manuuuids[0] !== 'undefined') manudata = btoh(response.manufacturer_data[manuuuids[0]]);
            let mqttData = {
                id: response.addr, //ok theengs
                mac_type: response.addr_type, //ok theengs
                advertisementdata: btoh(response.advData),
              //  scanRsp: response.scanRsp,
                rssi: response.rssi, //ok theengs
                flags: response.flags,
                localname: response.local_name,
                manufacturerdatauuid: manuuuids[0],
                manufacturerdata: manudata, //ok theengs
                servicedatauuid: uuid,
                servicedata: btoh(response.service_data[uuid]), //Convert into Base16 to get around utf8 Error.
                txpower: response.tx_power_level, //ok theengs
            };
            if(debug) print('Debug: ',mqttData);
            let unixtime = (Shelly.getComponentStatus("sys").unixtime + 2 * 3600) * 1000;
            let dateScan = new Date(unixtime);
            if(MQTT.isConnected()){
                if(debug) print('Debug: sending MQTT Data');
                topic = genTopic + response.addr + ':' + uuid;
                MQTT.publish(topic + '/undecoded', JSON.stringify(mqttData), 0, false);
                //MQTT.publish(topic + '/date', dateScan.toLocaleString(), 0, true);
                //MQTT.publish(topic + '/date', JSON.stringify(dateScan), 0, true);
                return;
            }
            print('Error: MQTT is not Ready, cant send MQTT Data');
        });
   // }catch(e){print('pacLog' + e);}
}

print('Status: started Script');
BLE.Scanner.Start({ duration_ms: BLE.Scanner.INFINITE_SCAN, active: true}, ScanCB);

Je récupère le JSON suivant :

{
  "id":"88:88:88:88:88:88",
  "mac_type":1,
  "advertisementdata":"0201061216d2fc45b3c2e261863eb7d076660d129bc1",
  "rssi":-66,
  "flags":6,
  "servicedatauuid":"fcd2",
  "servicedata":"45b3c2e261863eb7d076660d129bc1"
}

Lorsque je colle le JSON sur le site https://parser.theengs.io/, j’ai une erreur.

Une aide de la part de @DigiH ou de @1technophile serait la bienvenue.

Merci.

Bonjour,

Comme vous ne semblez pas recevoir les braodcasts de Shelly avec TGW, mais votre propre script, il manque certains détails de BLE broadcast dans votre JSON que TGW aurait reçus et requis pour décoder les informations. Il en va de même pour l’Web Parser.

Et comme votre exemple ci-dessus provient d’un ShellyBLU Button1 crypté, l’Web Parser ne pourra pas le décoder de toute façon. Cela n’est possible qu’avec TGW et la bindkey requise.

Pourquoi n’utilisez-vous pas TGW?

@Mips Peut-être parce que le plug-in TGW n’a pas (encore) l’option bindkey dans l’interface utilisateur? Que les utilisateurs du plug-in TGW puissent faire reconnaître et décoder leurs appareils Xiaomi Mijia LYWSD03MMC/MJWSD05MMC, ShellyBLU Door/Window, ShellyBLU Motion et ShellyBLU Button1 cryptés.

Mais je ne sais pas si je connais la dernière UI.

J’utilise bien TGW (la version snap) mais en mode MQTTtoMQTT decoding.

theengs-gateway  1.4.0      63     latest/stable  koen-vervloesem  held
theengs-gateway  1.3.0      60     latest/stable  koen-vervloesem  disabled,held
theengs-gateway  1.2.0      51     latest/stable  koen-vervloesem  disabled,held

Peux-tu me dire ce qui manque dans le JSON pour que j’essaye de modifier mon script ?

Merci

Le nom de l’appareil de diffusion, et évidemment la bindkey pour toutes les diffusions d’appareils Shelly chiffrés.

J’espère que cela vous aidera :slight_smile:

Un exemple de JSON conforme pour un ShellyBLU Button1 serait fortement apprécié.

Merci

Comme je n’ai pas d’appareils Shelly moi-même, je ne peux pas donner d’exemples de messages qu’ils envoient, mais je sais que le nom de la diffusion est manquant pour tout décodage avec TGW.

Quel nom de braodcast recevez-vous?

Je ne sais même pas comment obtenir les bindkeys pour Shellys, à cause d’appareils manquants :wink:

Il serait toujours très utile d’avoir ce champ dans le plug-in TGW, afin que les utilisateurs du plug-in TGW puissent faire reconnaître et décoder leurs appareils Xiaomi Mijia LYWSD03MMC/MJWSD05MMC, ShellyBLU Door/Window, ShellyBLU Motion et ShellyBLU Button1 cryptés.

Je suis très heureux d’aider à résoudre tous les problèmes de TGW, et aussi d’ajouter de nouveaux périphériques à TGW si possible, mais j’espère que vous comprenez que je ne peux pas vraiment m’empêcher de déboguer d’autres projets si c’est plus compliqué que mes suggestions ci-dessus.

Je comprends très bien ta position.

Ce que je souhaitait c’est surtout la syntaxe de la partie gauche du JSON qui n’est pas exhaustive sur ton site.

Merci

Voila ce que je dispose de mon ShellyBLU Button1 et que je pourrai ajouter dans mon script.

{
  "info": {
    "id": "*****************",
    "name": "ShellyBLUButton1-************",
    "mac": "************",
    "fwID": "20240408-184555\/v1.0.16@716b307b",
    "gen": "GBLE",
    "code": "SBBT-002C",
    "unixtime": 1719061230,
    "beaconSupported": true,
    "defaultPasskey": "******"
  },
  "settings": {
    "provisioningKey": "**********************************************************************************************************************************************************************************************************************************************************************************************",
    "encrypted": true,
    "encryptionKey": "********************************",
    "bootloaderMac": "*****************",
    "beaconEnabled": true,
    "buzzerEnabled": false,
    "clickSpeed": 3
  }
}

Vos servicedatauuid et servicedata ont l’air bien, d’après ce que je peux dire, mais vous n’avez aucun nom de périphérique dans votre JSON.

Et êtes-vous entré dans le bindey en TGW pour le ShellyBLU Button1?

Ahh ok :wink: votre script appelle le nom de code.

Appelez-le « name » et incluez-le dans votre JSON.

1 « J'aime »

Grace à ton aide:
J’ai ajouté la bindkey.

snap set theengs-gateway bindkeys="**:**:**:**:**:** ********************************"

J’ai ajouté "name": "SBBT-002C", dans le JSON.

Et voici, le résultat après le décodage de tgw.

{
  "id": "**:**:**:**:**:**",
  "mac_type": 1,
  "name": "SBBT-002C",
  "advertisementdata": "0201061216d2fc450e90f7cdff3ff00477666a3e6914",
  "rssi": -49,
  "flags": 6,
  "brand": "Shelly",
  "model": "ShellyBLU Button1 encrypted",
  "model_id": "SBBT_002C_ENCR",
  "type": "BTN"
}

Par contre, il semblerait que tgw ne soit pas en mesure d’indiquer le nombre de pressions sur le bouton (1, 2 ou 3).

Press shortly once, twice, or three times.

Il devrait le faire, et l’a fait lorsque le coéquipier l’a créé et vérifié avec son Shelly Button.

0 - None (sent every 8 seconds if beacon mode is enabled)
1 - Single short click
2 - Double click
3 - Triple click
9 - Long press

Qu’en est-il lorsque vous utilisez Theengs Gateway indépendamment de votre script pour recevoir les diffusions Bluetooth lui-même?

Donc il manque encore quelque chose dans mon JSON, mais quoi ?

Je n’ai pas d’antenne bluetooth, à part mes modules Shelly Gen2.

EDIT : je suis avec la dernière version de snap 1.4.0 qui n’est pas la dernière version de tgw.

Je ne sais pas comment et ce que votre script reçoit, mais le résultat lors de l’obtention d’un résultat chiffré devrait avoir « cipher », « ctr », « mic » et « mac » keys, qui sert ensuite à décoder.

Les données ci-dessus ne ressemblent pas à une réponse de déchiffrement correcte de Theengs Gateway.

Merci pour la piste, je vais chercher dans ce sens.

Ça fonctionne bien avec un bouton non crypté.

{
  "id": "**:**:**:**:**:**", 
  "mac_type": 1,
  "name": "SBBT-002C",
  "advertisementdata": "0201060a16d2fc44002501643a03",
  "rssi": -58,
  "flags": 6,
  "brand": "Shelly",
  "model": "ShellyBLU Button1",
  "model_id": "SBBT-002C",
  "type": "BTN",
  "packet": 37,
  "batt": 100,
  "press": 3
}

Oui, tout devrait bien fonctionner :slight_smile:

Mais avec le cryptage, c’est un processus à double sens - Tout d’abord, faites déchiffrer la diffusion déchiffrée, puis faire décoder à nouveau le message déchiffré par Theengs Gateway.

Cette double étape doit également être effectuée par votre script, ce que TGW fait automatiquement.

Votre script doit peut-être faire le déchiffrement par lui-même.

En fait, votre propre décryptage semble être la seule solution actuelle, car passer des données cryptées à la passerelle Theengs à partir d’une source externe ne semble pas être possible pour le moment.

Tout fonctionne bien, cependant, si Theengs Gateway est utilisé directement pour recevoir de telles données cryptées.

Quand une fonctionnalité externe pourrait être ajoutée, je ne peux pas le dire pour le moment.

1 « J'aime »

Merci pour ton temps et tes conseils.

Je vais attendre une éventuelle évolution pour un fonctionnement des modules cryptés en mode MQTTtoMQTT decoding.

Une dernière chose, pouvez vous mettre la dernière version de tgw dans sa version SNAP ?

Comme d’autres collègues maintiennent les versions Snap, Docker, etc. et qu’ils sont actuellement très occupés par d’autres choses ou absents, cela peut prendre un certain temps pour qu’ils soient mis à jour, mais ils le seront.

1 « J'aime »