Skip to content

Conversation

@mrestivill
Copy link
Contributor

Device: Insoma SGW08Z
type: _TZE284_eaet5qt5

based on this PR: zigpy/zha-device-handlers#3556

onEvent: tuya.onEventSetTime,
configure: tuya.configureMagicPacket,
exposes: [
e.enum("valve_status_1", ea.STATE, ["manual", "auto", "idle"]).withDescription("Valve 1 status (manual, auto, idle)"),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
e.enum("valve_status_1", ea.STATE, ["manual", "auto", "idle"]).withDescription("Valve 1 status (manual, auto, idle)"),
e.enum("valve_status_l1", ea.STATE, ["manual", "auto", "idle"]).withDescription("Valve 1 status (manual, auto, idle)"),

Does this make sense to keep it consistent with switch l1/l2?

@Jaegerstefan
Copy link

the same device is also sold with the manufactor id _TZE284_fhvpaltk. Possibility to add this id too?

@Koenkk Koenkk merged commit a61f8d3 into Koenkk:master May 1, 2025
3 checks passed
@Koenkk
Copy link
Owner

Koenkk commented May 1, 2025

Thanks!

@ASDBigmac
Copy link

the same device is also sold with the manufactor id _TZE284_fhvpaltk. Possibility to add this id too?

Just trying to get exactly this working with the latest dev build. Power is not reported, the device also has only 2 batteries (not 4 as the other one) -> might this be the reason that no battery state is reported?

Also, while it reads the state, countdown, etc. correctly, activation of the valves only works manually via the button, not via Zigbee.

@Jaegerstefan : Do you see similar issues with your device?

@ASDBigmac
Copy link

also the getState buttons just expose an error -> z2m: No converter available for 'get' 'state' (undefined)

@grobian
Copy link

grobian commented May 11, 2025

I see the same with my SGW08Z, you cannot control the valves through zigbee, I only see feedback from pressing the buttons on the device.

@Giulio-Ladu
Copy link

I’m using the _TZE284_fhvpaltk iteration of the TS0601 watering device and I’m trying to set it up in Home Assistant. Could anyone provide guidance on how I can get this working? I’ve created a question on the forums, and any assistance would be greatly appreciated!

@grobian
Copy link

grobian commented May 11, 2025

@Giulio-Ladu you need to switch to koenkk/zigbee2mqtt:latest-dev docker image of zigbee2mqtt if you want to test this, latest release doesn't have the support yet. (Or at least that's what I understadn of it.)

@Giulio-Ladu
Copy link

@Giulio-Ladu you need to switch to koenkk/zigbee2mqtt:latest-dev docker image of zigbee2mqtt if you want to test this, latest release doesn't have the support yet. (Or at least that's what I understadn of it.)

Ah I see, thank you! I will await an update :)

@Aenos85
Copy link

Aenos85 commented May 15, 2025

Hey, I have the _TZE284_fhvpaltk and i switched to z2m edge. The device is now added but i cant switch the two switches. it get the update if i change manually at the device but if i change it in HA the state_l1 or 2 toggle but the valve_status_l1/2 stays on idle not manual

@samking86
Copy link

Hey, I have the _TZE284_fhvpaltk and i switched to z2m edge. The device is now added but i cant switch the two switches. it get the update if i change manually at the device but if i change it in HA the state_l1 or 2 toggle but the valve_status_l1/2 stays on idle not manual

I had the exact same issue with _TZE284_fhvpaltk — added fine in Zigbee2MQTT (Edge), but I couldn't switch either valve from Home Assistant. The state_l1/l2 toggles changed visually, but nothing happened physically. Also valve_status_l1/l2 stayed stuck on "idle".

After a lot of debugging, I created a custom external converter that fully fixes this behavior. The key was avoiding state_l1/l2 and instead using consistent custom property names like valve_l1/l2.

✅ Working features:

  • valve_l1 / valve_l2 → switches both valves correctly
  • countdown_l1 / _l2 → sets countdown timers
  • valve_status_l1 / _l2 → updates to "manual"/"remote"
  • battery from DP 59
  • Fully tested on Zigbee2MQTT Edge version

