- Sensor arcón congelador ZT08 e integración en Home Assistant
Hace unas semanas vi un termómetro zigbee con una sonda externa que me podia ir bien para el arcón congelador que tengo , el enlace de Aliexpres es este

Lo elegí porque el que tenia antes a partir de -20ºC tenia problemas y no daba lectura , el mínimo teórico de este dispositivo son -40ºC

Se puede colocar de diferentes maneras , desde magnética , adhesiva y con ventosa , al final me decante por la adhesiva en la tapa de las baterías.

Va alimentado por tres pilas AAA

Al alimentarlo ya nos muestra la temperatura local , la de las sonda , la hora y el nivel de bateria , pero las temperaturas en grados Fahrenheit

El siguiente paso es integrarlo en zigbee2mqtt , la información de este dispositivo será la siguiente.
Nada mas emparejarlo nos dice que no esta soportado , y nos devuelve este identificador “_TZE284_hodyryli“

Para disponer de el tendremos que usar un converter , aquí encontre uno que funcionaba , el código seria el siguiente :
const tuya = require('zigbee-herdsman-converters/lib/tuya'); const exposes = require('zigbee-herdsman-converters/lib/exposes'); const e = exposes.presets; const ea = exposes.access; const fzLocal = { tuya_weather_station: { cluster: 'manuSpecificTuya', type: ['commandDataReport', 'commandActiveStatusReport', 'commandMcuSyncTime'], convert: (model, msg, publish, options, meta) => { const result = {}; // Time synchro if (msg.type === 'commandMcuSyncTime') { (async () => { try { const endpoint = msg.endpoint; const now = new Date(); const utcTime = Math.round(now.getTime() / 1000); const localTime = utcTime - (now.getTimezoneOffset() * 60); const utcArray = [ (utcTime >> 24) & 0xFF, (utcTime >> 16) & 0xFF, (utcTime >> 8) & 0xFF, utcTime & 0xFF, ]; const localArray = [ (localTime >> 24) & 0xFF, (localTime >> 16) & 0xFF, (localTime >> 8) & 0xFF, localTime & 0xFF, ]; const payload = { payloadSize: 8, payload: [...utcArray, ...localArray], }; await endpoint.command('manuSpecificTuya', 'mcuSyncTime', payload, {disableDefaultResponse: true}); // set 24h time format await new Promise(resolve => setTimeout(resolve, 500)); try { await tuya.sendDataPointBool(endpoint, 17, false); } catch (e) { // Ignore if DP 17 don't exist } } catch (error) { // Ignore time synchro errors } })(); return {}; } if (!msg.data || !msg.data.dpValues) return {}; for (const dpValue of msg.data.dpValues) { const dp = dpValue.dp; const data = dpValue.data; let value; // temperature if (dpValue.datatype === 2) { // Reads the data as an unsigned big-endian 32-bit integer (Negative numbers will be wrong, eg. 429496724.6) // value = data.readUInt32BE(0); // Reads the data as a signed big-endian 32-bit integer (Negative numbers will be correct) value = data.readInt32BE(0); } else if (dpValue.datatype === 4) { value = data[0]; } else { value = data[0]; } switch (dp) { // temperature case 1: result.temperature = value / 10; break; // humidity case 2: result.humidity = value; break; // battery_state case 3: result.battery_state = value; result.battery = value === 0 ? 10 : (value === 1 ? 50 : 100); result.battery_low = value === 0; break; // time_format case 17: result.time_format = value ? '12h' : '24h'; break; // temperature_external case 38: result.temperature_external = value / 10; break; } } return result; }, }, }; const definition = { fingerprint: tuya.fingerprint('TS0601', ['_TZE284_hodyryli']), model: 'TS0601_weather_station', vendor: 'TuYa', description: 'Weather station with clock, internal/external temperature and humidity', fromZigbee: [fzLocal.tuya_weather_station], toZigbee: [tuya.tz.datapoints], configure: tuya.configureMagicPacket, exposes: [ e.temperature().withDescription('Internal temperature'), e.humidity().withDescription('Internal humidity'), e.numeric('temperature_external', ea.STATE) .withUnit('°C') .withDescription('External temperature sensor'), e.battery() .withDescription('Battery level (10%=low, 50%=medium, 100%=full)'), e.battery_low() .withDescription('Battery low warning'), e.enum('battery_state', ea.STATE, [0, 1, 2]) .withDescription('Raw battery state (0=low, 1=medium, 2=full)'), e.enum('time_format', ea.STATE, ['12h', '24h']) .withDescription('Clock time format'), ], meta: { tuyaDatapoints: [ [1, 'temperature', tuya.valueConverter.divideBy10], [2, 'humidity', tuya.valueConverter.raw], [3, 'battery_state', tuya.valueConverter.raw], [17, 'time_format', tuya.valueConverter.onOff], [38, 'temperature_external', tuya.valueConverter.divideBy10], ], }, }; module.exports = definition;Crearemos el fichero TS0601.js y copiamos el código en el

paramos el docker

en configuration.yaml añadimos el fichero del converter
groups: {} external_converters: - TS0601.js - TS0202.jsArrancamos el docker y ya nos aparece el nuevo dispositivo

Ya podemos ver como empieza a exponer los datos

Físicamente una vez colocado quedaria así , con los grados en Fahrenheit 🙁

'0xa4c138f9601e97ca': friendly_name: '0xa4c138f9601e97ca' temperature_calibration: 0 temperature_precision: 1 humidity_calibration: 0 humidity_precision: 0Crearemos nuestros sensores
### TERMOMETRO ARCON CONGELADOR - state_topic: "zigbee2mqtt/temperatura_congelador" availability_topic: "zigbee2mqtt/bridge/state" unit_of_measurement: "°C" device_class: "temperature" value_template: "{{ value_json.temperature }}" name: "temperatura_lavadero" - state_topic: "zigbee2mqtt/temperatura_congelador" availability_topic: "zigbee2mqtt/bridge/state" unit_of_measurement: "°C" device_class: "temperature" value_template: "{{ value_json.temperature_external }}" name: "temperatura_congelador_temperatura" - state_topic: "zigbee2mqtt/temperatura_congelador" availability_topic: "zigbee2mqtt/bridge/state" unit_of_measurement: "%" device_class: "humidity" value_template: "{{ value_json.humidity }}" name: "temperatura_congelador_humedad" - state_topic: "zigbee2mqtt/temperatura_congelador" availability_topic: "zigbee2mqtt/bridge/state" unit_of_measurement: "%" icon: "mdi:battery" device_class: "battery" value_template: "{{ value_json.battery }}" expire_after: 86400 force_update: true name: "temperatura_congelador_bateria" - state_topic: "zigbee2mqtt/temperatura_congelador" availability_topic: "zigbee2mqtt/bridge/state" icon: "mdi:signal" unit_of_measurement: "lqi" value_template: "{{ value_json.linkquality }}" name: "temperatura_congelador_estado" - state_topic: "zigbee2mqtt/temperatura_congelador" availability_topic: "zigbee2mqtt/bridge/state" icon: "mdi:calendar-clock" value_template: "{{ value_json.last_seen }}" name: "temperatura_congelador_ultima_conexion"Y después de reiniciar veremos como va guardando los diferentes valores

Y con esto y un bizcocho …………
BONUS : Me tocaba bastante los webs ver los grados en Fahrenheit por lo que mire a ver como ponerlos en Celsius
Para ello cambiaremos el código del converter por este
const tuya = require('zigbee-herdsman-converters/lib/tuya'); const exposes = require('zigbee-herdsman-converters/lib/exposes'); const e = exposes.presets; const ea = exposes.access; const fzLocal = { tuya_weather_station: { cluster: 'manuSpecificTuya', type: ['commandDataReport', 'commandActiveStatusReport', 'commandMcuSyncTime'], convert: (model, msg, publish, options, meta) => { const result = {}; // Time synchro if (msg.type === 'commandMcuSyncTime') { (async () => { try { const endpoint = msg.endpoint; const now = new Date(); const utcTime = Math.round(now.getTime() / 1000); const localTime = utcTime - (now.getTimezoneOffset() * 60); const utcArray = [ (utcTime >> 24) & 0xFF, (utcTime >> 16) & 0xFF, (utcTime >> 8) & 0xFF, utcTime & 0xFF, ]; const localArray = [ (localTime >> 24) & 0xFF, (localTime >> 16) & 0xFF, (localTime >> 8) & 0xFF, localTime & 0xFF, ]; const payload = { payloadSize: 8, payload: [...utcArray, ...localArray], }; await endpoint.command('manuSpecificTuya', 'mcuSyncTime', payload, {disableDefaultResponse: true}); // set 24h time format await new Promise(resolve => setTimeout(resolve, 500)); try { await tuya.sendDataPointBool(endpoint, 17, false); } catch (e) { // Ignore if DP 17 don't exist } } catch (error) { // Ignore time synchro errors } })(); return {}; } if (!msg.data || !msg.data.dpValues) return {}; for (const dpValue of msg.data.dpValues) { const dp = dpValue.dp; const data = dpValue.data; let value; // temperature if (dpValue.datatype === 2) { // Reads the data as an unsigned big-endian 32-bit integer (Negative numbers will be wrong, eg. 429496724.6) // value = data.readUInt32BE(0); // Reads the data as a signed big-endian 32-bit integer (Negative numbers will be correct) value = data.readInt32BE(0); } else if (dpValue.datatype === 4) { value = data[0]; } else { value = data[0]; } switch (dp) { // temperature case 1: result.temperature = value / 10; break; // humidity case 2: result.humidity = value; break; // battery_state case 3: result.battery_state = value; result.battery = value === 0 ? 10 : (value === 1 ? 50 : 100); result.battery_low = value === 0; break; // temperature_unit (LCD display) case 9: result.temperature_unit = value === 0 ? 'celsius' : 'fahrenheit'; break; // time_format case 17: result.time_format = value ? '12h' : '24h'; break; // temperature_external case 38: result.temperature_external = value / 10; break; } } return result; }, }, }; const definition = { fingerprint: tuya.fingerprint('TS0601', ['_TZE284_hodyryli']), model: 'TS0601_weather_station', vendor: 'TuYa', description: 'Weather station with clock, internal/external temperature and humidity', fromZigbee: [fzLocal.tuya_weather_station], toZigbee: [tuya.tz.datapoints], configure: tuya.configureMagicPacket, exposes: [ e.temperature().withDescription('Internal temperature'), e.humidity().withDescription('Internal humidity'), e.numeric('temperature_external', ea.STATE) .withUnit('°C') .withDescription('External temperature sensor'), e.battery() .withDescription('Battery level (10%=low, 50%=medium, 100%=full)'), e.battery_low() .withDescription('Battery low warning'), e.enum('battery_state', ea.STATE, [0, 1, 2]) .withDescription('Raw battery state (0=low, 1=medium, 2=full)'), e.enum('temperature_unit', ea.STATE_SET, ['celsius', 'fahrenheit']) .withDescription('Temperature unit displayed on LCD screen'), e.enum('time_format', ea.STATE, ['12h', '24h']) .withDescription('Clock time format'), ], meta: { tuyaDatapoints: [ [1, 'temperature', tuya.valueConverter.divideBy10], [2, 'humidity', tuya.valueConverter.raw], [3, 'battery_state', tuya.valueConverter.raw], [9, 'temperature_unit', tuya.valueConverter.temperatureUnitEnum], [17, 'time_format', tuya.valueConverter.onOff], [38, 'temperature_external', tuya.valueConverter.divideBy10], ], }, }; module.exports = definition;Por defecto lo tendremos asi

Al consultar los ajustes nos aparece un nuevo selector Celsius / Fahrenheit

Cambiamos a Celsius y pulsamos varias veces para que se actualice

Y tachannnnnnnnnnnnnn ya aparece en Celsius

Hola Antonio!! LLegue a tu web buscando un tutorial de como instalar un ZBDongle-E en un QNAP TS 251D pero aun ando bastante liado jaja ojala me puedas dar una mano si tienes un tiempo libre!! Abrazo desde Argentina!!
Buenos dias
Cuando quieras lo miramos
Saludos