Votre avis sur Electrovanne SASWELL

Bonjour à tous,
Bon chez moi:
L’info batterie remonte, mais je doute de son actualisation.
Elle était à 50% pendant longtemps, puis j’ai remplacé les piles (batteries) et indique maintenant 100%, mais ne bouge pas.
Pour le schedule je sais pas, pas testé.
Je lance l’arrosage avec un script trois fois par jours (40 min). Arrêt par la vanne suivant le temps d’arrosage programmé sur la vanne, mais…
Un autre prob. il ne tiens pas compte du temps d’arrosage réglé via le curseur dans l’interface.
Solution gros bourrin rapidos: redéfinir un curseur pour le temps d’arrosage et dans le script récupérer sa valeur et la mettre dans le temps d’arrosage de la vanne. Si on récupère la valeur du curseur d’origine, cela n’a pas l’air de fonctionné. Pas toujours la bonne valeur souhaitée.
Vanne trop loin? Limite portée zigbee? Je ne sais pas. Pas le temps de tester à fond, J’ai du assurer l’arrosage de façon certaine rapidement.
Pour vérification, second script qui envoi une notification sur le tél. à l’ouverture et la fermeture de la vanne.
Pas vérifier la consommation en eau. Je pense que sur les petit volume la valeur et très imprécise, mais c’est le cas de beaucoup d’appareil mesurant la conso. de liquide sauf pour le matos de laboratoire.
Sinon la vanne fait son taf. (quand même :grin:)

Si cela peu aider, mes script:

alias: Arrosage Jardin - Start
description: ""
trigger:
  - platform: time
    at: sensor.sun_next_rising
    enabled: true
  - platform: time
    at: "10:30:00"
    enabled: true
  - platform: time
    at: "20:30:00"
    enabled: true
condition: []
action:
  - service: number.set_value
    data:
      value: "{{ states('input_number.vr_timer') | float(0) }}"
    target:
      entity_id: number.vannejardin_timer
  - type: turn_on
    device_id: 39ab163c3b0925fd7339c3b6005a599c
    entity_id: switch.vannejardin
    domain: switch
    enabled: true
mode: single

alias: Arrosage Jardin - SendMessage
description: ""
trigger:
  - platform: device
    type: changed_states
    device_id: 39ab163c3b0925fd7339c3b6005a599c
    entity_id: switch.vannejardin
    domain: switch
condition: []
action:
  - if:
      - condition: device
        type: is_on
        device_id: 39ab163c3b0925fd7339c3b6005a599c
        entity_id: switch.vannejardin
        domain: switch
    then:
      - service: notify.mobile_app_sm_g960f
        data:
          message: à {{ now().strftime("%Y-%m-%d - %H:%M") }}
          title: Démarrage arrosage
    else:
      - service: notify.mobile_app_sm_g960f
        data:
          message: à {{ now().strftime("%Y-%m-%d - %H:%M") }}
          title: Arrêt arrosage
mode: single

Bonjour @Dams
Peux-tu nous dire si tu es sur ZHA ?
Même chose pour @Argonaute64, ZHA ou pas ZHA ?

Pour ce qui est de la durée d’arrosage, la vanne a une fonction spécifique qui la ferme au bout d’un certain temps si elle n’a pas reçu d’ordre. C’est une sécurité intéressante pour éviter qu’elle reste ouverte trop longtemps. Néanmoins, chez moi, si l’automation donne un temps d’arrosage de plus de 10 min, la vanne se ferme au bout de 10 min de toutes façons.
Pour résoudre ce problème, j’ai juste adapté mon automation pour déclencher un un autre arrosage avec la durée cible moins 10 minutes si je veux arroser plus de 10 min.

zigbee2mqtt pour moi
idem l’histoire des 10min d’où le number.set_value du script

Avec le schedule, ca outrepasse le délai d’activation de la vanne, donc je n’ai pas ce pb (j’arrose 1h tous les soirs)

Idem qu’@argonaute64, je suis sous zigbee2mqtt.

