zigpy / zha-device-handlers

ZHA device handlers bridge the functionality gap created when manufacturers deviate from the ZCL specification, handling deviations and exceptions by parsing custom messages to and from Zigbee devices.
Apache License 2.0
695 stars 639 forks source link

[Device Support Request] - TS0601 by _TZE200_v1jqz5cy - Chlorine Meter PH ORP EC TDS Salinity Temp CL Tester Swimming Pool Water Quality Analyzer #2565

Open KirkKirk opened 10 months ago

KirkKirk commented 10 months ago

Problem description

Not supported device in ZHA

Smart WiFi Zigbee Chlorine Meter PH ORP EC TDS Salinity Temp CL Tester Swimming Pool Water Quality Analyzer

https://www.aliexpress.com/item/1005005575336871.html?spm=a2g0o.order_list.order_list_main.11.28e31802Wxn6Wl

Solution description

Add it to the supported device list in ZHA Please.

Screenshots/Video

Screenshots/Video [![image](https://github.com/zigpy/zha-device-handlers/assets/30799136/1d0bfbdc-8897-4c2f-bce7-a6ed9012923e)]

Device signature

Device signature ```json [{ "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0051", "input_clusters": [ "0x0000", "0x0004", "0x0005", "0xef00" ], "output_clusters": [ "0x000a", "0x0019" ] } }, "manufacturer": "_TZE200_v1jqz5cy", "model": "TS0601", "class": "zigpy.device.Device" }] ```

Diagnostic information

Diagnostic information ```json [{ "home_assistant": { "installation_type": "Home Assistant OS", "version": "2023.8.4", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.11.4", "docker": true, "arch": "aarch64", "timezone": "Australia/Sydney", "os_name": "Linux", "os_version": "6.1.21-v8", "supervisor": "2023.08.1", "host_os": "Home Assistant OS 10.5", "docker_version": "23.0.6", "chassis": "embedded", "run_as_root": true }, "custom_components": { "nodered": { "version": "2.2.0", "requirements": [] }, "smartthings": { "version": "1.0", "requirements": [ "pysmartapp==0.3.3", "pysmartthings==0.7.6" ] }, "dohome": { "version": "0.2.0", "requirements": [] }, "braviatv_psk": { "version": "0.4.2", "requirements": [ "pySonyBraviaPSK==0.2.4" ] }, "hacs": { "version": "1.32.1", "requirements": [ "aiogithubapi>=22.10.1" ] }, "truenas": { "version": "0.0.0", "requirements": [] }, "tesla_custom": { "version": "3.16.1", "requirements": [ "teslajsonpy==3.9.3" ] }, "sonoff": { "version": "3.5.2", "requirements": [ "pycryptodome>=3.6.6" ] }, "localtuya": { "version": "5.2.1", "requirements": [] }, "roborock": { "version": "1.0.11", "requirements": [ "python-roborock==0.32.3", "ical==5.0.0" ] } }, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "after_dependencies": [ "onboarding", "usb" ], "codeowners": [ "@dmulcahey", "@adminiuga", "@puddly" ], "config_flow": true, "dependencies": [ "file_upload" ], "documentation": "https://www.home-assistant.io/integrations/zha", "iot_class": "local_polling", "loggers": [ "aiosqlite", "bellows", "crccheck", "pure_pcapy3", "zhaquirks", "zigpy", "zigpy_deconz", "zigpy_xbee", "zigpy_zigate", "zigpy_znp" ], "requirements": [ "bellows==0.35.9", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.102", "zigpy-deconz==0.21.0", "zigpy==0.56.4", "zigpy-xbee==0.18.1", "zigpy-zigate==0.11.0", "zigpy-znp==0.11.4" ], "usb": [ { "vid": "10C4", "pid": "EA60", "description": "*2652*", "known_devices": [ "slae.sh cc2652rb stick" ] }, { "vid": "1A86", "pid": "55D4", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus v2" ] }, { "vid": "10C4", "pid": "EA60", "description": "*sonoff*plus*", "known_devices": [ "sonoff zigbee dongle plus" ] }, { "vid": "10C4", "pid": "EA60", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*tubeszb*", "known_devices": [ "TubesZB Coordinator" ] }, { "vid": "1A86", "pid": "7523", "description": "*zigstar*", "known_devices": [ "ZigStar Coordinators" ] }, { "vid": "1CF1", "pid": "0030", "description": "*conbee*", "known_devices": [ "Conbee II" ] }, { "vid": "10C4", "pid": "8A2A", "description": "*zigbee*", "known_devices": [ "Nortek HUSBZB-1" ] }, { "vid": "0403", "pid": "6015", "description": "*zigate*", "known_devices": [ "ZiGate+" ] }, { "vid": "10C4", "pid": "EA60", "description": "*zigate*", "known_devices": [ "ZiGate" ] }, { "vid": "10C4", "pid": "8B34", "description": "*bv 2010/10*", "known_devices": [ "Bitron Video AV2010/10" ] } ], "zeroconf": [ { "type": "_esphomelib._tcp.local.", "name": "tube*" }, { "type": "_zigate-zigbee-gateway._tcp.local.", "name": "*zigate*" }, { "type": "_zigstar_gw._tcp.local.", "name": "*zigstar*" }, { "type": "_slzb-06._tcp.local.", "name": "slzb-06*" } ], "is_built_in": true }, "data": { "ieee": "**REDACTED**", "nwk": 7411, "manufacturer": "_TZE200_v1jqz5cy", "model": "TS0601", "name": "_TZE200_v1jqz5cy TS0601", "quirk_applied": false, "quirk_class": "zigpy.device.Device", "manufacturer_code": 4098, "power_source": "Battery or Unknown", "lqi": null, "rssi": null, "last_seen": "2023-09-04T18:58:59", "available": true, "device_type": "EndDevice", "signature": { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0051", "input_clusters": [ "0x0000", "0x0004", "0x0005", "0xef00" ], "output_clusters": [ "0x000a", "0x0019" ] } }, "manufacturer": "_TZE200_v1jqz5cy", "model": "TS0601" }, "active_coordinator": false, "entities": [], "neighbors": [], "routes": [], "endpoint_names": [ { "name": "SMART_PLUG" } ], "user_given_name": "Pool Sensor", "device_reg_id": "9de124bce188ac54b74bf7f2d0ac920a", "area_id": "backyard", "cluster_details": { "1": { "device_type": { "name": "SMART_PLUG", "id": 81 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0001": { "attribute_name": "app_version", "value": 65 }, "0x0004": { "attribute_name": "manufacturer", "value": "_TZE200_v1jqz5cy" }, "0x0005": { "attribute_name": "model", "value": "TS0601" } }, "unsupported_attributes": {} }, "0x0004": { "endpoint_attribute": "groups", "attributes": {}, "unsupported_attributes": {} }, "0x0005": { "endpoint_attribute": "scenes", "attributes": {}, "unsupported_attributes": {} }, "0xef00": { "endpoint_attribute": null, "attributes": {}, "unsupported_attributes": {} } }, "out_clusters": { "0x0019": { "endpoint_attribute": "ota", "attributes": {}, "unsupported_attributes": {} }, "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} } } } } } }] ```

Logs

Logs ```python [Paste the logs here] ```

Custom quirk

Custom quirk ```python [Paste your custom quirk here] ```

Additional information

No response

tschiex commented 9 months ago

My feeling is that in the midst of my trials, I temporarily made my pH meter talkative. But the current quirk is clearly not doing the job. I would tend to think that @TheJulianJES was incorrect when he said

looking at the Z2M implementation, it uses the normal Tuya spell that we also use.

When I look at ZHA code, the spell is a series of attributes read:

await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);

but instead, Koenkk mentioned a required "DataQuery" message here.

And the code that Z2M uses to cast that sort of spell is:

await endpoint.command('manuSpecificTuya', 'dataQuery', {});

Looking into Tuya documentation here, a dataQuery is a command 0x03 sent to the MCU-cluster.

And my Zigbee sniffing of the initial dialog between the device and a Tuya gateway indeed contains an 'Unknown command: 0x03'.

I hope @TheJulianJES will find some time to look into this and tell me if I'm wrong (or not :-) ).

In the meantime, I will finish my addition of sensors for ORP, TDS, and Salt, set up a PR for HA, and will come back to this when @TheJulianJES enlightens us. I will ask Koenkk for more info too.

tschiex commented 9 months ago

Well, Koenkk (the maintainer of Z2M) confirmed:

The attribute read is something different. The data query is something else needed to get this one working.

So the current quirk very likely casts the wrong spell. I will have to go back to a previous version.

tschiex commented 9 months ago

@KirkKirk If you find time, and have HACS configured, could you try the following, after having paired with the pH Meter

  1. Install the ZHA toolkit from HACS: https://github.com/mdeweerd/zha-toolkit
  2. restart HA
  3. Go to the pHmeter page and copy its IEEE network address. It's in the ZigBee info (left box)
  4. Go to the developer tools, in the "Services" tab
  5. Select the service " ZHA Toolkit: Send Cluster Command"
  6. Paste the IEEE address in the Device reference
  7. select the "Target Endpoint" box (left) and type 1 in the input field
  8. In the Target cluster, type 61184 (this is 0XEF00, the Tuya manufacturer cluster)
  9. In the Command Id, type 3
  10. Then click the "Call Service" button at the bottom.

Wait A minute and then check the device again. Does it talk now?

KirkKirk commented 9 months ago

@tschiex unfortunately, no changes. Maybe didn't pass the call service command as I got an error and didn't know what else can do 20231027_151227

KirkKirk commented 9 months ago

@tschiex I apologize for any confusion caused by my previous statement. The readings are displayed in the management section!

image

sorry for my stupidity (I forgot to add the line "zha-toolkit" in the configuration file)

KirkKirk commented 9 months ago

@tschiex noticed that the data is not updating. Call service in the toolkit not reporting as well. To update the sensor data I have to delete a device, re-join to network, issue a call service in the toolkit, and read data in management. Hope this will help a bit

tschiex commented 9 months ago

Yep. That's the same for me. And apparently, it's also the case on Z2M...

tschiex commented 9 months ago

As I wrote on the Z2M side, the solution probably lies in the Zigbee traces I posted there. I just don't have time currently to dig this. Sorry guys.

KirkKirk commented 8 months ago

@TheJulianJES can you jump in and help on this, please?

TheJulianJES commented 8 months ago

And the code that Z2M uses to cast that sort of spell is:

await endpoint.command('manuSpecificTuya', 'dataQuery', {});

Looking into Tuya documentation here, a dataQuery is a command 0x03 sent to the MCU-cluster.

Hmm, I did not see this, as it's called here: https://github.com/Koenkk/zigbee-herdsman-converters/blob/3afd0be2a6dcc5f863d7499923b5884efb02c61a/src/lib/tuya.ts#L76C1-L78

We can't really hook onto events in quirks like Z2M can at the moment. But we can try "overriding the spell" to include that command though.


From an ealier message:

I realized that the spell function should be in the Enchantable cluster, not the Enchanted device. I used the TuyaNoBindPowerConfigurationCluster as a possibility, overloading spell with just:

class MyTuyaNoBindPowerConfigurationCluster(TuyaNoBindPowerConfigurationCluster):

    async def spell(self):
        """Cast spell, so the Tuya device works correctly."""
        self.debug("Executing spell on Tuya device %s", self.endpoint.device.ieee)
        # await basic_cluster.write_attributes({0xffde: 0x13})
        mcu_cluster = self.endpoints[1].in_clusters[3]
        await mcu_cluster.command(0x03)
        self.debug("Executed spell on Tuya device %s", self.endpoint.device.ieee)

What if you change the spell method to something like this:

    async def spell(self):
        """Cast spell, so the Tuya device works correctly."""
        # normal spell (also needed):
        self.debug("Executing spell on Tuya device %s", self.endpoint.device.ieee)
        attr_to_read = [4, 0, 1, 5, 7, 0xFFFE]
        basic_cluster = self.endpoint.device.endpoints[1].in_clusters[0]
        await basic_cluster.read_attributes(attr_to_read)
        self.debug("Executed spell on Tuya device %s", self.endpoint.device.ieee)

        # new part for maybe sending command with id 3 on `0xEF00` cluster
        self.debug("Executing data query spell on Tuya device %s", self.endpoint.device.ieee)
        tuya_manuf_cluster = self.endpoint.device.endpoints[1].in_clusters[TUYA_CLUSTER_ID]
        await tuya_manuf_cluster.command(0x03)
        self.debug("Executed data query spell on Tuya device %s", self.endpoint.device.ieee)

I think your issue was that you grabbed a wrong cluster: mcu_cluster = self.endpoints[1].in_clusters[3] (ID 3 is identify cluster, you want 0xEF00 for the cluster ID).


EDIT: We probably also need to change the cluster definition to include the data_query command, as zigpy will probably fail otherwise. Might be able to include that in TuyaManufCluster similar to this:

    server_commands = {
        0x03: foundation.ZCLCommandDef(
            "query_data", {}, False, is_manufacturer_specific=True
        ),
        TUYA_SET_DATA: foundation.ZCLCommandDef(
            "set_data", {"data": TuyaCommand}, False, is_manufacturer_specific=True
        ),
        TUYA_SEND_DATA: foundation.ZCLCommandDef(
            "send_data", {"data": TuyaCommand}, False, is_manufacturer_specific=True
        ),
        TUYA_SET_TIME: foundation.ZCLCommandDef(
            "set_time", {"time": TuyaTimePayload}, False, is_manufacturer_specific=True
        ),
    }
# ...
tschiex commented 6 months ago

I have edited my zigpy adding a TUYA_QUERY_DATA server command. I changed the spell as advised. My device is functional (it already was working ok). As for Z2M, updates only come when I send a new QUERY_DATA command.

What bothers me is that despite the creation of suitable units/measurements/sensors in ha/const.py components/zha and components/sensor, there are 2 sensor entitities missing in the reported entities (TDS aka Total Dissolved Solids and Sodium). The battery reports are also lacking. Finally, some entities lack their suffix (for Electrical conductivity for example). I don't understand why I get these different behaviors. The logs do not help...

The quirk is here: https://gist.github.com/tschiex/28237907a4f0c569015b1869c8ffe66a The edited HA core is here: https://github.com/tschiex/core/tree/TDS-ORP-CL-EC-PH-Na

If someone has an idea, please let me know.

Capture d’écran du 2024-01-04 17-56-56 .

tschiex commented 6 months ago

Slowly trying to get something out of Zha Entity registry matching... One more sensor. Capture d’écran du 2024-01-05 13-43-40

tschiex commented 6 months ago

This is it. All sensors are now recognized as entities by {Z}HA and updated each time a tuya data_query packet is sent.

@TheJulianJES I would need some minor support now to reach a decent state. It will likely be a small effort for you and a definitely painful one for me alone:

  1. I need to rescale the units (e.g., the pH is 74.0 above instead of 7.4).
  2. I need to get some method to read the battery level. The cluster I'm using looks like a poor choice.
  3. I need to add something that updates sensors (sends a data_query) from HA, when requested, like a service call. People will be able to poll the device when they need to. This is more satisfying than a systematic 10' periodic call, as in Z2M.

Then I will deliver a PR to zha-quirks, and ha/core.

The calibration commands and the max/min values (used for alarms) may be added at a later stage.

Capture d’écran du 2024-01-05 14-39-31

TheJulianJES commented 6 months ago

Awesome, I'll have a closer look later.

Regarding 1., there should be a multiplier attribute for the ZHA sensor which you can set to 0.01.

tschiex commented 6 months ago

Thanks. Found a useful _divisor for this case.

tschiex commented 6 months ago

Battery now working apparently.

Capture d’écran du 2024-01-06 13-36-41

ofirda commented 6 months ago

Thanks for the hard work! Stepping in here for some help since I too bought the device and connected it via the Zigbee gateway (tuya mobile app sees it and I can see its values there)

I would also like to have it in HA - right now it shows in Tuya as unsupported = device is found without entities.

I am trying to add it via ZHA, but I don't know how to setup the connection to the gateway.

Under the "Select the serial port for your Zigbee radio" I select enter manually and get these options:

Which one should I choose and what's the how do I find out the input paratmers of it?

tschiex commented 6 months ago

The code to make the device functional under ZHA is not yet included in ZHA + ZHA-device-handlers. You will have to wait a bit. It's not just a quirk, it requires some new sensor classes in ZHA and even some new units in HA.

As for Zigbee controllers, I would say that the EZSP way is advised with ZHA. I have a SONOFF (ZBDONGLE-E model). See this link, in the "RECOMMENDED ZIGBEE RADIO ADAPTERS AND MODULES" section.

tschiex commented 6 months ago

@TheJulianJES I understand you are busy. I will try two quickly answered questions. Short answers would help me move forward:

  1. The device has eight "AnalogOutput"-like datapoints. Should I use the number.py + "match quirk_id" approach here? Without any reaction, that's what I will try to do.
  2. I have no idea how to give access to a new service/entity that would allow users to emit a "data_query" packet and poll the device. A quick hint (anything similar that exists?) would be welcome.

Capture d’écran du 2024-01-07 11-31-16

ofirda commented 6 months ago

The code to make the device functional under ZHA is not yet included in ZHA + ZHA-device-handlers. You will have to wait a bit. It's not just a quirk, it requires some new sensor classes in ZHA and even some new units in HA.

As for Zigbee controllers, I would say that the EZSP way is advised with ZHA. I have a SONOFF (ZBDONGLE-E model). See this link, in the "RECOMMENDED ZIGBEE RADIO ADAPTERS AND MODULES" section.

Thanks Thomas

What would you say is the best way now for me to add this device to my HA and see its data in the dashboard?

TheJulianJES commented 6 months ago
  1. The device has eight "AnalogOutput"-like datapoints. Should I use the number.py + "match quirk_id" approach here? Without any reaction, that's what I will try to do.

Creating the number entities using number.py should be fine, yes. And yeah, I'd recommend matching by quirk id. A quirk id needs to be set in the quirk using quirk_id = "something.quirk.id (example which links to a constant). HA then needs to have the same string. Later, that string should be added to the quirk ids file in the quirks repo and then be imported from HA.

  1. I have no idea how to give access to a new service/entity that would allow users to emit a "data_query" packet and poll the device. A quick hint (anything similar that exists?) would be welcome.

Hmm, this is tricky. We could add a ZHA button entity maybe that sends that command. Otherwise, the homeassistant.update_entity service call already exists and should call async_update in the "entity class" IIRC. Similar to this: homeassistant/components/zha/light.py#L974-L979 The command could then be sent when async_update is triggered, but that would have to be called on one entity, so maybe a custom button is a better idea?

tschiex commented 6 months ago

Ok. Thanks @TheJulianJES .

quirk_id and number.py entities created (and lit looks like they work, they have consistent initial values). Here is how one block looks like:

@CONFIG_DIAGNOSTIC_MATCH(
    cluster_handler_names="tuya_manufacturer", quirk_ids=TUYA_POOL_SENSOR
)
# pylint: disable-next=hass-invalid-inheritance # needs fixing
class ChlorineMinValue(ZHANumberConfigurationEntity):
    """Representation of a ZHA Chlorine Concentration Maximum Value configuration entity."""

    _unique_id_suffix = "cl_min_value"
    _attr_entity_category = EntityCategory.CONFIG
    _attr_icon: str = ICONS[20]
    _attr_native_min_value: float = 0
    _attr_native_max_value: float = 15
    _attr_native_unit_of_measurement: str | None = UNITS[191]
    _attribute_name = "cl_min_value"
    _attr_translation_key: str = "cl_min_value"

But the created entities have not a "nice" name (_TZE200_v1jqz5cy TS0601 None). How could this be changed?

Capture d’écran du 2024-01-20 15-15-22

TheJulianJES commented 6 months ago

I can give you more detailed instructions later, but you'll need to add the translation key to the translation files and run the "language" script once.

tschiex commented 6 months ago

@TheJulianJES Ok. I have added a button:

@CONFIG_DIAGNOSTIC_MATCH(
    cluster_handler_names="tuya_manufacturer", quirk_ids=TUYA_POOL_SENSOR
)
class TuyaPoolSensorUpdateButton(ZHAAttributeButton):
    """Defines a ZHA update button for the Tuya pool sensor."""

    _unique_id_suffix = "update"
    _attribute_name = "update"
    _attribute_value = 1
    _attr_entity_category = EntityCategory.CONFIG
    _attr_translation_key = "update"

and modified the core/cluster_handlers/manufacturerspecific.py with:

    def __init__(self, cluster: zigpy.zcl.Cluster, endpoint: Endpoint) -> None:
        """Initialize TuyaClusterHandler."""
        super().__init__(cluster, endpoint)
        if endpoint.device.quirk_id == TUYA_PLUG_MANUFACTURER:
            self.ZCL_INIT_ATTRS = {
                "backlight_mode": True,
                "power_on_state": True,
            }
        if endpoint.device.quirk_id == TUYA_POOL_SENSOR:
            self.ZCL_INIT_ATTRS = {
                "ph_min_value": True,
                "ph_max_value": True,
                "cl_min_value": True,
                "cl_max_value": True,
                "ec_min_value": True,
                "ec_max_value": True,
                "orp_min_value": True,
                "orp_max_value": True,
                "update": True,
            }

I also added this to the quirk:

class PoolManufCluster(TuyaMCUCluster):
    """Tuya Manufacturer Cluster with Pool data points."""

    attributes = TuyaMCUCluster.attributes.copy()
    attributes.update(
        {
            # random attribute IDs
            0xEF01: ("ph_min_value", t.uint32_t, True),
            0xEF02: ("ph_max_value", t.uint32_t, True),
            0xEF03: ("cl_min_value", t.uint32_t, True),
            0xEF04: ("cl_max_value", t.uint32_t, True),
            0xEF05: ("ec_min_value", t.uint32_t, True),
            0xEF06: ("ec_max_value", t.uint32_t, True),
            0xEF07: ("orp_min_value", t.uint32_t, True),
            0xEF08: ("orp_max_value", t.uint32_t, True),
            0xEF09: ("update",t.Single, True),
        }
    )

    def _update_attribute(self, attrid: int, value: Any) -> None:
        """Catch button attribute to emit data_query."""
        super()._update_attribute(attrid, value)
        if attrid == "0xEF09":
            tuya_manuf_cluster = self.endpoint.device.endpoints[1].in_clusters[TuyaMCUCluster.cluster_id]
            tuya_manuf_cluster.command(0x03)

As this a chance to work? I feel I'm working as a blind coder :-)

tschiex commented 6 months ago

The button is there in the interface. It does something (as the Journal reports). Will prepare PRs. Information for translation is welcome. I tried to edit components/number/translation/en.json (adding translation for "cl_max_value") but it did no good.

Capture d’écran du 2024-01-20 16-46-30

TheJulianJES commented 6 months ago

https://developers.home-assistant.io/docs/internationalization/core/#test-translations for translations.

tschiex commented 6 months ago

@TheJulianJES Could you have a look at https://github.com/zigpy/zha-device-handlers/pull/2927 and more precisely https://github.com/zigpy/zha-device-handlers/actions/runs/7595993411/job/20689201853?pr=2927

The spell tests will not tolerate that a spell sends 2 messages. So my PR fails the tests, but I cannot do anything to pass them.

Rudo1111 commented 1 month ago

Hello, there is currently a possibility - how to load sensors from TS0601 _TZE200_v1jqz5cy via SkyConnect v1.0 in Home Assistant (ZHA). well thank you TS0601 _TZE200_v1jqz5cy

ftardif commented 3 days ago

Hi, Amazing to see all the good work behind this development. I understand this requires to synchronize ongoing changes in 3 components: quirk, ZHA and HA. Could we summarize the tickets and/or PR's for each of these in order to track the progresses?

What would normally be the process to move this forward? Is this currently blocked at a specific phase? Can I help in any way (test, dev, code review)? Again, thanks for the amazing work 👍

alexandrezia commented 3 days ago

To be honest, the thing is, I did all the merges from all PRs, commits, etc and build a local container, and got it running, Only to find out the device is a complete useless cheap sensor. I have two of them, just in case I got a defective one, and none of them is worth, I compared the PH with manual tests (stripe and liquid) and the sensor measurements are way out ... You have to recalibrate the PH sensor every week or less, the other sensors are kinda useless too, the only one that works well is the temperature, which I already have on my iAquaLink system.