Xiaomi/Aqara Cube T1 Pro (MFCZQ12LM)

Hello all,
Je viens de mettre en place (partiellement) ce capteur sur Z2M et je propose de vous partager les résultats; en espérant que ca puisse aider certains.
Note: Je vous propose ma façon de faire; c’est une « bidouille » qui répond à mon besoin. Rien de plus.

OBJECTIF:
Faire fonctionner le nouveau modèle (MFCZQ12LM) du Magic Cube Aqara/Xiami sur Jeedom avec Zigbeelinker. Ce modèle n’est pas encore compatible zigbee2mqtt.
Perso, je l’utilise pour piloter les modes de la maison (coucher / lever / partir / arriver), 1 par face.

RESULTAT:
Fonctionnement partiel:

  • Détection de toutes les faces (la face finale qui est vers le haut)
  • Détection « shake »
  • Détection « fly/fall » (pas bien utile à priori)
  • Détection des rotations (gauche et droite) et de l’angle associé

Note: Ce cube fonctionne mieux sur DeConz (plus de fonctions détectées) que Z2M à ce jour.

LIMITATIONS:

  • Pas de détection du mouvement (flip 90° ou flip 180°). Faisable si on enregistre le changement de face via Jeedom et que l’on déduit le mouvement
  • Pas de détection du slide (bouger transversalement sans changer de face)
  • Le capteur semble avoir 2 modes (action et scène) d’après la doc; ce n’est pas pilotable
  • Cette procédure a été faite sur un Jeedom DIY (installation sur VM Debian Buster). Les répertoires peuvent changer dans d’autres cas.

PREREQUIS:

  • Des connaissances de base suffisantes en Linux (édition de fichiers de configuration) + Accès SSH
  • Plugin Zigbeelinker ou Zigbee2MQTT installé
  • Avoir une version récente des fichiers zigbee2mqtt (notamment une qui supporte l’ancien modèle). Pour savoir, vérifiez qu’il est pris en charge (rechercher « MFKZQ01LM » dans « /opt/zigbee2mqtt/node_modules/zigbee-herdsman-converters/devices/xiaomi.js »). Si absent, téléchargez sur github une version plus récente des éléments du répertoire « zigbee-herdsman-converters »

PRINCIPE:

  • Ajouter le « convertisseur » associé pour interpréter les messages du capteur
  • Ajouter le capteur dans les modèles reconnus par zigbee2mqqtt
  • Ajouter la photo du capteur dans Jeedom