Et comme je viens de le dire, pas de soucis de durrée d’activation pour moi : si le timer est à 10mn et que le scedule de la vanne (normal_schedule_timer_1) est plus long l’ouverture de la vanne sera la durée précisée dans le schedule. Par contre, si j’active la vanne manuellement alors là c’est le timer qui l’arrête au bout de 10mn (et en effet, quand on change la durée, ca ne fonctionne qu’une fois, ensuite ca remet 10mn par défaut - idem pour le weather delay)

Je comprend pas trop le weather delay
C’est quoi exactement?
Hé oui actionné manuellement le délai est de 10 min
Le temps pour moi d’aller voir si ça coule au bout du tuyau :laughing:

Je pense que le weather delay c’est s’il a plus alors on reporte de Xh l’ouverture de la vanne

Merci
Avis perso., un peu n’importe quoi l’option. J’ai du mal à l’intgrer dans un scénario cohérent

En effet, j’ai le même avis… :d

Dans le cas présent, je ne sais pas comment celà fonctionne ici, mais sur mon programmateur d’arrosage principal, j’ai aussi une option « weather delay » qui est super utile au quotidien, pour affiner l’utilisation.
En particulier: mon programmateur détermine un taux d’arrosage en fonction de la météo (température, vent, ensoleillement, etc.). Néanmoins, il ne regarde pas le futur de la météo, car c’est trop risqué (prévision de pluie qui ne se réalise pas, etc.). Du coup si je sais de façon sûre qu’il va pleuvoir dans les 24 heures, je mets une « weather delay » de 24h, pour être sûr que le programme ne se déclenchera pas 1 heure avant la pluie.
Je vois donc cette option comme un ajustement pratique de façon manuelle.
Malheureusement sur cette vanne, toutes ces infos ne sont pas disponibles sur ZHA, the le PR sur GitHub n’a pas beaucoup d’effet.

idem ici , l’attribut durée ouverture n’est pas dispo dans ZHA

Bonsoir

Pour ceux que ça intéresse, je suis en train de mettre au point un convertisseur pour cette vanne SAS980SWT-7-Z01 pour Zigbee2MQTT.

J’arrive à tout faire fonctionner, mais j’ai des problèmes avec la synchro de l’heure et les timers normaux/cycles embarqués. Ca a l’air de se déclencher, mais avec un décalage de 6 heures (quand je règle 21h00, ça se déclenche à 15h00).

Mais sinon, le timer de base fonctionne bien, le ON/OFF aussi, et les infos de batterie, de temps d’ouverture et d’eau consommée sont OK.

Voici le code du convertisseur ci-dessous, si vous voulez tester et me faire un retour. Le lien vers le Github :

const legacy = require('zigbee-herdsman-converters/lib/legacy');
const fz = {...require('zigbee-herdsman-converters/converters/fromZigbee'), legacy: require('zigbee-herdsman-converters/lib/legacy').fromZigbee};
const tz = {...require('zigbee-herdsman-converters/converters/toZigbee'), legacy: require('zigbee-herdsman-converters/lib/legacy').toZigbee};
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;


const sas980swt_set_time_request = {
    cluster: 'manuSpecificTuya',
    type: ['commandMcuSyncTime'],
    convert: async (model, msg, publish, options, meta) => {
        const hour = new Date().getHours();
        if (hour < 9) {
            meta.logger.info('SKIP commandMcuSyncTime message to SaswellSAS980SWTValve, to solve gap problem');
        } else {
            meta.logger.info('Send commandMcuSyncTime message to SaswellSAS980SWTValve');
            // Standard method
            const OneJanuary2000 = (new Date('January 01, 2000 00:00:00 UTC+00:00')).getTime();
            const utcTime = Math.round(((new Date()).getTime() - OneJanuary2000) / 1000);
            const localTime = utcTime - (new Date()).getTimezoneOffset() * 60;

            // Method grabbed from Github
            // const gap_s = 8 * 3600;
            // const offset_s = gap - tzo
            // const currentTime = Math.round(((new Date()).getTime()) / 1000);
            // const utcTime = currentTime - tzo - gap;
            // const localTime = 0;
            // meta.logger.info(`commandMcuSyncTime - SaswellSAS980SWTValve tzo = ${tzo}`);
            // meta.logger.info(`commandMcuSyncTime - SaswellSAS980SWTValve gap = ${gap}`);

            // Method from https://github.com/kkossev/Hubitat-Tuya-Wall-Thermostat/blob/main/Tuya-Wall-Thermostat.groovy in syncTuyaDateTime()
            //const offset = (new Date()).getTimezoneOffset() * 60;  // Hours in minute with sign * 60 to get seconds.
            //const offsetHours = Math.round(offset / 3600)
            //const OneJanuary2000 = (new Date('January 01, 2000 00:00:00 UTC+00:00')).getTime();
            //const utcTime = Math.round(((new Date()).getTime() - OneJanuary2000) / 1000);
            //const localTime = utcTime;

            
            const endpoint = msg.endpoint;
            meta.logger.info(`commandMcuSyncTime - SaswellSAS980SWTValve sent utc time = ${utcTime}`);
            meta.logger.info(`commandMcuSyncTime - SaswellSAS980SWTValve sent local time = ${localTime}`);
            const payload = {
                payloadSize: 8,
                payload: [
                    ...legacy.convertDecimalValueTo4ByteHexArray(utcTime),
                    ...legacy.convertDecimalValueTo4ByteHexArray(localTime),
                ],
            };
            await endpoint.command('manuSpecificTuya', 'mcuSyncTime', payload, {});
        };
    },
};


