Upload files to "/"
This commit is contained in:
commit
64f12e6a38
118
README.en.md
Normal file
118
README.en.md
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
[🇵🇱 Polish version](README.md)
|
||||||
|
|
||||||
|
|
||||||
|
# TS0601_BY_RK.js
|
||||||
|
Minimalist Zigbee2MQTT converter for Tuya TS0601 TRV heads (ON / OFF)
|
||||||
|
|
||||||
|
## Why this converter exists
|
||||||
|
|
||||||
|
This converter was created to solve a real-world problem:
|
||||||
|
some Tuya TS0601 thermostatic radiator valves generate a huge amount of Zigbee reports, which:
|
||||||
|
|
||||||
|
- spam MQTT
|
||||||
|
- cause constant state changes in Home Assistant
|
||||||
|
- increase CPU usage and database load
|
||||||
|
- destabilise automations
|
||||||
|
- provide no real value in everyday use
|
||||||
|
|
||||||
|
In installations with many TRVs (a dozen or more), this resulted in:
|
||||||
|
- Home Assistant slowdowns
|
||||||
|
- difficult troubleshooting
|
||||||
|
- unpredictable automation behaviour
|
||||||
|
|
||||||
|
## Conscious design decision
|
||||||
|
|
||||||
|
Instead of fighting every reported variable, a different approach was chosen:
|
||||||
|
|
||||||
|
minimalism over completeness
|
||||||
|
|
||||||
|
This converter:
|
||||||
|
- removes all unnecessary exposes
|
||||||
|
- ignores temperature, mode, and calibration reports
|
||||||
|
- reduces control to a single simple action: ON / OFF
|
||||||
|
|
||||||
|
Result:
|
||||||
|
- minimal Zigbee traffic
|
||||||
|
- no MQTT spam
|
||||||
|
- stable Home Assistant
|
||||||
|
- predictable automations
|
||||||
|
|
||||||
|
## How the converter works
|
||||||
|
|
||||||
|
Tuya TS0601 TRVs are controlled using datapoint DP=2 (setpoint).
|
||||||
|
|
||||||
|
Mapping:
|
||||||
|
- ON -> sends 45°C (valve forced fully open)
|
||||||
|
- OFF -> sends 0°C (valve fully closed)
|
||||||
|
|
||||||
|
Any other value:
|
||||||
|
- is treated as ON
|
||||||
|
- is not corrected back to avoid generating additional Zigbee traffic
|
||||||
|
|
||||||
|
The state is published immediately after sending the command, without waiting for further device reports.
|
||||||
|
|
||||||
|
## What is NOT exposed (by design)
|
||||||
|
|
||||||
|
This converter deliberately does NOT expose:
|
||||||
|
- target temperature
|
||||||
|
- operating modes
|
||||||
|
- calibration or offsets
|
||||||
|
- diagnostic data
|
||||||
|
|
||||||
|
This is not a bug or missing feature — it is a deliberate limitation to ensure system stability.
|
||||||
|
|
||||||
|
## Exposed features
|
||||||
|
|
||||||
|
- Switch (ON / OFF) – main valve control
|
||||||
|
- Battery (%) – if reported by the device
|
||||||
|
- Local temperature (°C) – passive only
|
||||||
|
|
||||||
|
## How to add the converter to Zigbee2MQTT
|
||||||
|
|
||||||
|
1. Copy the file TS0601_BY_RK.js to the Zigbee2MQTT directory, for example:
|
||||||
|
/zigbee2mqtt/external_converters/TS0601_BY_RK.js
|
||||||
|
|
||||||
|
If the external_converters directory does not exist, create it.
|
||||||
|
|
||||||
|
2. In /zigbee2mqtt/configuration.yaml add:
|
||||||
|
```
|
||||||
|
external_converters:
|
||||||
|
- TS0601_BY_RK.js
|
||||||
|
```
|
||||||
|

