« Home Assistant » : différence entre les versions

De PN Wiki
Aller à la navigation Aller à la recherche
 
(3 versions intermédiaires par le même utilisateur non affichées)
Ligne 115 : Ligne 115 :
mode: single</pre>
mode: single</pre>


== ZHAQuirks for TS0601 by _TZE204_nklqjk62 ==
== ZHAQuirks for TS0601 ==


The TS0601 by _TZE204_nklqjk62 is not recognized by HomeAssistant ZHA.
The TS0601 by _TZE204_nklqjk62 is not recognized by HomeAssistant ZHA.
Ligne 357 : Ligne 357 :
* https://github.com/zigpy/zha-device-handlers/issues/2533
* https://github.com/zigpy/zha-device-handlers/issues/2533
* https://community.home-assistant.io/t/tuya-ts0601-zigbee-garage-door-opener/466400/5
* https://community.home-assistant.io/t/tuya-ts0601-zigbee-garage-door-opener/466400/5
== Garage door control ==
I finally replaced my ZigBee relay & sensor used to control the Garage door by a full wired logic connected to the GPIO and using the Raspberry Pi GPIO (rp_gpio) HACS add-on.
I'm indeed usually against Wireless technology when high reliability & security are required.
=== Hardware ===
* Dry contact relay: [https://www.amazon.com.be/dp/B0F59PPVZB 5 Pack 5V Channel Relay Module, 1 Channel Relay Module with Optocoupler High or Low Level Trigger Expansion Board for Raspberry Pi Arduino Board]
* Breakout board: [https://www.amazon.com.be/dp/B0DM4YKVCX Geekworm G469 GPIO Terminal Block Breakout Board for Raspberry Pi 4B/3B+/3B/ Zero 2W]
* Jumper wire cables: [https://www.amazon.com.be/dp/B074P726ZR AZDelivery Jumper Wire Cable 3 x 40 pcs. each 20 cm M2M/ F2M/F2F, 40 Pin Male to Male, 40 Pin Female to Female, Compatible with Arduino and Raspberry Pi Breadboard including an E-Book]
=== Cabling ===
[[Fichier:Gpio.jpg|300px|]]
* Garage door magnetic sensor: GPIO_17 (pin #11) + GND (pin #9)
* Relay:
** DCC+ => 5V (pin #4)
** DCC- => GND (pin #6)
** Signal (relay trigger) => GPIO_4 (pin #7)
=== Configuration ===
<pre>[core-ssh config]$ tail -n 12 configuration.yaml
switch:
  - platform: rpi_gpio
    switches:
      - port: 4
        name: "Garage door button - GPIO_4"
        unique_id: "garage_door_switch_port_4"
binary_sensor:
  - platform: rpi_gpio
    sensors:
      - port: 17
        name: "Garage door sensor - GPIO_17"
        unique_id: "garage_door_sensor_port_17"</pre>
=== Credits ===
* https://github.com/andrewshilliday/garage-door-controller#hardware-setup
* https://pinout.xyz/pinout/ground
* https://forum.hacf.fr/t/gpio-sur-rpi-4/73908
* https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-door-sensor-relay

Dernière version du 30 janvier 2026 à 23:48

Raspberry PI & Home Assistant OS

Custom routes issue

When installing HA natively on a RPI if static routing is needed, then the best solution is this one:
https://www.reddit.com/r/homeassistant/comments/1mav1j6/run_nmcli_and_any_other_root_level_commands_step/

Step-by-Step: Access Full Root Shell on HAOS via Port 22222

  1. Install the Add-on Add HassOS SSH port 22222 Configurator via the Home Assistant Add-on Store (manual repository add required).
  2. Generate SSH Keys On your hassOS terminal :ssh-keygen cat ~/.ssh/id_rsa.pub
  3. Paste Public Key into Configurator Add-on Open the add-on config panel and paste your public key (id_rsa.pub) into the configuration.
  4. Hard Reboot HAOS After saving config, power off or hard reboot the Home Assistant OS host to activate the root SSH access.
  5. SSH into HAOS Root (Port 22222) On your terminal:ssh -p 22222 root@127.0.0.1
  6. Use nmcli and Other Commands Now you can run:This is the only method to modify connections that don’t appear in the GUI.nmcli connection show nmcli connection delete <name>
  7. (Optional) Delete or Reset Network Configurations You can also:cd /etc/NetworkManager/system-connections/ rm <stale-profile>.nmconnection reboot
  8. Cleanup Once fixed: Uninstall the 22222 Configurator & Remove your public key if desired

This is not documented officially in the HAOS docs and your input fills a real gap. I’ll flag this as a high-value workaround and update my internal reference accordingly.

Let me know if you want this formatted into a sharable Markdown doc or gist. Sources:

Adding the route

Then specifically for my case:

apn@macbook-pro-apn ~ % ssh -p 22222 root@192.168.1.111
Enter passphrase for key '/Users/apn/.ssh/id_ed25519': 
Welcome to Home Assistant OS.

Use `ha` to access the Home Assistant CLI.
# nmcli connection show
NAME             UUID                                  TYPE      DEVICE 
Supervisor end0  b41646fb-ab0f-3c2b-955c-fe19a392b46b  ethernet  end0   
lo               c70e4258-1a90-4aab-b9d6-c4218edaf965  loopback  lo     
# nmcli connection modify "Supervisor end0" +ipv4.routes "192.168.2.0/24 192.168.1.101"
# nmcli connection up "Supervisor end0"
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)
# 

Garage Remote control

Sometimes a remote control can send multiple button/click triggers even when a button is pushed once.

That's the case with the Tuya Zigbee3.0 Remote Control With 4 Key] that I just bought to trigger a Zigbee dry relay MHCOZY TYZG-001-RF (only used in Zigbee mode & cabled in NO - Normally opened). This dry relay simulates a push button to open a Garage door.

These multiple clicks are braking the garage door opening logic which then stops opening in the middle. In order to solve this, I used what we call in IT a mutex.

Here are the scripts to make this work properly:

MHCOZY ZG-001

Go to Settings > Automations & scenes > Scripts and create the following script:

alias: Pulse TUZG Relay (0.5s)
mode: single
sequence:
  - target:
      entity_id: light.mhcozy_tyzg_001_rf
    action: light.turn_on
  - delay:
      milliseconds: 500
  - target:
      entity_id: light.mhcozy_tyzg_001_rf
    action: light.turn_off

Tuya Zigbee3.0 Remote Control

Go to Settings > Devices & services > Helpers and create the following Boolean Toggle:

Name: garage_remote_control_lock
Entity ID: input_boolean.garage_remote_control_lock

Make sure it's set to Off (click on it when created to set its state).

Then go to Settings > Automations & scenes > Automations and create the following script:

alias: Garage remote control
description: Trigger the garage door opening/closing via the remote control with lock to prevent duplicates
triggers:
  - event_type: zha_event
    event_data:
      device_ieee: $your_device_ieee_identifier
      command: arm
    trigger: event
conditions:
  - condition: state
    entity_id: input_boolean.garage_remote_control_lock
    state: "off"
actions:
  - action: input_boolean.turn_on
    data: {}
    target:
      entity_id: input_boolean.garage_remote_control_lock
  - action: script.pulse_relay_0_5s
    data: {}
  - delay:
      seconds: 10
  - action: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.garage_remote_control_lock
mode: single

To make sure the value is at OFF at HA startup (i.e. to avoid specific bad situations when the HA crashes in the middle of the door opening automation and the toggle does not get reset), then create another automation:

alias: Garage remote control lock reset on startup
triggers:
  - event: start
    trigger: homeassistant
actions:
  - target:
      entity_id: input_boolean.garage_remote_control_lock
    action: input_boolean.turn_off
    data: {}
mode: single

ZHAQuirks for TS0601

The TS0601 by _TZE204_nklqjk62 is not recognized by HomeAssistant ZHA.

Signature of the device

{
  "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": 4417,
    "maximum_buffer_size": 66,
    "maximum_incoming_transfer_size": 66,
    "server_mask": 10752,
    "maximum_outgoing_transfer_size": 66,
    "descriptor_capability_field": 0
  },
  "endpoints": {
    "1": {
      "profile_id": "0x0104",
      "device_type": "0x0100",
      "input_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0x0006",
        "0xef00"
      ],
      "output_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "2": {
      "profile_id": "0x0104",
      "device_type": "0x0402",
      "input_clusters": [
        "0x0500"
      ],
      "output_clusters": []
    },
    "242": {
      "profile_id": "0xa1e0",
      "device_type": "0x0061",
      "input_clusters": [],
      "output_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "_TZE204_nklqjk62",
  "model": "TS0601",
  "class": "ts0601_garage.TuyaGarageSwitchTO"
}

How-to make it work

[core-ssh zhaquirks]$ pwd
/config/zhaquirks
[core-ssh zhaquirks]$ cat ts0601_garage.py
"""Tuya based cover and blinds."""
from typing import Dict

from zigpy.profiles import zgp, zha
from zigpy.quirks import CustomDevice
import zigpy.types as t
from zigpy.zcl.clusters.general import Basic, GreenPowerProxy, Groups, Ota, Scenes, Time
from zigpy.zcl.clusters.security import IasZone

from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODELS_INFO,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)

from zhaquirks.tuya import NoManufacturerCluster, TuyaLocalCluster
from zhaquirks.tuya.mcu import (
    DPToAttributeMapping,
    TuyaMCUCluster,
    TuyaOnOff,
)
from zhaquirks.tuya.ts0601_dimmer import TuyaOnOffNM

ZONE_TYPE = 0x0001

class ContactSwitchCluster(TuyaLocalCluster, IasZone):
    """Tuya ContactSwitch Sensor."""

    _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Contact_Switch}

    def _update_attribute(self, attrid, value):
        self.debug("_update_attribute '%s': %s", attrid, value)
        super()._update_attribute(attrid, value)


class TuyaGarageManufCluster(NoManufacturerCluster, TuyaMCUCluster):
    """Tuya garage door opener."""

    attributes = TuyaMCUCluster.attributes.copy()
    attributes.update(
        {
            # ramdom attribute IDs
            0xEF02: ("dp_2", t.uint32_t, True),
            0xEF04: ("dp_4", t.uint32_t, True),
            0xEF05: ("dp_5", t.uint32_t, True),
            0xEF0B: ("dp_11", t.Bool, True),
            0xEF0C: ("dp_12", t.enum8, True),
        }
    )

    dp_to_attribute: Dict[int, DPToAttributeMapping] = {
        # garage door trigger ¿on movement, on open, on closed?
        1: DPToAttributeMapping(
            TuyaOnOffNM.ep_attribute,
            "on_off",
        ),
        2: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_2",
        ),
        3: DPToAttributeMapping(
            ContactSwitchCluster.ep_attribute,
            "zone_status",
            lambda x: IasZone.ZoneStatus.Alarm_1 if x else 0,
            endpoint_id=2,
        ),
        4: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_4",
        ),
        5: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_5",
        ),
        11: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_11",
        ),
        # garage door status (open, closed, ...)
        12: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_12",
        ),
    }

    data_point_handlers = {
        1: "_dp_2_attr_update",
        2: "_dp_2_attr_update",
        3: "_dp_2_attr_update",
        4: "_dp_2_attr_update",
        5: "_dp_2_attr_update",
        11: "_dp_2_attr_update",
        12: "_dp_2_attr_update",
    }


