Skip to content

[Device Support Request] Tuya SDM01V1.5 / Zemismart 3P+N energy monitor #3971

@validide

Description

@validide

Problem description

Hi,

I have a Zemismart 3P+N energy monitor (Tuya SDM01V1.5), Zigbee model TS0601 and manufacutrer _TZE204_gomuk3dc and this is not working with the fix from #3571.

Solution description

I have implemented the fix from Z2M and all of the sensors seem to be working.

The ones that are not working are:

  • apparent_power
  • power_factor
  • update_frequency - I have not yet fully tested this

Screenshots/Video

Screenshots/Video

Image

Device signature

Device signature
{
  "node_descriptor": {
    "logical_type": 1,
    "complex_descriptor_available": 0,
    "user_descriptor_available": 0,
    "reserved": 0,
    "aps_flags": 0,
    "frequency_band": 8,
    "mac_capability_flags": 142,
    "manufacturer_code": 4098,
    "maximum_buffer_size": 82,
    "maximum_incoming_transfer_size": 82,
    "server_mask": 11264,
    "maximum_outgoing_transfer_size": 82,
    "descriptor_capability_field": 0
  },
  "endpoints": {
    "1": {
      "profile_id": "0x0104",
      "device_type": "0x0051",
      "input_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0x0b04",
        "0xef00"
      ],
      "output_clusters": [
        "0x000a",
        "0x0019"
      ]
    }
  },
  "manufacturer": "_TZE204_gomuk3dc",
  "model": "TS0601"
}

Diagnostic information