const fzLocal = {
    SAS980SWT: {
        cluster: 'manuSpecificTuya',
        type: 'commandDataResponse',
        convert: (model, msg, publish, options, meta) => {
            const dpValue = legacy.firstDpValue(msg, meta, 'SAS980SWT');
            const value = legacy.getDataValue(dpValue);
            const dp = dpValue.dp;
            switch (dp) {
            case legacy.dataPoints.state: {
                return {state: value ? 'ON': 'OFF'};
            }
            case 5: {
                // Seems value is reported in tenths of liters
                return {water_consumed: (value / 10.0).toFixed(2)};
            }
            case 7: {
                return {battery: value};
            }
            case 10: {
                let data = 'disabled';
                if (value == 1) {
                    data = '24h';
                } else if (value == 2) {
                    data = '48h';
                } else if (value == 3) {
                    data = '72h';
                }
                return {weather_delay: data};
            }
            case 11: {
                // value reported in seconds
                return {timer_time_left: value / 60};
            }
            case 12: {
                if (value === 0) return {timer_state: 'disabled'};
                else if (value === 1) return {timer_state: 'active'};
                else return {timer_state: 'enabled'};
            }
            case 15: {
                // value reported in seconds
                return {last_valve_open_duration: value / 60};
            }
            case 16: {
                meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: Received DP ` +
                    `#${dp} with data ${JSON.stringify(dpValue)}`);
                const tresult = {
                    cycle_timer_1: '',
                    cycle_timer_2: '',
                    cycle_timer_3: '',
                    cycle_timer_4: '',
                };
                for (let index = 0; index < 40; index += 12) {
                    meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: DP ` +
                        `#${dp} decoding value for index ${index} = ${value.slice(index)}`);
                    const timer = legacy.convertRawToCycleTimer(value.slice(index));
                    meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: DP ` +
                        `#${dp} timer ${index} = ${timer.starttime} / ${timer.endtime} / ` +
                        `${timer.irrigationDuration} / ${timer.pauseDuration} / ` +
                        `${timer.weekdays} / ${timer.active}`);
                    if (timer.irrigationDuration > 0) {
                        meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: DP ` +
                            `#${dp} timer ${index} = ${timer.starttime} / ${timer.endtime} / ` +
                            `${timer.irrigationDuration} / ${timer.pauseDuration} / ` +
                            `${timer.weekdays} / ${timer.active}`);
                        tresult['cycle_timer_' + (index / 12 + 1)] = timer.starttime +
                            ' / ' + timer.endtime + ' / ' +
                            timer.irrigationDuration + ' / ' +
                            timer.pauseDuration + ' / ' +
                            timer.weekdays + ' / ' + timer.active;
                    }
                }
                return tresult;
            }
            case 17: {
                meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: Received DP ` +
                    `#${dp} with data ${JSON.stringify(dpValue)}`);
                const tresult = {
                    normal_schedule_timer_1: '',
                    normal_schedule_timer_2: '',
                    normal_schedule_timer_3: '',
                    normal_schedule_timer_4: '',
                };
                for (let index = 0; index < 40; index += 13) {
                    meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: DP ` +
                        `#${dp} decoding value for index ${index} = ${value.slice(index)}`);
                    const timer = legacy.convertRawToTimer(value.slice(index));
                    if (timer.duration > 0) {
                        meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: DP ` +
                            `#${dp} timer ${index} = ${timer.time} / ${timer.duration} / ${timer.weekdays} / ${timer.active}`);
                        tresult['normal_schedule_timer_' + (index / 13 + 1)] = timer.time +
                        ' / ' + timer.duration +
                        ' / ' + timer.weekdays +
                        ' / ' + timer.active;
                    }
                }
                return tresult;
            }
            default: {
                meta.logger.warn(`zigbee-herdsman-converters:SaswellSAS980SWTValve: NOT RECOGNIZED DP ` +
                    `#${dp} with data ${JSON.stringify(dpValue)}`);
            }
            }
        },
    },
};


const tzLocal = {
    ZVG1_cycle_timer: {
        key: ['cycle_timer_1', 'cycle_timer_2', 'cycle_timer_3', 'cycle_timer_4'],
        convertSet: async (entity, key, value, meta) => {
            let data = [0];
            const footer = [0x64];
            if (value == '') {
                // delete
                data.push(0x04);
                data.push(parseInt(key.substr(-1)));
                meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: ${entity}, DP ` +
                    `#16 sending raw data ${data}`);
                await legacy.sendDataPointRaw(entity, 16, data);
                const ret = {state: {}};
                ret['state'][key] = value;
                return ret;
            } else {
                if ((meta.state.hasOwnProperty(key) && meta.state[key] == '') ||
                    !meta.state.hasOwnProperty(key)) {
                    data.push(0x03);
                } else {
                    data.push(0x02);
                    data.push(parseInt(key.substr(-1)));
                }
            }

            const tarray = value.replace(/ /g, '').split('/');
            if (tarray.length < 4) {
                throw new Error('Please check the format of the timer string');
            }
            if (tarray.length < 5) {
                tarray.push('MoTuWeThFrSaSu');
            }

            if (tarray.length < 6) {
                tarray.push('1');
            }

            const starttime = tarray[0];
            const endtime = tarray[1];
            const irrigationDuration = tarray[2];
            const pauseDuration = tarray[3];
            const weekdays = tarray[4];
            const active = parseInt(tarray[5]);

            if (!(active == 0 || active == 1)) {
                throw new Error('Active value only 0 or 1 allowed');
            }
            data.push(active);

            const weekdaysPart = legacy.convertWeekdaysTo1ByteHexArray(weekdays);
            data = data.concat(weekdaysPart);

            data = data.concat(legacy.convertTimeTo2ByteHexArray(starttime));
            data = data.concat(legacy.convertTimeTo2ByteHexArray(endtime));

            data = data.concat(legacy.convertDecimalValueTo2ByteHexArray(irrigationDuration));
            data = data.concat(legacy.convertDecimalValueTo2ByteHexArray(pauseDuration));

            data = data.concat(footer);
            meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: ${entity}, DP ` +
                `#16 sending raw data ${data}`);
            await legacy.sendDataPointRaw(entity, 16, data);
            const ret = {state: {}};
            ret['state'][key] = value;
            return ret;
        },
    },
    ZVG1_normal_schedule_timer: {
        key: ['normal_schedule_timer_1', 'normal_schedule_timer_2', 'normal_schedule_timer_3', 'normal_schedule_timer_4'],
        convertSet: async (entity, key, value, meta) => {
            let data = [0];
            const footer = [0x07, 0xe6, 0x08, 0x01, 0x01];
            if (value == '') {
                // delete
                data.push(0x04);
                data.push(parseInt(key.substr(-1)));
                meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: ${entity}, DP ` +
                    `#17 sending raw data ${data}`);
                await legacy.sendDataPointRaw(entity, 17, data);
                const ret = {state: {}};
                ret['state'][key] = value;
                return ret;
            } else {
                if ((meta.state.hasOwnProperty(key) && meta.state[key] == '') || !meta.state.hasOwnProperty(key)) {
                    data.push(0x03);
                } else {
                    data.push(0x02);
                    data.push(parseInt(key.substr(-1)));
                }
            }

            const tarray = value.replace(/ /g, '').split('/');
            if (tarray.length < 2) {
                throw new Error('Please check the format of the timer string');
            }
            if (tarray.length < 3) {
                tarray.push('MoTuWeThFrSaSu');
            }

            if (tarray.length < 4) {
                tarray.push('1');
            }

            const time = tarray[0];
            const duration = tarray[1];
            const weekdays = tarray[2];
            const active = parseInt(tarray[3]);

            if (!(active == 0 || active == 1)) {
                throw new Error('Active value only 0 or 1 allowed');
            }

            data = data.concat(legacy.convertTimeTo2ByteHexArray(time));

            const durationPart = legacy.convertDecimalValueTo2ByteHexArray(duration);
            data = data.concat(durationPart);

            const weekdaysPart = legacy.convertWeekdaysTo1ByteHexArray(weekdays);
            data = data.concat(weekdaysPart);
            data = data.concat([64, active]);
            data = data.concat(footer);
            meta.logger.info(`zigbee-herdsman-converters:SaswellSAS980SWTValve: ${entity}, DP ` +
                  `#17 sending raw data ${data}`);
            await legacy.sendDataPointRaw(entity, 17, data);
            const ret = {state: {}};
            ret['state'][key] = value;
            return ret;
        },
    },
};


const definition = {
    fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_akjefhj5'}],
    model: 'SAS980SWT-7-Z01',
    vendor: 'SASWELL',
    description: 'Zigbee smart water valve',
    fromZigbee: [fzLocal.SAS980SWT, fz.ignore_basic_report, sas980swt_set_time_request], //, fz.ignore_tuya_set_time],
    toZigbee: [tz.legacy.tuya_switch_state, tz.legacy.ZVG1_weather_delay, tz.legacy.ZVG1_timer, tzLocal.ZVG1_cycle_timer, tzLocal.ZVG1_normal_schedule_timer],
    // onEvent: tuya.onEventSetLocalTime,
    // onEvent: tuya.onEventSetTime,
    configure: tuya.configureMagicPacket,
    exposes: [e.switch().setAccess('state', ea.STATE_SET), e.battery(),
        exposes.enum('weather_delay', ea.STATE_SET, ['disabled', '24h', '48h', '72h']),
        exposes.enum('timer_state', ea.STATE, ['disabled', 'active', 'enabled']),
        exposes.numeric('timer', ea.STATE_SET).withValueMin(0).withValueMax(60).withUnit('min')
            .withDescription('Auto off after specific time'),
        exposes.numeric('timer_time_left', ea.STATE).withUnit('min')
            .withDescription('Auto off timer time left'),
        exposes.numeric('last_valve_open_duration', ea.STATE).withUnit('min')
            .withDescription('Time the valve was open when state on'),
        exposes.numeric('water_consumed', ea.STATE).withUnit('l')
            .withDescription('Liters of water consumed'),
        exposes.text('cycle_timer_1', ea.STATE_SET).withDescription('Format 08:00 / 20:00 / 15 / 60 / MoTuWeThFrSaSu / 1 (' +
            '08:00 = start time ' +
            '20:00 = end time ' +
            '15 = irrigation duration in minutes ' +
            '60 = pause duration in minutes ' +
            'MoTu..= active weekdays ' +
            '1 = deactivate timer with 0)'),
        exposes.text('cycle_timer_2', ea.STATE_SET).withDescription('Format 08:00 / 20:00 / 15 / 60 / MoTuWeThFrSaSu / 1 (' +
            '08:00 = start time ' +
            '20:00 = end time ' +
            '15 = irrigation duration in minutes ' +
            '60 = pause duration in minutes ' +
            'MoTu..= active weekdays ' +
            '1 = deactivate timer with 0)'),
        exposes.text('cycle_timer_3', ea.STATE_SET).withDescription('Format 08:00 / 20:00 / 15 / 60 / MoTuWeThFrSaSu / 1 (' +
            '08:00 = start time ' +
            '20:00 = end time ' +
            '15 = irrigation duration in minutes ' +
            '60 = pause duration in minutes ' +
            'MoTu..= active weekdays ' +
            '1 = deactivate timer with 0)'),
        exposes.text('cycle_timer_4', ea.STATE_SET).withDescription('Format 08:00 / 20:00 / 15 / 60 / MoTuWeThFrSaSu / 1 (' +
            '08:00 = start time ' +
            '20:00 = end time ' +
            '15 = irrigation duration in minutes ' +
            '60 = pause duration in minutes ' +
            'MoTu..= active weekdays ' +
            '1 = deactivate timer with 0)'),
        exposes.text('normal_schedule_timer_1', ea.STATE_SET).withDescription('Format 08:00 / 15 / MoTuWeThFrSaSu / 1 (' +
            '08:00 = start time ' +
            '15 = duration in minutes ' +
            'MoTu..= active weekdays ' +
            '1 = deactivate timer with 0)'),
        exposes.text('normal_schedule_timer_2', ea.STATE_SET).withDescription('Format 08:00 / 15 / MoTuWeThFrSaSu / 1 (' +
            '08:00 = start time ' +
            '15 = duration in minutes ' +
            'MoTu..= active weekdays ' +
            '1 = deactivate timer with 0)'),
        exposes.text('normal_schedule_timer_3', ea.STATE_SET).withDescription('Format 08:00 / 15 / MoTuWeThFrSaSu / 1 (' +
            '08:00 = start time ' +
            '15 = duration in minutes ' +
            'MoTu..= active weekdays ' +
            '1 = deactivate timer with 0)'),
        exposes.text('normal_schedule_timer_4', ea.STATE_SET).withDescription('Format 08:00 / 15 / MoTuWeThFrSaSu / 1 (' +
            '08:00 = start time ' +
            '15 = duration in minutes ' +
            'MoTu..= active weekdays ' +
            '1 = deactivate timer with 0)')],
};