💾 Converter (drop this in /config/zigbee2mqtt/external_converters/ts0601_valve_custom.js):

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

module.exports = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZE284_fhvpaltk',
        },
    ],
    model: 'TS0601_valve_custom',
    vendor: 'Tuya',
    description: 'Custom working dual water valve with _l1/_l2 naming',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    exposes: [
        e.binary('valve_l1', ea.STATE_SET, 'ON', 'OFF'),
        e.binary('valve_l2', ea.STATE_SET, 'ON', 'OFF'),
        e.numeric('countdown_l1', ea.STATE_SET).withValueMin(0).withValueMax(255).withUnit('min'),
        e.numeric('countdown_l2', ea.STATE_SET).withValueMin(0).withValueMax(255).withUnit('min'),
        e.enum('valve_status_l1', ea.STATE, ['idle', 'manual', 'remote']),
        e.enum('valve_status_l2', ea.STATE, ['idle', 'manual', 'remote']),
        e.numeric('battery', ea.STATE).withUnit('%'),
    ],
    meta: {
        tuyaDatapoints: [
            [1, 'valve_l1', tuya.valueConverter.onOff],
            [2, 'valve_l2', tuya.valueConverter.onOff],
            [13, 'countdown_l1', tuya.valueConverter.countdown],
            [14, 'countdown_l2', tuya.valueConverter.countdown],
            [104, 'valve_status_l1', tuya.valueConverterBasic.lookup({
                idle: tuya.enum(2),
                manual: tuya.enum(0),
                remote: tuya.enum(1),
            })],
            [105, 'valve_status_l2', tuya.valueConverterBasic.lookup({
                idle: tuya.enum(2),
                manual: tuya.enum(0),
                remote: tuya.enum(1),
            })],
            [59, 'battery', tuya.valueConverter.raw],
        ],
    },
};

@ASDBigmac
Copy link

Can confirm this works, though the "last time it ran xxx seconds" is gone in contrast to the build-in converter.

Question: Shouldn't it show "auto" if controlled via Zigbee instead of "manual" == button press?

@samking86
Copy link

Thanks for confirming it works!

“Last time it ran xxx seconds”
Yeah — that was probably coming from a valve_duration_* expose in the built-in converter. I haven’t added that yet since it wasn’t needed for basic control, but happy to include it if you know which DP it maps to.

“Shouldn’t it show auto for Zigbee control?”
Good question — in my setup it reports remote (DP 104/105 = value 1) when controlled via Zigbee, and manual (value 0) when I press the button physically. But I’ve also seen reports that some devices reverse those values.

So it may depend on the firmware or valve revision. You could test the actual DP values using tuya_data_point_dump and compare what’s coming in?

@MrTeamaker
Copy link

Hi,
Thanks a lot for the converter file. Unfortunately it doesn't seem to work with my device.

The device is now shown as supported through the external definition file, however there is not actual link between what's shown in z2m and the physical device. Most exposed properties have a state of 'null'. Only the valve_11/12 have a non-null status, however this is not linked to the device as changing the state in z2m won't affect the device, nor will pressing the button be reported in z2m.

Any ideas what could be it? How can I help to get this to work? What were the things you played around with?

@samking86
Copy link

Hi, Thanks a lot for the converter file. Unfortunately it doesn't seem to work with my device.

The device is now shown as supported through the external definition file, however there is not actual link between what's shown in z2m and the physical device. Most exposed properties have a state of 'null'. Only the valve_11/12 have a non-null status, however this is not linked to the device as changing the state in z2m won't affect the device, nor will pressing the button be reported in z2m.

Any ideas what could be it? How can I help to get this to work? What were the things you played around with?

Hey, thanks for testing it out and for the detailed feedback!

I ran into exactly the same issue in earlier iterations — the device showing up, but no actual control or sync between Z2M and the physical valves.

Here's what helped in my case:

✅ I made sure I'm on the latest Zigbee2MQTT dev build (Edge)
→ This is required because stable Z2M versions don't yet fully support all Tuya TS0601 quirks for these valves.

✅ I used the _TZE284_fhvpaltk version, which seems to respond correctly to Tuya datapoint IDs:

  • Valve 1 on/off: DP 1
  • Valve 2 on/off: DP 2
  • Countdown timers: DP 13 + 14
  • Valve status: DP 104 + 105
  • Battery: DP 59

✅ It’s important the meta.tuyaDatapoints matches these IDs exactly. Some clones or firmware versions might use different ones, so that could explain the null values.


👇 How you can help debug:

  1. Go to your Z2M frontend and enable debug log level
  2. Press any physical button on the device
  3. Watch the MQTT log (or console) — it should print the datapoint ID + value
  4. Send me the output here — I’ll help map the correct IDs for your device

Once we know the correct datapoints for your device variant, I can help you adapt the converter file. Happy to collaborate on this — it took me a while to get it stable too 😅

Let me know!

@MrTeamaker
Copy link

Hi @samking86,

Sorry for the delay in responding. I've got my z2m running in proxmox and have been trying to figure out how to change from release V2.3.0 to the latest Edge. I haven't found a simple way to so yet so would appreciate any tips on how to do so.

In the meantime I've had a play with the device anyway, here is what I get in the log file:
info 2025-05-24 07:10:10z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Dual Retic Timer', payload '{"battery":36,"countdown_l1":null,"countdown_l2":null,"linkquality":69,"valve_l1":"ON","valve_l2":"OFF","valve_status_l1":null,"valve_status_l2":null}' info 2025-05-24 07:10:10z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Dual Retic Timer', payload '{"battery":36,"countdown_l1":null,"countdown_l2":null,"linkquality":103,"valve_l1":"ON","valve_l2":"OFF","valve_status_l1":"manual","valve_status_l2":null}' info 2025-05-24 07:10:10z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Dual Retic Timer', payload '{"battery":36,"countdown_l1":10,"countdown_l2":null,"linkquality":103,"valve_l1":"ON","valve_l2":"OFF","valve_status_l1":"manual","valve_status_l2":null}' info 2025-05-24 07:10:29z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Dual Retic Timer', payload '{"battery":36,"countdown_l1":10,"countdown_l2":null,"linkquality":103,"valve_l1":"OFF","valve_l2":"OFF","valve_status_l1":"manual","valve_status_l2":null}' info 2025-05-24 07:10:29z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/Dual Retic Timer', payload '{"battery":36,"countdown_l1":10,"countdown_l2":null,"linkquality":95,"valve_l1":"OFF","valve_l2":"OFF","valve_status_l1":"idle","valve_status_l2":null}'

In case it may be helpful, here's the database.db entry for my device:
{"id":10,"type":"EndDevice","ieeeAddr":"0x4c97a1fffef0d448","nwkAddr":52542,"manufId":4098,"manufName":"_TZE284_fhvpaltk","powerSource":"Battery","modelId":"TS0601","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[0,4,5,61184,0,60672],"outClusterList":[25,10],"clusters":{"genBasic":{"attributes":{"65487":14400,"65503":"���/i","65506":31,"65508":0,"modelId":"TS0601","manufacturerName":"_TZE284_fhvpaltk","stackVersion":0,"dateCode":"","appVersion":68}}},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":68,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"interviewState":"SUCCESSFUL","meta":{},"lastSeen":1748039633345}

Let me know where to from here.

@gitlonbil
Copy link

Hi, just adding that I used the /config/zigbee2mqtt/external_converters/ts0601_valve_custom.js script above today (24 May 2025) in Z2M version: 2.3.0-1 on my _TZE284_fhvpaltk and it was immediately detected and exposed both valves, the countdown timers, status and battery levels.

thank you for the work on this.

@MrTeamaker
Copy link

Hi @samking86,