|
||||||
|
|
||||||
|
3. Restart Zigbee2MQTT
|
||||||
|
|
||||||
|
## How to add a new TRV (fingerprint)
|
||||||
|
|
||||||
|
If your TS0601 TRV is not supported, you need to add its identifier.
|
||||||
|
|
||||||
|
1. In Zigbee2MQTT, check:
|
||||||
|
- modelID
|
||||||
|
- manufacturerName
|
||||||
|
|
||||||
|
Example:
|
||||||
|
modelID: TS0601
|
||||||
|
manufacturerName: _TZE200_xxxxxxxx
|
||||||
|
|
||||||
|
2. In TS0601_BY_RK.js add a new fingerprint entry:
|
||||||
|
```
|
||||||
|
{ modelID: 'TS0601', manufacturerName: '_TZE200_NOWYID' }
|
||||||
|
```
|
||||||
|
<img width="1371" height="1282" alt="add new trv" src="https://github.com/user-attachments/assets/f1e24681-78da-4464-8183-a78c7d2229dd" />
|
||||||
|
|
||||||
|
3. Restart Zigbee2MQTT
|
||||||
|
|
||||||
|
## Who this converter is for
|
||||||
|
|
||||||
|
- installations with many TRVs
|
||||||
|
- systems sensitive to MQTT spam
|
||||||
|
- simple open / close valve control
|
||||||
|
- stable and predictable automations
|
||||||
|
|
||||||
|
It is NOT intended for users who expect full temperature control from Home Assistant.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
This converter does not try to be perfect.
|
||||||
|
Its goal is stability, silence, and predictable behaviour.
|
||||||
117
README.md
Normal file
117
README.md
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
[🇬🇧 English version](README.en.md)
|
||||||
|
|
||||||
|
|
||||||
|
# TS0601_BY_RK.js
|
||||||
|
Minimalistyczny konwerter Zigbee2MQTT dla głowic Tuya TS0601 (ON / OFF)
|
||||||
|
|
||||||
|
## Po co ten konwerter istnieje
|
||||||
|
|
||||||
|
Ten konwerter powstał jako rozwiązanie realnego problemu:
|
||||||
|
niektóre głowice termostatyczne Tuya TS0601 generują ogromne ilości raportów Zigbee, które:
|
||||||
|
|
||||||
|
- spamują MQTT
|
||||||
|
- powodują ciągłe zmiany stanów w Home Assistant
|
||||||
|
- zwiększają zużycie CPU i bazy danych
|
||||||
|
- destabilizują automatyzacje
|
||||||
|
- nie wnoszą realnej wartości w codziennym użytkowaniu
|
||||||
|
|
||||||
|
W instalacjach z wieloma głowicami (kilkanaście lub więcej) prowadziło to do:
|
||||||
|
- spowolnienia Home Assistant
|
||||||
|
- trudnej diagnostyki
|
||||||
|
- nieprzewidywalnego działania automatyzacji
|
||||||
|
|
||||||
|
## Świadoma decyzja projektowa
|
||||||
|
|
||||||
|
Zamiast walczyć z każdą raportowaną zmienną, przyjęto podejście:
|
||||||
|
|
||||||
|
minimalizm zamiast kompletności
|
||||||
|
|
||||||
|
Konwerter:
|
||||||
|
- usuwa wszystkie zbędne expose’y
|
||||||
|
- ignoruje raporty temperatur, trybów i kalibracji
|
||||||
|
- redukuje sterowanie do jednej prostej akcji: ON / OFF
|
||||||
|
|
||||||
|
Efekt:
|
||||||
|
- minimalny ruch Zigbee
|
||||||
|
- brak spamu MQTT
|
||||||
|
- stabilny Home Assistant
|
||||||
|
- przewidywalne automatyzacje
|
||||||
|
|
||||||
|
## Jak działa konwerter
|
||||||
|
|
||||||
|
Głowice Tuya TS0601 sterowane są poprzez datapoint DP=2 (setpoint).
|
||||||
|
|
||||||
|
Mapowanie:
|
||||||
|
- ON -> wysyłane 45°C (zawór wymuszony maksymalnie otwarty)
|
||||||
|
- OFF -> wysyłane 0°C (zawór zamknięty)
|
||||||
|
|
||||||
|
Każda inna wartość:
|
||||||
|
- traktowana jest jako ON
|
||||||
|
- nie jest korygowana zwrotnie, aby nie generować dodatkowego ruchu Zigbee
|
||||||
|
|
||||||
|
Stan publikowany jest natychmiast po wysłaniu komendy, bez oczekiwania na kolejne raporty z urządzenia.
|
||||||
|
|
||||||
|
## Co NIE jest udostępniane (celowo)
|
||||||
|
|
||||||
|
Ten konwerter świadomie nie udostępnia:
|
||||||
|
- temperatury zadanej
|
||||||
|
- trybów pracy
|
||||||
|
- kalibracji i offsetów
|
||||||
|
- danych diagnostycznych
|
||||||
|
|
||||||
|
Nie jest to błąd ani brak funkcji — to celowe ograniczenie, mające na celu stabilność systemu.
|
||||||
|
|
||||||
|
## Udostępnione expose
|
||||||
|
|
||||||
|
- Switch (ON / OFF) – główne sterowanie zaworem
|
||||||
|
- Battery (%) – jeśli urządzenie raportuje
|
||||||
|
- Local temperature (°C) – tylko pasywnie
|
||||||
|
|
||||||
|
## Jak dodać konwerter do Zigbee2MQTT
|
||||||
|
|
||||||
|
1. Skopiuj plik TS0601_BY_RK.js do katalogu Zigbee2MQTT, .:
|
||||||
|
/zigbee2mqtt/external_converters/TS0601_BY_RK.js
|
||||||
|
jesli katalog external_converters nie istnieje dodaj go
|
||||||
|
|
||||||
|
2. W pliku /zigbee2mqtt/configuration.yaml dodaj:
|
||||||
|
```
|
||||||
|
external_converters:
|
||||||
|
- TS0601_BY_RK.js
|
||||||
|
```
|
||||||
|

|
||||||
|
|
||||||
|
3. Zrestartuj Zigbee2MQTT
|
||||||
|
|
||||||
|
## Jak dodać nową głowicę (fingerprint)
|
||||||
|
|
||||||
|
Jeśli Twoja głowica TS0601 nie jest obsługiwana, należy dodać jej identyfikator.
|
||||||
|
|
||||||
|
1. W Zigbee2MQTT sprawdź:
|
||||||
|
- modelID
|
||||||
|
- manufacturerName
|
||||||
|
|
||||||
|
Przykład:
|
||||||
|
modelID: TS0601
|
||||||
|
manufacturerName: _TZE200_xxxxxxxx
|
||||||
|
|
||||||
|
2. W pliku TS0601_BY_RK.js dodaj nowy fingerprint do listy:
|
||||||
|
```
|
||||||
|
{ modelID: 'TS0601', manufacturerName: '_TZE200_NOWYID' }
|
||||||
|
```
|
||||||
|
<img width="1371" height="1282" alt="add new trv" src="https://github.com/user-attachments/assets/f1e24681-78da-4464-8183-a78c7d2229dd" />
|
||||||
|
|
||||||
|
4. Zrestartuj Zigbee2MQTT
|
||||||
|
|
||||||
|
## Dla kogo ten konwerter jest przeznaczony
|
||||||
|
|
||||||
|
- instalacje z wieloma głowicami TRV
|
||||||
|
- systemy wrażliwe na spam MQTT
|
||||||
|
- proste sterowanie otwórz / zamknij
|
||||||
|
- stabilne automatyzacje
|
||||||
|
|
||||||
|
Nie jest przeznaczony dla osób oczekujących pełnej kontroli temperatury z Home Assistant.
|
||||||
|
|
||||||
|
## Podsumowanie
|
||||||
|
|
||||||
|
Ten konwerter nie próbuje być idealny.
|
||||||
|
Jego celem jest stabilność, cisza i przewidywalność działania.
|
||||||
73
TS0601_BY_RK.js
Normal file
73
TS0601_BY_RK.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
const exposes = require('zigbee-herdsman-converters/lib/exposes');
|
||||||
|
const ea = exposes.access;
|
||||||
|
|
||||||
|
function intTo4BytesBE(value) {
|
||||||
|
return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendSetpoint(entity, setpoint) {
|
||||||
|
const payload = {
|
||||||
|
seq: 0,
|
||||||
|
dpValues: [{
|
||||||
|
dp: 2,
|
||||||
|
datatype: 0x02,
|
||||||
|
data: intTo4BytesBE(setpoint),
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
await entity.command('manuSpecificTuya', 'dataRequest', payload, {disableDefaultResponse: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
fingerprint: [
|
||||||
|
{ modelID: 'TS0601', manufacturerName: '_TZE200_b6wax7g0' },
|
||||||
|
{ modelID: 'TS0601', manufacturerName: '_TZE204_pcdmj88b' }
|
||||||
|
],
|
||||||
|
model: 'TS0601-TRV-MANUAL-RK',
|
||||||
|
vendor: 'Moes',
|
||||||
|
description: 'TS0601 TRV manual ON/OFF (ON=45, OFF=0, auto-sync)',
|
||||||
|
fromZigbee: [
|
||||||
|
{
|
||||||
|
cluster: 'manuSpecificTuya',
|
||||||
|
type: ['commandDataResponse', 'commandDataReport'],
|
||||||
|
convert: (model, msg, publish, options, meta) => {
|
||||||
|
const dp = msg.data.dpValues[0].dp;
|
||||||
|
const raw = msg.data.dpValues[0].data;
|
||||||
|
const value = raw[3]; // ostatni bajt wystarcza dla setpoint
|
||||||
|
|
||||||
|
if (dp === 2) {
|
||||||
|
if (value === 0) {
|
||||||
|
return {state: 'OFF', current_heating_setpoint: 0};
|
||||||
|
} else if (value >= 45) {
|
||||||
|
return {state: 'ON', current_heating_setpoint: 45};
|
||||||
|
} else {
|
||||||
|
// jeżeli przyjdzie np. 22 → traktujemy jako ON, ale poprawki nie wysyłamy z fromZigbee
|
||||||
|
return {state: 'ON', current_heating_setpoint: 45};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
toZigbee: [
|
||||||
|
{
|
||||||
|
key: ['state'],
|
||||||
|
convertSet: async (entity, key, value) => {
|
||||||
|
let setpoint = 0;
|
||||||
|
if (value.toLowerCase() === 'on') setpoint = 45;
|
||||||
|
if (value.toLowerCase() === 'off') setpoint = 0;
|
||||||
|
|
||||||
|
await sendSetpoint(entity, setpoint);
|
||||||
|
|
||||||
|
// natychmiast publikujemy nowy stan
|
||||||
|
return {state: {state: value.toUpperCase(), current_heating_setpoint: setpoint}};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
exposes: [
|
||||||
|
exposes.switch().withState('state', ea.ALL)
|
||||||
|
.withDescription('ON = valve forced open (45°C), OFF = valve closed (0°C)'),
|
||||||
|
exposes.numeric('battery', ea.STATE).withUnit('%').withDescription('Battery level'),
|
||||||
|
exposes.numeric('local_temperature', ea.STATE).withUnit('°C').withDescription('Measured local temperature'),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
Loading…
Reference in New Issue
Block a user