module.exports = definition;
2 « J'aime »

Bonjour,
Voila, je teste mais j’ai quelques question et quelques points. (C’est la premier fois que je m’attaque à ce genre de convertiseur.)
Dans le fingerprint j’ai du changer le manufacturername en ‹ _TZE200_81isopgh ›
→ D’où j’espère que les modèles sont compatible. Pas trouvé d’infos sur le net.
Dans toZigbee: [tz.legacy.tuya_switch_state, tz.legacy.ZVG1_weather_delay, tz.legacy.ZVG1_timer, …, erreur au redémarrage de Z2M.
→ Supprimer le .legacy
A partir le là Z2M démarre la vanne est visible avec les nouvelles infos.
Mais j’ai un message dans le log ’ Exception while calling fromZigbee converter: legacy.firstDpValue is not a function}
J’imagine qu’il manque une bibliothèque quelque part? Question de version?
Ma version de Z2M et la 1.29.2-1. Si je passe à la dernière je perd la remonté des infos des interrupteurs. Pas le temps de regarder donc pas de miseà jour pour l’instant.
Cordialement

Ah oui, le convertisseur est écrit pour la dernière version de Z2M. Je te fais passer une version que j’utilisais sur la version 1.28 de Z2M.

Par contre, le modèle _TZE200_81isopgh est déjà pris en charge nativement par Z2M, comme une RTX ZVG1 : https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/src/devices/rtx.ts
Mon modèle SASWELL _TZE200_akjefhj5 est identique et présent dans la définition de Z2M, mais la mesure de consommation d’eau n’est pas bonne, la RTX renvoie des onces, alors que la SASWELL renvoie des dixièmes de litre. D’om mon convertisseur perso.
Ta vanne ne fonctionne pas correctement avec la définition intégrée à Z2M ?

Merci pour les réponses
J’ai des doutes sur la valeur des conso. Difficile pour l’instant d’essayer avec un seau.
C’était pour moi occasion de m’y mettre pour comprendre et faire des convertisseurs.
J’ai également un capteur de t° Orvibo ST30 qui lui aussi est pris en charge mais qui me donne une erreur dans Z2M. Je pense que cela concerne la batterie. L’idée est de faitre un convertisseur pour corriger cela.