Just a quick update. Not sure what happened but for some reason it seems to be working now. I once again clicked on the valve in the dashboard to open it but then got distracted and after about 20s the physical valve responded.

Having activated it a few more times, it seems that it is now working as expected, the valves can be manually triggered from Z2m, and the activation delay is now down to 5s.

Thanks for all your work and sorry for the troubles.

@LarsOde
Copy link

LarsOde commented May 31, 2025

I also dropped the above code into /config/zigbee2mqtt/external_converters/ts0601_valve_custom.js but it still doesn't expose anything... do I need something else? (I have Z2M in HA)
Edit: thinking about it, that code can't work for me, becuase of this:

`const exposes = require('zigbee-herdsman-converters/lib/exposes');

const e = exposes.presets;

const ea = exposes.access;

const tuya = require('zigbee-herdsman-converters/lib/tuya');`

can I circumvent this, since I don't have this package installed, since Im on HA installtion?

@MrTeamaker
Copy link

Hi @LarsOde,

I ended up moving my external_converters from the location that you have it, to .../zigbee2mqtt/data/external_converters and then it was able to load the .js and which did the trick for me and now it shows as
image

I don't know anything about the constants so can't comment on that part.

@scobby
Copy link

scobby commented Jun 3, 2025

@Koenkk
ok, that external converter from @samking86 seems to work. Looks a little bit different then the current production exposes view. but it works. Can someone merge this into master and adjust the UI-Interface according the current implementation?

@Koenkk
Copy link
Owner

Koenkk commented Jun 3, 2025

Can someone make a PR for this?

Could you make a PR by clicking here?

@SnowZucc
Copy link

SnowZucc commented Jun 6, 2025

Hi, when placing samking86's adapter in external_extensions, z2m rejects it and renames it to .invalid.
What's the proper way to debug this issue?

Also, the adapter hasn't made it to z2m edge yet right ?

Home Assistant OS
Core 2025.5.2
Supervisor 2025.05.3
Operating System 15.2

[2025-06-06 20:56:23] error: z2m: Failed to load external extension ' ts0601_valve_custom.js'. Check the code for syntax error and make sure it is up to date with the current Zigbee2MQTT version. [2025-06-06 20:56:23] error: z2m: Invalid external extension ' ts0601_valve_custom.js' was ignored and renamed to prevent interference with Zigbee2MQTT.

@tesnz076
Copy link

Just as per the instruction, External converter worked for me too. No need to add any lines to configuration.yaml file (chatGPT suggests that you have to). And also calling it "external" - works, rather than "custom". Also using latest Zigbee2MQTT Edge (if not latest for you, delete it and install again)

@LarsOde
Copy link

LarsOde commented Jun 13, 2025

what i notice, most of it works, few things not, like setting the watering duration, also state of switches doesn't update always

@chhonord
Copy link

I use the external converter from @samking86 . I see changes while pressing buttons on the device - but can't remote control the device. This is what is shown in the logs:

info 2025-06-13 20:37:24z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x0c2a6ffffea22309', payload '{"battery":null,"countdown_l1":9,"countdown_l2":3,"last_seen":"2025-06-13T20:37:00+02:00","linkquality":109,"state_l1":"ON","state_l2":"ON","valve_duration_l1":77,"valve_duration_l2":452,"valve_status_l1":"idle","valve_status_l2":"idle","voltage":null}'

info 2025-06-13 20:42:03z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x0c2a6ffffea22309', payload '{"battery":null,"countdown_l1":10,"countdown_l2":10,"last_seen":"2025-06-13T20:42:02+02:00","linkquality":105,"state_l1":"ON","state_l2":"ON","valve_duration_l1":77,"valve_duration_l2":452,"valve_status_l1":"manual","valve_status_l2":"manual","voltage":null}' info 2025-06-13 20:42:08z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x0c2a6ffffea22309', payload '{"battery":null,"countdown_l1":10,"countdown_l2":10,"last_seen":"2025-06-13T20:42:07+02:00","linkquality":105,"state_l1":"ON","state_l2":"ON","valve_duration_l1":77,"valve_duration_l2":13,"valve_status_l1":"manual","valve_status_l2":"manual","voltage":null}' info 2025-06-13 20:42:09z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x0c2a6ffffea22309', payload '{"battery":null,"countdown_l1":10,"countdown_l2":10,"last_seen":"2025-06-13T20:42:07+02:00","linkquality":109,"state_l1":"ON","state_l2":"OFF","valve_duration_l1":77,"valve_duration_l2":13,"valve_status_l1":"manual","valve_status_l2":"manual","voltage":null}' info 2025-06-13 20:42:14z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x0c2a6ffffea22309', payload '{"battery":null,"countdown_l1":10,"countdown_l2":10,"last_seen":"2025-06-13T20:42:13+02:00","linkquality":76,"state_l1":"ON","state_l2":"OFF","valve_duration_l1":77,"valve_duration_l2":13,"valve_status_l1":"manual","valve_status_l2":"idle","voltage":null}' info 2025-06-13 20:42:14z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x0c2a6ffffea22309', payload '{"battery":null,"countdown_l1":10,"countdown_l2":10,"last_seen":"2025-06-13T20:42:13+02:00","linkquality":109,"state_l1":"ON","state_l2":"OFF","valve_duration_l1":12,"valve_duration_l2":13,"valve_status_l1":"manual","valve_status_l2":"idle","voltage":null}' info 2025-06-13 20:42:14z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x0c2a6ffffea22309', payload '{"battery":null,"countdown_l1":10,"countdown_l2":10,"last_seen":"2025-06-13T20:42:13+02:00","linkquality":109,"state_l1":"OFF","state_l2":"OFF","valve_duration_l1":12,"valve_duration_l2":13,"valve_status_l1":"manual","valve_status_l2":"idle","voltage":null}' info 2025-06-13 20:42:14z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x0c2a6ffffea22309', payload '{"battery":null,"countdown_l1":10,"countdown_l2":10,"last_seen":"2025-06-13T20:42:13+02:00","linkquality":109,"state_l1":"OFF","state_l2":"OFF","valve_duration_l1":12,"valve_duration_l2":13,"valve_status_l1":"idle","valve_status_l2":"idle","voltage":null}' info 2025-06-13 20:42:17z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x0c2a6ffffea22309', payload '{"battery":null,"countdown_l1":10,"countdown_l2":10,"last_seen":"2025-06-13T20:42:13+02:00","linkquality":109,"state_l1":"OFF","state_l2":"ON","valve_duration_l1":12,"valve_duration_l2":13,"valve_status_l1":"idle","valve_status_l2":"idle","voltage":null}' info 2025-06-13 20:42:33z2m:mqtt: MQTT publish: topic 'zigbee2mqtt/0x0c2a6ffffea22309', payload '{"battery":null,"countdown_l1":10,"countdown_l2":10,"last_seen":"2025-06-13T20:42:13+02:00","linkquality":109,"state_l1":"OFF","state_l2":"OFF","valve_duration_l1":12,"valve_duration_l2":13,"valve_status_l1":"idle","valve_status_l2":"idle","voltage":null}'

Any ideas what I need to change?

@MadAimBln
Copy link

@SnowZucc Did you resolved your problem? I habe the same issue and i'm not able to get it working.

Home assistant with Zigbee2MQTT and all without docker container. I can see it changes the countdown_l1 and countdown_l2 but it is not running and the status always stays "idle".
I only can manually click the Buttons at the device. But nothing smart online is working.

@LarsOde
Copy link

LarsOde commented Jun 15, 2025

I moved it back to Tuya... need the stuff working in summer ;)

@MadAimBln
Copy link

Thanks for the reply. An other ideas or tips? I would prefer to make it work with HA

@LarsOde
Copy link

LarsOde commented Jun 15, 2025

oh, it's still in HA... I have my humidity sensors still in MQTT, only moved the water tap to Tuya, and use that with the Tuya integration

@Aenos85
Copy link

Aenos85 commented Jun 15, 2025

I have the same problems, after adding the device to z2m all works ok. If switch is changed to on the state changes to manual and all works. After 1-2 days it do not works anymore. I have 3 devices and all have the same behaviour.

Strange side node, I have a similar behaviour with a fan aswell. Add it new and all works fine. After a few days all works, only the on/off switch do not work. All other settings are working as expected. (WLAN connected via Tuya )

@MadAimBln
Copy link

For me it was working no time at all. It never opened the valve or changed the status to auto

@SnowZucc
Copy link

@MadAimBln sadly no, my z2m still rejects the .js adapter and I have not found why

@Aenos85
Copy link

Aenos85 commented Jun 16, 2025

Ok the original config from z2m edge do not work for me. Like you discribed the state do not change. But I used @samking86 solution and added the duration in it. This seems to work. To be sure I first added the converter file, then deleted the added valve devices restart z2m and added devices new. I had some problems in the past, that it stops working after a period but atm it works.

File: zigbee2mqtt/external_converters/ts0601_value.js

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

module.exports = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZE284_fhvpaltk',
        },
    ],
    model: 'TS0601_valve_custom',
    vendor: 'Tuya',
    description: 'Custom working dual water valve with _l1/_l2 naming',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    exposes: [
        e.binary('valve_l1', ea.STATE_SET, 'ON', 'OFF'),
        e.binary('valve_l2', ea.STATE_SET, 'ON', 'OFF'),
        e.numeric('countdown_l1', ea.STATE_SET).withValueMin(0).withValueMax(255).withUnit('min'),
        e.numeric('countdown_l2', ea.STATE_SET).withValueMin(0).withValueMax(255).withUnit('min'),
        e.enum('valve_status_l1', ea.STATE, ['idle', 'manual', 'remote']),
        e.enum('valve_status_l2', ea.STATE, ['idle', 'manual', 'remote']),
		e.numeric("valve_duration", ea.STATE).withUnit("s").withDescription("Valve 1 irrigation last duration in seconds").withEndpoint("l1"),
		e.numeric("valve_duration", ea.STATE).withUnit("s").withDescription("Valve 2 irrigation last duration in seconds").withEndpoint("l2"),
        e.numeric('battery', ea.STATE).withUnit('%'),
    ],
    meta: {
        tuyaDatapoints: [
            [1, 'valve_l1', tuya.valueConverter.onOff],
            [2, 'valve_l2', tuya.valueConverter.onOff],
            [13, 'countdown_l1', tuya.valueConverter.countdown],
            [14, 'countdown_l2', tuya.valueConverter.countdown],
			[25, "valve_duration_l1", tuya.valueConverter.raw], // Valve 1 duration
			[26, "valve_duration_l2", tuya.valueConverter.raw], // Valve 2 duration
            [104, 'valve_status_l1', tuya.valueConverterBasic.lookup({
                idle: tuya.enum(2),
                manual: tuya.enum(0),
                remote: tuya.enum(1),
            })],
            [105, 'valve_status_l2', tuya.valueConverterBasic.lookup({
                idle: tuya.enum(2),
                manual: tuya.enum(0),
                remote: tuya.enum(1),
            })],
            [59, 'battery', tuya.valueConverter.raw],
        ],
    },
};
`

@MadAimBln
Copy link

I have still the same issue. The js file is renamed with invalid after restart of zigbee2mqtt.

Home Assistant without docker. With Zigbee2MQTT AddOn

'''
ts0601_value.js contains invalid code: mod is not a constructor

z2m: Failed to load external extension 'ts0601_value.js'. Check the code for syntax error and make sure it is up to date with the current Zigbee2MQTT version.
'''

@Aenos85
Copy link

Aenos85 commented Jun 19, 2025

Can you try to use the edge Version? ( Separat z2m Edge addon . You have to stop the normal addon and Install the Edge addon)

@SnowZucc
Copy link

SnowZucc commented Jun 19, 2025

I just tried using z2m Edge, and it still renames it to invalid for me.

Using the latest Edge version that I just downloaded

@MadAimBln
Copy link

Same here. Z2m edge and renamed to invalid.

And via GUI

ts0601_value.js contains invalid code: mod is not a constructor

z2m: Failed to load external extension 'ts0601_value.js'. Check the code for syntax error and make sure it is up to date with the current Zigbee2MQTT version.

@ThorstenDtk
Copy link

It worked for me. The device can be controlled from the devices tab

image

but not from the dashboard:

image

Not a big problem. But does anybody know how this can be fixed?

@xs400dohc
Copy link
Contributor

Can confirm, the code of @Aenos85 is working in device-tab and Homeassistant, but not in dashboard. But the dashboard I never used.
I just changed 'valve_status_l1' and 'valve_status_l2' to ON and OFF, because the state can only have two values.
Here is the code I use:

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

module.exports = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZE284_fhvpaltk',
        },
    ],
    model: 'TS0601_valve_custom',
    vendor: 'Tuya',
    description: 'Custom working dual water valve with _l1/_l2 naming',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    exposes: [
        e.binary('valve_l1', ea.STATE_SET, 'ON', 'OFF'),
        e.binary('valve_l2', ea.STATE_SET, 'ON', 'OFF'),
        e.numeric('countdown_l1', ea.STATE_SET).withValueMin(0).withValueMax(255).withUnit('min'),
        e.numeric('countdown_l2', ea.STATE_SET).withValueMin(0).withValueMax(255).withUnit('min'),
        e.enum('valve_status_l1', ea.STATE, ['idle', 'manual', 'remote']),
        e.enum('valve_status_l2', ea.STATE, ['idle', 'manual', 'remote']),
		e.numeric("valve_duration", ea.STATE).withUnit("s").withDescription("Valve 1 irrigation last duration in seconds").withEndpoint("l1"),
		e.numeric("valve_duration", ea.STATE).withUnit("s").withDescription("Valve 2 irrigation last duration in seconds").withEndpoint("l2"),
        e.numeric('battery', ea.STATE).withUnit('%'),
    ],
    meta: {
        tuyaDatapoints: [
            [1, 'valve_l1', tuya.valueConverter.onOff],
            [2, 'valve_l2', tuya.valueConverter.onOff],
            [13, 'countdown_l1', tuya.valueConverter.countdown],
            [14, 'countdown_l2', tuya.valueConverter.countdown],
			[25, "valve_duration_l1", tuya.valueConverter.raw], // Valve 1 duration
			[26, "valve_duration_l2", tuya.valueConverter.raw], // Valve 2 duration
            [104, 'valve_status_l1', tuya.valueConverterBasic.lookup({
                OFF: tuya.enum(2),
                ON: tuya.enum(0),
            })],
            [105, 'valve_status_l2', tuya.valueConverterBasic.lookup({
                OFF: tuya.enum(2),
                ON: tuya.enum(0),
            })],
            [59, 'battery', tuya.valueConverter.raw],
        ],
    },
};

If some more can confirm, that the code is working, I could make a pull-request so the not-working-code is replaced.

Is there someone also having "_TZE284_8zizsafo" or "_TZE284_iilebqoo"? Think, these can also use this code, because they are having the same datapoints. If someone can confirm the code is also working with these devices, we can merge the codes and white-label these devices.

@chhonord
Copy link

Any idea what to do?
Pressing buttons on the device reflects in status changes at the devices tab.
Trying to turn off valves via devices tab does not work :-(

@wariosc
Copy link

wariosc commented Jun 28, 2025

Can confirm, the code of @Aenos85 is working in device-tab and Homeassistant, but not in dashboard. But the dashboard I never used. I just changed 'valve_status_l1' and 'valve_status_l2' to ON and OFF, because the state can only have two values. Here is the code I use:

const exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

module.exports = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZE284_fhvpaltk',
        },
    ],
    model: 'TS0601_valve_custom',
    vendor: 'Tuya',
    description: 'Custom working dual water valve with _l1/_l2 naming',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    exposes: [
        e.binary('valve_l1', ea.STATE_SET, 'ON', 'OFF'),
        e.binary('valve_l2', ea.STATE_SET, 'ON', 'OFF'),
        e.numeric('countdown_l1', ea.STATE_SET).withValueMin(0).withValueMax(255).withUnit('min'),
        e.numeric('countdown_l2', ea.STATE_SET).withValueMin(0).withValueMax(255).withUnit('min'),
        e.enum('valve_status_l1', ea.STATE, ['idle', 'manual', 'remote']),
        e.enum('valve_status_l2', ea.STATE, ['idle', 'manual', 'remote']),
		e.numeric("valve_duration", ea.STATE).withUnit("s").withDescription("Valve 1 irrigation last duration in seconds").withEndpoint("l1"),
		e.numeric("valve_duration", ea.STATE).withUnit("s").withDescription("Valve 2 irrigation last duration in seconds").withEndpoint("l2"),
        e.numeric('battery', ea.STATE).withUnit('%'),
    ],
    meta: {
        tuyaDatapoints: [
            [1, 'valve_l1', tuya.valueConverter.onOff],
            [2, 'valve_l2', tuya.valueConverter.onOff],
            [13, 'countdown_l1', tuya.valueConverter.countdown],
            [14, 'countdown_l2', tuya.valueConverter.countdown],
			[25, "valve_duration_l1", tuya.valueConverter.raw], // Valve 1 duration
			[26, "valve_duration_l2", tuya.valueConverter.raw], // Valve 2 duration
            [104, 'valve_status_l1', tuya.valueConverterBasic.lookup({
                OFF: tuya.enum(2),
                ON: tuya.enum(0),
            })],
            [105, 'valve_status_l2', tuya.valueConverterBasic.lookup({
                OFF: tuya.enum(2),
                ON: tuya.enum(0),
            })],
            [59, 'battery', tuya.valueConverter.raw],
        ],
    },
};

If some more can confirm, that the code is working, I could make a pull-request so the not-working-code is replaced.

Is there someone also having "_TZE284_8zizsafo" or "_TZE284_iilebqoo"? Think, these can also use this code, because they are having the same datapoints. If someone can confirm the code is also working with these devices, we can merge the codes and white-label these devices.

I've used the same code and it is working both on Z2M and simple automation (on/off valve).

@chhonord
Copy link

chhonord commented Jul 2, 2025

@rejo007 Doesn't work for me :-( How/where did you debug? Need to get this thing running before holiday :-)

@joba-1
Copy link

joba-1 commented Jul 5, 2025

I used @wariosc 's code and it works.
Just noticed a minor flaw: if operated by the physical buttons the separate attribute in the ui is updated but not the toggle switch.

p.s.: first I needed to pull latest from github (was 2.4.0, now is 2.5.1)
p.p.s.: not to mention the nice device icon is missing now :D

@joba-1
Copy link

joba-1 commented Jul 6, 2025

hm, minor flaw gone. Now ui button state always = valve state. Maybe it was a browser cache issue.
And got device picture back by using the same model name as before (TS0601_water_switch)

@jeongpiano
Copy link

It works good. Thank you very much.

@arungria
Copy link

Did you find a way to make it work properly?
With the above instructions using the .js it works well for two weeks or so. Then, it randomly stops accepting orders (opening or closing the valves) until you physically use the buttons.
Thanks! :)

@joba-1
Copy link

joba-1 commented Sep 15, 2025

not used mine for several weeks and switched both valves on and off now without problem

@arungria
Copy link

not used mine for several weeks and switched both valves on and off now without problem

Nice, thanks! It might be due to the link quality in my device 👍 I'll see in some weeks

@arungria
Copy link

arungria commented Oct 2, 2025

not used mine for several weeks and switched both valves on and off now without problem

Nice, thanks! It might be due to the link quality in my device 👍 I'll see in some weeks

After connecting the device to a closer router it seems to be working fine now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.