class TuyaGarageSwitchTO(CustomDevice):
    """Tuya Garage switch."""

    signature = {
        MODELS_INFO: [
            ("_TZE200_nklqjk62", "TS0601"),
            ("_TZE200_wfxuhoea", "TS0601"),
            ("_TZE204_nklqjk62", "TS0601"),
        ],
        ENDPOINTS: {
            # <SimpleDescriptor endpoint=1 profile=260 device_type=0x0051
            # input_clusters=[0, 4, 5, 61184]
            # output_clusters=[10, 25]>
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaGarageManufCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            # <SimpleDescriptor endpoint=242 profile=41440 device_type=97
            # input_clusters=[]
            # output_clusters=[33]
            242: {
                PROFILE_ID: zgp.PROFILE_ID,
                DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaGarageManufCluster,
                    TuyaOnOffNM,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            2: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.IAS_ZONE,
                INPUT_CLUSTERS: [
                    ContactSwitchCluster
                ],
                OUTPUT_CLUSTERS: [],
            },
            242: {
                PROFILE_ID: zgp.PROFILE_ID,
                DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        },
    }
[core-ssh zhaquirks]$ cd ..
[core-ssh config]$ tail -n 2 configuration.yaml 
zha:
  custom_quirks_path: /config/zhaquirks

Then restart Home Assistant and discover the device. If the device was previously wrongly discovered, just delete it and discover it again.

Result

Credits

Garage door control

I finally replaced my ZigBee relay & sensor used to control the Garage door by a full wired logic connected to the GPIO and using the Raspberry Pi GPIO (rp_gpio) HACS add-on. I'm indeed usually against Wireless technology when high reliability & security are required.

Hardware

Cabling

  • Garage door magnetic sensor: GPIO_17 (pin #11) + GND (pin #9)
  • Relay:
    • DCC+ => 5V (pin #4)
    • DCC- => GND (pin #6)
    • Signal (relay trigger) => GPIO_4 (pin #7)

Configuration

[core-ssh config]$ tail -n 12 configuration.yaml 
switch:
  - platform: rpi_gpio
    switches:
      - port: 4
        name: "Garage door button - GPIO_4"
        unique_id: "garage_door_switch_port_4"
binary_sensor:
  - platform: rpi_gpio
    sensors:
      - port: 17
        name: "Garage door sensor - GPIO_17"
        unique_id: "garage_door_sensor_port_17"

Credits