Diagnostic information The file to large to paste here so I have attached it. [diag.json](https://github.com/user-attachments/files/19394821/diag.json)

Logs

Logs

Custom quirk

Custom quirk
class Tuya3PhaseElectricalMeasurementV1_5(ElectricalMeasurement, TuyaLocalCluster):
    """Tuya Electrical Measurement cluster."""

    _CONSTANT_ATTRIBUTES = {
        ElectricalMeasurement.AttributeDefs.ac_current_divisor.id: 1000,
        ElectricalMeasurement.AttributeDefs.ac_voltage_divisor.id: 10,
        ElectricalMeasurement.AttributeDefs.ac_frequency_divisor.id: 100,
    }


(
    TuyaQuirkBuilder("_TZE204_gomuk3dc", "TS0601")
    .applies_to("_TZE284_gomuk3dc", "TS0601")
    .applies_to("_TZE200_gomuk3dc", "TS0601")
    .tuya_sensor(
        dp_id=1,
        attribute_name="energy_consumed",
        type=t.uint32_t,
        divisor=100,
        state_class=SensorStateClass.TOTAL_INCREASING,
        device_class=SensorDeviceClass.ENERGY,
        unit=UnitOfEnergy.KILO_WATT_HOUR,
        fallback_name="Total energy",
    )
    .tuya_sensor(
        dp_id=23,
        attribute_name="energy_produced",
        type=t.uint32_t,
        divisor=100,
        state_class=SensorStateClass.TOTAL_INCREASING,
        device_class=SensorDeviceClass.ENERGY,
        unit=UnitOfEnergy.KILO_WATT_HOUR,
        translation_key="energy_produced",
        fallback_name="Energy produced",
    )
    .tuya_dp(
        dp_id=29,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="total_active_power",
    )
    .tuya_dp(
        dp_id=32,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="ac_frequency",
    )
    .tuya_sensor(
        dp_id=50,
        attribute_name="power_factor",
        type=t.uint8_t,
        state_class=SensorStateClass.MEASUREMENT,
        device_class=SensorDeviceClass.POWER_FACTOR,
        unit=PERCENTAGE,
        translation_key="total_power_factor",
        fallback_name="Total power factor",
    )
    # Update the frequency at which the device reports its data
    # did not manage to test this fully
    # .tuya_number(
    #     dp_id=102,
    #     attribute_name="update_frequency",
    #     type=t.uint16_t,
    #     device_class=SensorDeviceClass.DURATION,
    #     unit=UnitOfTime.SECONDS,
    #     min_value=5,
    #     max_value=3600,
    #     step=1,
    #     translation_key="update_frequency",
    #     fallback_name="Update frequency",
    #     access=foundation.ZCLAttributeAccess.Write,
    # )
    .tuya_dp(
        dp_id=103,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="rms_voltage_ph_a",
    )
    .tuya_dp(
        dp_id=104,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="rms_current_ph_a",
    )
    .tuya_dp(
        dp_id=105,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="active_power_ph_a",
    )
    .tuya_dp(
        dp_id=108,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="power_factor_ph_a",
    )
    .tuya_sensor(
        dp_id=109,
        attribute_name="energy_consumed_ph_a",
        type=t.uint32_t,
        divisor=100,
        state_class=SensorStateClass.TOTAL_INCREASING,
        device_class=SensorDeviceClass.ENERGY,
        unit=UnitOfEnergy.KILO_WATT_HOUR,
        translation_key="energy_ph_a",
        fallback_name="Energy phase A",
    )
    .tuya_sensor(
        dp_id=110,
        attribute_name="energy_produced_ph_a",
        type=t.uint32_t,
        divisor=100,
        state_class=SensorStateClass.TOTAL_INCREASING,
        device_class=SensorDeviceClass.ENERGY,
        unit=UnitOfEnergy.KILO_WATT_HOUR,
        translation_key="energy_produced_ph_a",
        fallback_name="Energy produced phase A",
    )
    .tuya_dp(
        dp_id=112,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="rms_voltage_ph_b",
    )
    .tuya_dp(
        dp_id=113,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="rms_current_ph_b",
    )
    .tuya_dp(
        dp_id=114,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="active_power_ph_b",
    )
    .tuya_dp(
        dp_id=117,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="power_factor_ph_b",
    )
    .tuya_sensor(
        dp_id=118,
        attribute_name="energy_consumed_ph_b",
        type=t.uint32_t,
        divisor=100,
        state_class=SensorStateClass.TOTAL_INCREASING,
        device_class=SensorDeviceClass.ENERGY,
        unit=UnitOfEnergy.KILO_WATT_HOUR,
        translation_key="energy_ph_b",
        fallback_name="Energy phase B",
    )
    .tuya_sensor(
        dp_id=119,
        attribute_name="energy_produced_ph_b",
        type=t.uint32_t,
        divisor=100,
        state_class=SensorStateClass.TOTAL_INCREASING,
        device_class=SensorDeviceClass.ENERGY,
        unit=UnitOfEnergy.KILO_WATT_HOUR,
        translation_key="energy_produced_ph_b",
        fallback_name="Energy produced phase B",
    )
    .tuya_dp(
        dp_id=121,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="rms_voltage_ph_c",
    )
    .tuya_dp(
        dp_id=122,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="rms_current_ph_c",
    )
    .tuya_dp(
        dp_id=123,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="active_power_ph_c",
    )
    .tuya_dp(
        dp_id=126,
        ep_attribute=Tuya3PhaseElectricalMeasurementV1_5.ep_attribute,
        attribute_name="power_factor_ph_c",
    )
    .tuya_sensor(
        dp_id=127,
        attribute_name="energy_consumed_ph_c",
        divisor=100,
        type=t.uint32_t,
        state_class=SensorStateClass.TOTAL_INCREASING,
        device_class=SensorDeviceClass.ENERGY,
        unit=UnitOfEnergy.KILO_WATT_HOUR,
        translation_key="energy_ph_c",
        fallback_name="Energy phase C",
    )
    .tuya_sensor(
        dp_id=128,
        attribute_name="energy_produced_ph_c",
        type=t.uint32_t,
        divisor=100,
        state_class=SensorStateClass.TOTAL_INCREASING,
        device_class=SensorDeviceClass.ENERGY,
        unit=UnitOfEnergy.KILO_WATT_HOUR,
        translation_key="energy_produced_ph_c",
        fallback_name="Energy produced phase C",
    )
    .adds(Tuya3PhaseElectricalMeasurementV1_5)
    # .skip_configuration() # Not sure why we would need to skip configuration
    .add_to_registry()
)

Additional information

I have implemented the quirk on a fork of the repo, would it be ok to create a pull request and discuss about any necessary code changes there?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions