Upload files to "/"

This commit is contained in:
rafal 2026-01-18 23:47:47 +00:00
commit 64f12e6a38
3 changed files with 308 additions and 0 deletions

118
README.en.md Normal file
View 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
```
![conf](https://github.com/user-attachments/assets/a7057153-2b3a-4db5-b2d1-ac4f3d0719c9)
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
View 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 exposey
- 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
```
![conf](https://github.com/user-attachments/assets/a7057153-2b3a-4db5-b2d1-ac4f3d0719c9)
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
View 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'),
],
},
];