ETAPES:

  • Le plugin zigbee2mqtt n’est pas facile à débugger. Afin de savoir où se pose le problème, stoppez et relancez-le à chaque changement de fichier de config. Soit via Jeedom (config du plugin) soit manuellement (à réserver à un plublic averti) directement zigbee2mqtt en lançant « sudo DEBUG=zigbee-herdsman* npm start » depuis « /opt/zigbee2mqtt/ » (en ayant précédemment désactivé le plugin Jeedom et configuré à minima votre configuration.yaml (mettre l’IP de votre serveur MQTT). Dès que Z2M plante, vérifiez vos modifs.
  • Modifier le convertisseur « /opt/zigbee2mqtt/node_modules/zigbee-herdsman-converters/converters/fromZigbee.js ». Faire une copie de sauvegarde auparavant, puis rajouter ce code là (par ex. après la définition du capteur MFKZQ01LM_action_analog, vers ligne -6130)
    MFCZQ12LM_action_multistate: {
        cluster: 'genMultistateInput',
        type: ['attributeReport', 'readResponse'],
        options: [exposes.options.legacy()],
        convert: (model, msg, publish, options, meta) => {
            /*
            Cube face = numbers on the cube itself:
               - Face 1 = 'Aqara logo'
               - Face 6 = Battery face
	       - Face f = Face with the f number of points

            attrId 329 (x) => Give the final face up
               - The final face number is x+1
            attrId 85 (y) => Give the action/movement 
               - y = 2 => Wake up 
               - y = 4 => Fall/Fly 
               - y = 0 => Shake 
               - y >= 1024 => Flip (90 or 180) to the face y-1023
            Note: Don't know how to differentiate flip 90 or 180 (can be deduced from the previous face and the current one)
            Note: Don't know how to detect slide (in such a case, attibId 85 is sent (no change) but not attrId 329
            Note: Dont't know hot to detect a tap (in such case, attrId 85 is sent (no change) and attrId is sent (no change) 
            Note: After each movement, the sensor sent a last dedicated message indicating its final side. This event is captured in the part MFCZQ12LM_action_finalface (see below) 
            */
            const value_action = msg.data['presentValue'];
            let result = null;

            if (value_action === 0) result = {action: 'shake'};
            else if (value_action === 2) result = {action: 'wakeup'};
            else if (value_action === 4) result = {action: 'fall'};
            else if (value_action >= 1024) result = {action: 'flip', side: value_action-1023};

            if (result && !isLegacyEnabled(options)) {
                delete result.to_side;
                delete result.from_side;
            }

            if (value_action == null) {
                delete result.side;
            }

           return result ? result : null;
        },
    },
    MFCZQ12LM_action_analog: {
        cluster: 'genAnalogInput',
        type: ['attributeReport', 'readResponse'],
        options: [exposes.options.legacy()],
        convert: (model, msg, publish, options, meta) => {
            /*  This cluster is catched each time a rotation is detected.
		2 informations are sent by the sensor:
			- the rotation angle (positive is clockwise, negative if not)
			- the concerned side (the side up)
		Note: After each movement, the sensor sent a last dedicated message indicating its final side. This event is captured in the part MFCZQ12LM_action_finalface (see below) 
	    */
            const value = msg.data['presentValue'];
            const face = msg.data['329'];

            const result = {
                action: value < 0 ? 'rotate_left' : 'rotate_right',
                angle: Math.floor(value * 100) / 100,
                action_angle: Math.floor(value * 100) / 100,
                side: face+1,
            };

            if (!isLegacyEnabled(options)) delete result.angle;
            return result;
        },
    },
    MFCZQ12LM_action_finalface: {
        cluster: 'aqaraOpple',
        type: ['attributeReport', 'readResponse'],
        options: [exposes.options.legacy()],
        convert: (model, msg, publish, options, meta) => {
	    /* This dedicated message is sent after any movement of the cube (flip, rotation, slide, etc...)
	       It contains the final side (up) of the cube after the movement
	    */
            const face = msg.data['329'];

            const result = {
                //action: 'finalface',
		side: face+1,
            };

            if (!isLegacyEnabled(options)) delete result.angle;
            return result;
        },
    },

Relancez zigbee2mqtt pour vérifier que ca fonctionne toujours. Sinon, vérifiez et remettez votre fichier sauvegardé précédemment.

  • Modifier le fichier « /opt/zigbee2mqtt/node_modules/zigbee-herdsman-converters/devices/xiaomi.js ». Copie de sauvegarde puis ajout (ligne 1558):
    {
        zigbeeModel: ['lumi.remote.cagl02'],
        model: 'MFCZQ12LM',
        vendor: 'Xiaomi',
        description: 'Mi/Aqara smart home cube T1 Pro',
        meta: {battery: {voltageToPercentage: '3V_2850_3000'}},
        fromZigbee: [fz.xiaomi_basic, fz.MFCZQ12LM_action_analog,fz.MFCZQ12LM_action_multistate,fz.MFCZQ12LM_action_finalface],
        exposes: [e.battery(), e.battery_voltage(), e.angle('action_angle'), e.device_temperature(), e.power_outage_count(false),
            e.cube_side('action_from_side'), e.cube_side('action_side'), e.cube_side('action_to_side'), e.cube_side('side'),
            e.action(['shake', 'wakeup', 'fall', 'tap', 'slide', 'flip180', 'flip90', 'rotate_left', 'rotate_right'])],
        toZigbee: [],
    },

Relancez et vérifiez que tout fonctionne.

  • Allez sur la page web zigbee2mqtt du plugin Jeedom, mettez-vous en mode d’inclusion et inclure le cube (appui long sur bouton dans le compartiment de la pile jusqu’à flash rapide de la led bleu). Ne pas hésiter à faire kkes appuis supplémentaires (brefs) pour forcer la communication du capteur et finir l’interview. Faire preuve de patience. Ressayer si KO (enlever la pile pendant 1min entre 2 essais pourrait aider). Vous devriez obtenir ceci:

Note: Nos modifs de code « font croire qu’il est reconnu » (supported) mais ce n’est que partiel, en attendant que Z2M le prenne VRAIMENT et officiellement en charge.

  • Dans la page de l’équipement Jeedom:


    Note: Toutes ces commandes correspondent au précédent modèle, elles ont été gardées car il y a fort à parier qu’elles seront utiles qd le capteur sera pris en charge. Notre modif ne permet d’utiliser que:
    ==> Action: donne les actions faites sur le capteur (wakeup, flip, fall, shake, rotation)
    ==> Côté du cube: face du cube vers le haut
    ==> Angle: angle de rotation
  • Si vous voulez une belle image du capteur dans Jeedom, rajoutez « MFCZQ12LM.jpg » dans « /var/www/html/plugins/zigbee2mqtt/data/devices/images » (veillez aux droits et à mettre www-data comme propriétaire via « sudo chown www-data:www-data MFCZQ12LM.jpg »). Exemple d’image:
    MFCZQ12LM
    Après relance du plugin l’image dans Jeedom devrait apparaitre (celle de la page web Z2M ne sera pas mise à jour).

Enjoy !

Hello,
La communauté Z2M a été particulièrement efficace… Même si le cube n’est pas encore officiellement supporté, tout fonctionne.
Tout est ici: Github Z2M
Vous pouvez mettre en place votre propre « converter » externe (1 fichier avec le code qu’ils proposent, à mettre à côté de votre configuration.yaml + rajouter 2 lignes dans ce configuration.yaml pour le prendre en compte) et le tour est joué.
Alors, ce cube a 2 modes (scene et action); on passe de l’un à l’autre via un appui rapide, 5 fois, sur le bouton de la trappe de pile.
Tout fonctionne (flip 90, flip 180, fall, hold, shake, rotate, slide, battery, mode); selon le mode, certaines fonctions sont disponibles.
Note: Mon capteur a des « ratés » en mode action (flip et slide non détectés parfois) alors qu’en mode scene il est plus fiable; j’ai donc choisi celui-là. La détection des faces est très fiable, la détection du shake aussi; mais dans ce mode, pas de tap ou de slide…
Amusez-vous bien !