Closed B-Hartley closed 3 years ago
I'm unsure which bits are needed, I think this is the whole pairing / setup sequence.
[0x0000:zdo] ZDO request ZDOCmd.Mgmt_Permit_Joining_req: [60, <Bool.false: 0>]
Device 0xa43a (00:15:8d:00:03:87:7f:49) joined the network
[0xa43a:zdo] ZDO request ZDOCmd.Device_annce: [0xA43A, 00:15:8d:00:03:87:7f:49, 128]
[0xa43a] Requesting 'Node Descriptor'
[0xa43a] Extending timeout for 0x2a request
[0xa43a] Node Descriptor: NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=128, manufacturer_code=4467, maximum_buffer_size=127, maximum_incoming_transfer_size=100, server_mask=11264, maximum_outgoing_transfer_size=100, descriptor_capability_field=0)
[0xa43a] Discovering endpoints
[0xa43a] Extending timeout for 0x2c request
[0xa43a] Discovered endpoints: [1, 2]
[0xa43a:1] Discovering endpoint information
[0xa43a] Extending timeout for 0x2e request
Device 0xa43a (00:15:8d:00:03:87:7f:49) joined the network
Skip initialization for existing device 00:15:8d:00:03:87:7f:49
[0xa43a:zdo] ZDO request ZDOCmd.Device_annce: [0xA43A, 00:15:8d:00:03:87:7f:49, 128]
[0xa43a] Extending timeout for 0x42 request
[0xa43a:1] Discovered endpoint information: SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=770, device_version=1, input_clusters=[0, 1, 3, 1026, 1037, 32], output_clusters=[25])
[0xa43a] Extending timeout for 0x44 request
[0xa43a:1:0x0000] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=68 command_id=Command.Read_Attributes_rsp>
[0xa43a:1] Manufacturer: Titan Products Ltd
[0xa43a:1] Model: TPZRCO2HT-Z3
[0xa43a:2] Discovering endpoint information
[0xa43a] Extending timeout for 0x54 request
[0xa43a:2] Discovered endpoint information: SizePrefixedSimpleDescriptor(endpoint=2, profile=260, device_type=775, device_version=1, input_clusters=[0, 1, 3, 1029], output_clusters=[])
Checking quirks for Titan Products Ltd TPZRCO2HT-Z3 (00:15:8d:00:03:87:7f:49)
device - 0xA43A:00:15:8d:00:03:87:7f:49 entering async_device_initialized - is_new_join: True
device - 0xA43A:00:15:8d:00:03:87:7f:49 has joined the ZHA zigbee network
[0xA43A](TPZRCO2HT-Z3): started configuration
[0xA43A:ZDO](TPZRCO2HT-Z3): 'async_configure' stage succeeded
[0xa43a] Extending timeout for 0x58 request
[0xa43a] Extending timeout for 0x5a request
[0xa43a] Extending timeout for 0x5c request
[0xA43A:1:0x0402]: bound 'temperature' cluster: Status.SUCCESS
[0xa43a] Extending timeout for 0x5e request
[0xA43A:1:0x0001]: bound 'power' cluster: Status.SUCCESS
[0xa43a] Extending timeout for 0x60 request
[0xA43A:1:0x0000]: bound 'basic' cluster: Status.NOT_SUPPORTED
[0xA43A:1:0x0000]: finished channel configuration
[0xa43a] Extending timeout for 0x62 request
[0xa43a:1:0x0402] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=94 command_id=Command.Configure_Reporting_rsp>
[0xA43A:1:0x0402]: reporting 'measured_value' attr on 'temperature' cluster: 30/900/50: Result: '[[ConfigureReportingResponseRecord(status=0)]]'
[0xA43A:1:0x0402]: finished channel configuration
[0xa43a] Extending timeout for 0x64 request
[0xa43a:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=96 command_id=Command.Configure_Reporting_rsp>
[0xA43A:1:0x0001]: reporting 'battery_voltage' attr on 'power' cluster: 3600/10800/1: Result: '[[ConfigureReportingResponseRecord(status=140, direction=0, attrid=32)]]'
[0xa43a] Extending timeout for 0x66 request
[0xA43A:1:0x0020]: bound 'poll_control' cluster: Status.SUCCESS
[0xa43a] Extending timeout for 0x68 request
[0xA43A:1:0x0019]: bound 'ota' cluster: Status.NOT_SUPPORTED
[0xA43A:1:0x0019]: finished channel configuration
[0xa43a] Extending timeout for 0x6a request
[0xa43a:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=102 command_id=Command.Configure_Reporting_rsp>
[0xA43A:1:0x0001]: reporting 'battery_percentage_remaining' attr on 'power' cluster: 3600/10800/1: Result: '[[ConfigureReportingResponseRecord(status=134, direction=0, attrid=33)]]'
[0xA43A:1:0x0001]: finished channel configuration
[0xa43a] Extending timeout for 0x6c request
[0xa43a:1:0x0020] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=104 command_id=Command.Write_Attributes_rsp>
[0xA43A:1:0x0020]: 3300.0s check-in interval set: [[WriteAttributesStatusRecord(status=<Status.SUCCESS: 0>)]]
[0xA43A:1:0x0020]: finished channel configuration
[0xA43A:1:0x0402]: 'async_configure' stage succeeded
[0xA43A:1:0x0001]: 'async_configure' stage succeeded
[0xA43A:1:0x0000]: 'async_configure' stage succeeded
[0xA43A:1:0x0020]: 'async_configure' stage succeeded
[0xA43A:1:0x0019]: 'async_configure' stage succeeded
[0xA43A:2:0x0000]: bound 'basic' cluster: Status.NOT_SUPPORTED
[0xA43A:2:0x0000]: finished channel configuration
[0xA43A:2:0x0405]: bound 'humidity' cluster: Status.SUCCESS
[0xa43a] Extending timeout for 0x70 request
[0xa43a:2:0x0405] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=112 command_id=Command.Configure_Reporting_rsp>
[0xA43A:2:0x0405]: reporting 'measured_value' attr on 'humidity' cluster: 30/900/50: Result: '[[ConfigureReportingResponseRecord(status=0)]]'
[0xA43A:2:0x0405]: finished channel configuration
[0xA43A:2:0x0000]: 'async_configure' stage succeeded
[0xA43A:2:0x0405]: 'async_configure' stage succeeded
[0xA43A](TPZRCO2HT-Z3): completed configuration
[0xA43A](TPZRCO2HT-Z3): stored in registry: ZhaDeviceEntry(name='Titan Products Ltd TPZRCO2HT-Z3', ieee='00:15:8d:00:03:87:7f:49', last_seen=1614619030.758866)
[0xa43a] Extending timeout for 0x7e request
[0xa43a:1:0x0003] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=126 command_id=Command.Default_Response>
[0xA43A:1:0x0003]: executed 'trigger_effect' command with args: '(2, 0)' kwargs: '{}' result: [64, <Status.UNSUP_CLUSTER_COMMAND: 129>]
[0xA43A](TPZRCO2HT-Z3): started initialization
[0xA43A:ZDO](TPZRCO2HT-Z3): 'async_initialize' stage succeeded
[0xA43A:1:0x0402]: initializing channel: from_cache: False
[0xa43a] Extending timeout for 0x81 request
[0xA43A:1:0x0001]: initializing channel: from_cache: False
[0xa43a] Extending timeout for 0x83 request
[0xA43A:1:0x0000]: initializing channel: from_cache: False
[0xA43A:1:0x0000]: finished channel configuration
[0xA43A:1:0x0020]: initializing channel: from_cache: False
[0xA43A:1:0x0020]: finished channel configuration
[0xA43A:1:0x0019]: initializing channel: from_cache: False
[0xA43A:1:0x0019]: finished channel configuration
[0xA43A:2:0x0000]: initializing channel: from_cache: False
[0xA43A:2:0x0000]: finished channel configuration
[0xA43A:2:0x0405]: initializing channel: from_cache: False
[0xa43a] Extending timeout for 0x85 request
[0xa43a:1:0x0402] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=129 command_id=Command.Read_Attributes_rsp>
[0xA43A:1:0x0402]: finished channel configuration
[0xa43a] Delivery error for seq # 0x83, on endpoint id 1 cluster 0x0001: message send failure
[0xA43A:1:0x0001]: failed to get attributes '['battery_voltage', 'battery_percentage_remaining']' on 'power' cluster: [0xa43a:1:0x0001]: Message send failure
[0xa43a] Extending timeout for 0x88 request
[0xa43a] Delivery error for seq # 0x85, on endpoint id 2 cluster 0x0405: message send failure
[0xA43A:2:0x0405]: failed to get attributes '['measured_value']' on 'humidity' cluster: [0xa43a:2:0x0405]: Message send failure
[0xA43A:2:0x0405]: finished channel configuration
[0xA43A:2:0x0000]: 'async_initialize' stage succeeded
[0xA43A:2:0x0405]: 'async_initialize' stage succeeded
[0xa43a:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=136 command_id=Command.Read_Attributes_rsp>
[0xA43A:1:0x0001]: finished channel configuration
[0xA43A:1:0x0402]: 'async_initialize' stage succeeded
[0xA43A:1:0x0001]: 'async_initialize' stage succeeded
[0xA43A:1:0x0000]: 'async_initialize' stage succeeded
[0xA43A:1:0x0020]: 'async_initialize' stage succeeded
[0xA43A:1:0x0019]: 'async_initialize' stage succeeded
[0xA43A](TPZRCO2HT-Z3): power source: Battery or Unknown
[0xA43A](TPZRCO2HT-Z3): completed initialization
I'm going to read through the docs on this site and have a go, but if anyone else can do this, it would be great !
The only non standard cluster is 0x040d cluster. I wonder if that one is the co2 measurement.
Yes it is. It’s linked in the docs as a concentration cluster. In the zigbee spec they use co2 as an example of something that would be stored in a concentration cluster. And that it would built in a structure within that cluster. but doesn’t explain how. as the cluster doesn’t bind I can’t see what it is sending. hoping to experiment with this quirks file sometime tomorrow. But I’m a bit lost at the moment.
I think the battery one must me a bit non standard too as it doesn’t report the battery level properly. That’s not as big a deal.
ah, missed that on the mobile. Kudos to the vendor for providing that information. So this would need a quirk and a modification to the ZHA. For concentration custom cluster would be something like
class GasConcentration(CustomCluster):
cluster_id = 0x040D
name = "Gas Concentration Measurement"
ep_attribute = "gas_concentration"
vendor_attributes = {
0x0000: ("measured_value", t.Single),
0x0001: ("min_measured_value", t.Single),
0x0002: ("max_measured_value", t.Single),
0xFFFD: ("cluster_revision", t.uint16_t),
}
server_commands = {}
client_commands = {}
and then a custom device with a replacement for 0x040D cluster_ID using the GacConcentration class. See https://github.com/zigpy/zha-device-handlers#what-the-heck-is-a-quirk for more info
That’s great. I’ll take a look Tomorrow and see if I can understand.
Hi,
Do you know of any similar devices I could look at to figure this out. I kind of follow the logic of what quirks do. But it looks pretty heavy. If I could find a similar device I might have a better chance.
Thanks.
I've raised an issue on Zigpy itself as I'm unsure if the ConcentrationCluster should be added into measurement.py to make products such as this work ?
Is that the right thing to do, or should it just be handled as a quirk ?
No, zigpy only contains standard clusters included in ZCL specification. So unless it was included in ZCL revision 7 it does not belong to zigpy
ok, I've hacked this together.............. I really am shooting in the dark here. I'm unsure what cluster to output my GasConcentration on? Do I need to change it from a Float to something else?
Thanks in advance........
__init__.py
"""Titan quirks."""
TITAN= "Titan Products Ltd"
TPZRC02THZ3.py
"""Device handler for Titan TPZRC02TH-Z3 Environment Sensor."""
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice, CustomCluster
from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl
from zigpy.zcl.clusters.measurement import TemperatureMeasurement, RelativeHumidity
from . import TITAN
from ..const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
class GasConcentration(CustomCluster):
cluster_id = 0x040D
name = "Gas Concentration Measurement"
ep_attribute = "gas_concentration"
vendor_attributes = {
0x0000: ("measured_value", t.Single),
0x0001: ("min_measured_value", t.Single),
0x0002: ("max_measured_value", t.Single),
0xFFFD: ("cluster_revision", t.uint16_t),
}
server_commands = {}
client_commands = {}
class TPZRC02THZ3(CustomDevice):
"""Custom device representing Bosch TPZRC02TH-Z3 environment sensor."""
signature = {
# <SimpleDescriptor endpoint=1 profile=260 device_type=770
# device_version=0
# input_clusters=[0, 1, 3, 32, 1026, 1037]
# output_clusters=[25]>
MODELS_INFO: [(TITAN, "TPZRCO2HT-Z3")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.xxxxxxxxxx,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
PollControl.cluster_id,
TemperatureMeasurement.cluster_id,
RelativeHumidity.cluster_id,
GasConcentration.cluster_id,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
}
},
}
replacement = {
ENDPOINTS: {
1: {
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
PollControl.cluster_id,
TemperatureMeasurement.cluster_id,
RelativeHumidity.cluster_id,
GasConcentration.cluster_id,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
}
}
}
No, zigpy only contains standard clusters included in ZCL specification. So unless it was included in ZCL revision 7 it does not belong to zigpy
Thanks. I've closed the issue on Zigpy and I'll see if I can get to the answer through this Quirk issue.
for the signature, the ENDPOINTS
key must match the zigbee device signature:
For device Types enums, reference https://github.com/zigpy/zigpy/blob/dev/zigpy/profiles/zha.py
signature = {
# UPDATE THIS COMMENTS TO MATCH the posted zigbee signature
# <SimpleDescriptor endpoint=1 profile=260 device_type=770
# device_version=0
# input_clusters=[0, 1, 3, 32, 1026, 1037]
# output_clusters=[25]>
MODELS_INFO: [(TITAN, "TPZRCO2HT-Z3")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
PollControl.cluster_id,
TemperatureMeasurement.cluster_id,
GasConcentration.cluster_id,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.MINI_SPLIT_AC,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
RelativeHumidity.cluster_id,
],
OUTPUT_CLUSTERS: [],
}
},
}
The replacements, in your case is going to match the signature mostly exactly, with the exception of the gas cluster only. Since you want to replace it with your copy, you have to reference it by the "class" instead of a cluster id:
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
PollControl.cluster_id,
TemperatureMeasurement.cluster_id,
GasConcentration,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.MINI_SPLIT_AC,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
RelativeHumidity.cluster_id,
],
OUTPUT_CLUSTERS: [],
}
},
}
Do I need to change it from a Float to something else?
t.Single
is the float type, matching the docs for the cluster. Enable zigpy debug and with your custom quirk, on restart, if everything is configured correctly you should see zigpy finding a quirk for your CO2 sensor. That would be the 1st step.
BTW, where did you get it? link?
Dang that thing is expensive. But last I've checked CO2 sensor were expensive. I'd love to know what kind of sensor they've used that it works from a battery.
This is the inside of the sensor. It is running on a lithium battery, so I guess it needs the max power it can get from an AA cell.
Is the order of this line important.......
# input_clusters=[0, 1, 3, 1026, 1037, 32]
In the log it shows them in this order, rather than in numerical order.
Order is not important. Usually quirks have clusters in numeri orders and constant names following the numeric order.
Thanks for the picture. Looks like this one https://sstsensing.com/product/cozir-lp2-ambient-air-co2-sensor/ Yeah, CO2 sensors seem to draw more power than any other sensors and most of the time have to run continuously and dont't go to low power mode. No chance of running it on C3202 or even an AA battery would not last long
ok, so more stupid questions. I've got the class and the quirk.
I've enabled zigpy debug.
So where do I put the quirk file ?
I'm running....
Version | core-2021.2.3
Installation Type | Home Assistant OS
Thanks very much for your help. I would never have even got this far without you !
Thanks for the picture. Looks like this one https://sstsensing.com/product/cozir-lp2-ambient-air-co2-sensor/
Agreed, it looks exactly like that.
This is the whole file I've got........
TPZRCO2THZ3.py
"""Device handler for Titan TPZRCO2TH-Z3 Environment Sensor."""
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice, CustomCluster
from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl
from zigpy.zcl.clusters.measurement import TemperatureMeasurement, RelativeHumidity
from . import TITAN
from ..const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
class GasConcentration(CustomCluster):
cluster_id = 0x040D
name = "Gas Concentration Measurement"
ep_attribute = "gas_concentration"
vendor_attributes = {
0x0000: ("measured_value", t.Single),
0x0001: ("min_measured_value", t.Single),
0x0002: ("max_measured_value", t.Single),
0xFFFD: ("cluster_revision", t.uint16_t),
}
server_commands = {}
client_commands = {}
class TPZRCO2THZ3(CustomDevice):
"""Custom device representing Titan TPZRCO2TH-Z3 environment sensor."""
signature = {
# <SimpleDescriptor endpoint=1 profile=260 device_type=770
# device_version=1
# input_clusters=[0, 1, 3, 32, 1026, 1037]
# output_clusters=[25]>
MODELS_INFO: [(TITAN, "TPZRCO2HT-Z3")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
PollControl.cluster_id,
TemperatureMeasurement.cluster_id,
GasConcentration.cluster_id,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.MINI_SPLIT_AC,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
RelativeHumidity.cluster_id,
],
OUTPUT_CLUSTERS: [],
}
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
PollControl.cluster_id,
TemperatureMeasurement.cluster_id,
GasConcentration,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.MINI_SPLIT_AC,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
RelativeHumidity.cluster_id,
],
OUTPUT_CLUSTERS: [],
}
},
}
and
init.py
"""Titan quirks."""
TITAN = "Titan Products Ltd"
Hang on, I might have found it, let my fight with it for a bit before you give me the answer !
:-)
If running HassOS, try https://github.com/zigpy/zha-device-handlers#testing-quirks-in-development-in-docker-based-install
Usually I just get access to HassOS dev console (not the ssh add-on one), gives you access to the docker. From there inside the home assistant container docker exec -ti homeassistant /bin/bash
gives the shell inside the container and the quirks are in 0.113: /usr/local/lib/python3.8/site-packages/zhaquirks/
folder
Thanks, I did it through portainer add-on. I was stumped at first by the fact that home-assistant containers were hidden. I've copied the files over and I'm doing a restart. Can't imagine it will work first time.
Fingers crossed !!
the first step is getting the quirk recognized. Second would require some mods to ZHA
I've run out of home automation time tonight. Will have to get back to this tomorrow.
The suspense !!
Ok, I have progress. But I still can't see the 0x040d cluster being bound. I had to make a few tweaks to the quirk due to syntax errors, or missing imports.
I ended up with..............
"""Device handler for Titan TPZRCO2TH-Z3 Environment Sensor."""
import logging
from zigpy.profiles import zha
from zigpy.quirks import CustomDevice, CustomCluster
from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl, PowerConfiguration
from zigpy.zcl.clusters.measurement import TemperatureMeasurement, RelativeHumidity
from zhaquirks import PowerConfigurationCluster
import zigpy.types as t
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
class GasConcentration(CustomCluster):
cluster_id = 0x040D
name = "Gas Concentration Measurement"
ep_attribute = "gas_concentration"
vendor_attributes = {
0x0000: ("measured_value", t.Single),
0x0001: ("min_measured_value", t.Single),
0x0002: ("max_measured_value", t.Single),
0xFFFD: ("cluster_revision", t.uint16_t),
}
server_commands = {}
client_commands = {}
_LOGGER = logging.getLogger(__name__)
class TPZRCO2THZ3(CustomDevice):
"""Custom device representing Titan TPZRCO2TH-Z3 environment sensor."""
signature = {
MODELS_INFO: [("Titan Products Ltd", "TPZRCO2HT-Z3")],
ENDPOINTS: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=770
# device_version=1
# input_clusters=[0, 1, 3, 32, 1026, 1037]
# output_clusters=[25]>
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
PollControl.cluster_id,
TemperatureMeasurement.cluster_id,
GasConcentration.cluster_id,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
},
# <SimpleDescriptor endpoint=2 profile=260, device_type=775
# device_version=1
# input_clusters=[0, 1, 3, 1029]
# output_clusters=[]>
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.MINI_SPLIT_AC,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
RelativeHumidity.cluster_id,
],
OUTPUT_CLUSTERS: [],
}
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.TEMPERATURE_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
PollControl.cluster_id,
TemperatureMeasurement.cluster_id,
GasConcentration,
],
OUTPUT_CLUSTERS: [Ota.cluster_id],
},
2: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.MINI_SPLIT_AC,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfigurationCluster.cluster_id,
Identify.cluster_id,
RelativeHumidity.cluster_id,
],
OUTPUT_CLUSTERS: [],
}
},
}
The log when I pair the product now says...............
Device 0x1baa (00:15:8d:00:03:87:7f:49) joined the network
--
[0x1baa:zdo] ZDO request ZDOCmd.Device_annce: [0x1BAA, 00:15:8d:00:03:87:7f:49, 128]
[0x1baa] Requesting 'Node Descriptor'
[0x1baa] Node Descriptor: NodeDescriptor(byte1=2, byte2=64, mac_capability_flags=128, manufacturer_code=4467, maximum_buffer_size=127, maximum_incoming_transfer_size=100, server_mask=11264, maximum_outgoing_transfer_size=100, descriptor_capability_field=0)
[0x1baa] Discovering endpoints
[0x1baa] Discovered endpoints: [1, 2]
[0x1baa:1] Discovering endpoint information
[0x1baa:1] Discovered endpoint information: SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=770, device_version=1, input_clusters=[0, 1, 3, 1026, 1037, 32], output_clusters=[25])
Unknown cluster 1037
[0x1baa:1:0x0000] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=215 command_id=Command.Read_Attributes_rsp>
[0x1baa:1] Manufacturer: Titan Products Ltd
[0x1baa:1] Model: TPZRCO2HT-Z3
[0x1baa:2] Discovering endpoint information
[0x1baa:2] Discovered endpoint information: SizePrefixedSimpleDescriptor(endpoint=2, profile=260, device_type=775, device_version=1, input_clusters=[0, 1, 3, 1029], output_clusters=[])
Checking quirks for Titan Products Ltd TPZRCO2HT-Z3 (00:15:8d:00:03:87:7f:49)
Considering <class 'zhaquirks.titan.TPZRCO2THZ3.TPZRCO2THZ3'>
Found custom device replacement for 00:15:8d:00:03:87:7f:49: <class 'zhaquirks.titan.TPZRCO2THZ3.TPZRCO2THZ3'>
device - 0x1BAA:00:15:8d:00:03:87:7f:49 entering async_device_initialized - is_new_join: True
device - 0x1BAA:00:15:8d:00:03:87:7f:49 has joined the ZHA zigbee network
[0x1BAA](TPZRCO2HT-Z3): started configuration
[0x1BAA:ZDO](TPZRCO2HT-Z3): 'async_configure' stage succeeded
[0x1BAA:1:0x0402]: bound 'temperature' cluster: Status.SUCCESS
[0x1BAA:1:0x0001]: bound 'power' cluster: Status.SUCCESS
[0x1BAA:1:0x0000]: bound 'basic' cluster: Status.NOT_SUPPORTED
[0x1BAA:1:0x0000]: finished channel configuration
[0x1baa:1:0x0402] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=229 command_id=Command.Configure_Reporting_rsp>
[0x1BAA:1:0x0402]: reporting 'measured_value' attr on 'temperature' cluster: 30/900/50: Result: '[[ConfigureReportingResponseRecord(status=0)]]'
[0x1BAA:1:0x0402]: finished channel configuration
[0x1baa:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=231 command_id=Command.Configure_Reporting_rsp>
[0x1BAA:1:0x0001]: reporting 'battery_voltage' attr on 'power' cluster: 3600/10800/1: Result: '[[ConfigureReportingResponseRecord(status=140, direction=0, attrid=32)]]'
[0x1BAA:1:0x0020]: bound 'poll_control' cluster: Status.SUCCESS
[0x1baa:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=237 command_id=Command.Configure_Reporting_rsp>
[0x1BAA:1:0x0001]: reporting 'battery_percentage_remaining' attr on 'power' cluster: 3600/10800/1: Result: '[[ConfigureReportingResponseRecord(status=134, direction=0, attrid=33)]]'
[0x1BAA:1:0x0001]: finished channel configuration
[0x1BAA:1:0x0019]: bound 'ota' cluster: Status.NOT_SUPPORTED
[0x1BAA:1:0x0019]: finished channel configuration
[0x1baa:1:0x0020] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=239 command_id=Command.Write_Attributes_rsp>
[0x1BAA:1:0x0020]: 3300.0s check-in interval set: [[WriteAttributesStatusRecord(status=<Status.SUCCESS: 0>)]]
[0x1BAA:1:0x0020]: finished channel configuration
[0x1BAA:1:0x0402]: 'async_configure' stage succeeded
[0x1BAA:1:0x0001]: 'async_configure' stage succeeded
[0x1BAA:1:0x0000]: 'async_configure' stage succeeded
[0x1BAA:1:0x0020]: 'async_configure' stage succeeded
[0x1BAA:1:0x0019]: 'async_configure' stage succeeded
[0x1BAA:2:0x0000]: bound 'basic' cluster: Status.NOT_SUPPORTED
[0x1BAA:2:0x0000]: finished channel configuration
[0x1BAA:2:0x0405]: bound 'humidity' cluster: Status.SUCCESS
[0x1baa:2:0x0405] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=245 command_id=Command.Configure_Reporting_rsp>
[0x1BAA:2:0x0405]: reporting 'measured_value' attr on 'humidity' cluster: 30/900/50: Result: '[[ConfigureReportingResponseRecord(status=0)]]'
[0x1BAA:2:0x0405]: finished channel configuration
[0x1BAA:2:0x0000]: 'async_configure' stage succeeded
[0x1BAA:2:0x0405]: 'async_configure' stage succeeded
[0x1BAA](TPZRCO2HT-Z3): completed configuration
[0x1BAA](TPZRCO2HT-Z3): stored in registry: ZhaDeviceEntry(name='Titan Products Ltd TPZRCO2HT-Z3', ieee='00:15:8d:00:03:87:7f:49', last_seen=1614778648.3336341)
[0x1baa:1:0x0003] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=249 command_id=Command.Default_Response>
[0x1BAA:1:0x0003]: executed 'trigger_effect' command with args: '(2, 0)' kwargs: '{}' result: [64, <Status.UNSUP_CLUSTER_COMMAND: 129>]
[0x1BAA](TPZRCO2HT-Z3): started initialization
[0x1BAA:ZDO](TPZRCO2HT-Z3): 'async_initialize' stage succeeded
[0x1BAA:1:0x0402]: initializing channel: from_cache: False
[0x1BAA:1:0x0001]: initializing channel: from_cache: False
[0x1BAA:1:0x0000]: initializing channel: from_cache: False
[0x1BAA:1:0x0000]: finished channel configuration
[0x1BAA:1:0x0020]: initializing channel: from_cache: False
[0x1BAA:1:0x0020]: finished channel configuration
[0x1BAA:1:0x0019]: initializing channel: from_cache: False
[0x1BAA:1:0x0019]: finished channel configuration
[0x1BAA:2:0x0000]: initializing channel: from_cache: False
[0x1BAA:2:0x0000]: finished channel configuration
[0x1BAA:2:0x0405]: initializing channel: from_cache: False
[0x1baa:1:0x0402] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=255 command_id=Command.Read_Attributes_rsp>
[0x1BAA:1:0x0402]: finished channel configuration
[0x1baa:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=1 command_id=Command.Read_Attributes_rsp>
[0x1baa:2:0x0405] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=3 command_id=Command.Read_Attributes_rsp>
[0x1BAA:2:0x0405]: finished channel configuration
[0x1BAA:2:0x0000]: 'async_initialize' stage succeeded
[0x1BAA:2:0x0405]: 'async_initialize' stage succeeded
[0x1baa:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=7 command_id=Command.Read_Attributes_rsp>
[0x1BAA:1:0x0001]: finished channel configuration
[0x1BAA:1:0x0402]: 'async_initialize' stage succeeded
[0x1BAA:1:0x0001]: 'async_initialize' stage succeeded
[0x1BAA:1:0x0000]: 'async_initialize' stage succeeded
[0x1BAA:1:0x0020]: 'async_initialize' stage succeeded
[0x1BAA:1:0x0019]: 'async_initialize' stage succeeded
[0x1BAA](TPZRCO2HT-Z3): power source: Battery or Unknown
[0x1BAA](TPZRCO2HT-Z3): completed initialization
Thoughts ?
Thanks
go to device page, pick the device -> Manage Clusters, Pick GasConcentration and then get value for the "measured_value" attribute. What do you get?
You mean:
integration -> Zigbee -> devices -> titan device. Manage Clusters:
Choose GasConcentration There are no Cluster Attributes to choose?
If I try the same for the Temperature Measurement Cluster, I can get the measured_value.
Is the drop down empty?
Yes, drop down empty.
Other quirk files say: manufacturer_attributes
Whereas, ours says vendor_attributes
should I change this ?
yes, change it then. It might not check for vendor attrs, if regular attrs are empty
Next step, in docker container you need to patch ZHA. In docker install is in /usr/src/homeassistant
:
find https://github.com/home-assistant/core/blob/dev/homeassistant/components/zha/core/channels/measurement.py in your docker and make essentially a copy of any channel. Something like
@registries.ZIGBEE_CHANNEL_REGISTRY.register(0x040D)
class GasConcentration(ZigbeeChannel):
"""Gas Concentration measurement channel."""
REPORT_CONFIG = [
{
"attr": "measured_value",
"config": (REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 1),
}
]
in "config": (REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 1)
I'm not sure about 1
value. it indicates by how much an attr needs to change in order for it to get reported. Since it is a float, might need something like 0.1 or 0.01 🤷 This part would need some experimentation
then in https://github.com/home-assistant/core/blob/dev/homeassistant/components/zha/sensor.py make a copy of the temp sensor
@STRICT_MATCH(channel_names="gas_concentration")
class GasConcentration(Sensor):
"""Gas Concentration sensor."""
SENSOR_ATTR = "measured_value"
_decimals = 5
_unit = CONCENTRATION_PARTS_PER_MILLION
but first need to get the attribte reading
manufacturer_attributes
Whereas, ours says vendor_attributes
Doh, yeah, it is supposed to be manufacturer_attributes
I've made those edits on a local copy (haven't put onto HA yet). At the moment, the attribute reading is on the drop down, but is returning none. The docs say that CO2 can only be reported every 600 seconds, so I'm going to leave it a while and try again.
enable debug logging, for zigpy
and the radio. Either use a config file, or a services call to logger.set_level
and monitor for traffic from the device. It might report it even without the configuration, but chances are that you still need to put the ZHA changes in and press "reconfigure device" button so it binds and configures reporting on 0x040d cluster
Can I patch it through custom_components, or do I need to actually change the file in the homeassistant components folder ?
Ok, I added this to measurement.py
@registries.ZIGBEE_CHANNEL_REGISTRY.register(0x040D)
class GasConcentration(ZigbeeChannel):
"""Gas Concentration measurement channel."""
REPORT_CONFIG = [
{
"attr": "measured_value",
"config": (REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT, 1),
}
]
and I added this to sensor.py
@STRICT_MATCH(channel_names="gas_concentration")
class GasConcentration(Sensor):
"""Gas Concentration sensor."""
SENSOR_ATTR = "measured_value"
_decimals = 5
_unit = CONCENTRATION_PARTS_PER_MILLION
you can patch through a custom component, but you do need to copy the entire zha
folder content into /config/custom_components/zha
Ok, I've patched those two files in /config/custom_components/zha
I also fixed the quirk file with manufacturer_attributes.
I can ask it to show me the measured_value now, but is shows "None" all the attributes on that cluster show "none" ?
It hasn't bound the cluster.
I see this in the log if it helps........
2021-03-03 14:51:28 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x36c4>, ep: 1, profile: 0x0104, cluster_id: 0x040d, data: b'1c73111501020086'
2021-03-03 14:55:58 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x36c4>, ep: 1, profile: 0x0104, cluster_id: 0x040d, data: b'1c73119b01000086'
Should this bit be MIN_INT or should it be float something ?
b'1c73119b01000086'
is a "Read_Attribute_Response" with the status of 0x86 -- UNSUPPORTED_ATTRIBUTES 😮
In the quirk, change the manufacturer_attributes
to just attributes
so it does not try to use the manufacturer id when reading those attributes
Seesms to be a problem with:
CONCENTRATION_PARTS_PER_MILLION
The only one I can find in const.py is:
CONCENTRATION_PARTS_PER_CUBIC_METER
which doesn't seem quite right.
ah, I guess they've added it in the current dev tree only. replace it just with "ppm"
string literal
Actually I think I was looking in the wrong place, do I need to import it to use it ?
you do need to import it, yes. But I don't see it in the "master" branch. ATM not even in the beta, only in the dev tree
ok, I had a few issues as I had mistakenly taken the dev branch of zha and put it in custom components. I've taken the correct release branch now. I've put it in literal for now. just starting up to test.
ok, we have a change. querying the measured value now, give nan
I'll give it 10 mins and try again in case it just doesn't have a reading yet.
I've got........
2021-03-03 16:01:42 WARNING (MainThread) [zigpy.zcl] Unknown cluster 1037
which I figure is 0x040d ?
I've also got.........
2021-03-03 16:04:30 DEBUG (MainThread) [zigpy_deconz.uart] Frame received: 0x1cb90012000b0003497f8703008d1500ffca
--
2021-03-03 16:04:30 DEBUG (MainThread) [zigpy_deconz.uart] Frame received: 0x17b9002a0023002202fdff000217bf00000013000c000017bf497f8703008d15008000afff80e23d00ca
2021-03-03 16:04:30 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0xbf17>, ep: 0, profile: 0x0000, cluster_id: 0x0013, data: b'0017bf497f8703008d150080'
2021-03-03 16:04:34 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 20 under 21 request id, data: b'14497f8703008d150001200003d0df05ffff2e210001'
2021-03-03 16:04:34 DEBUG (MainThread) [zigpy_deconz.uart] Send: 0x12cf002c00250015000217bf000000210000160014497f8703008d150001200003d0df05ffff2e2100010200
2021-03-03 16:04:34 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 22 under 23 request id, data: b'16497f8703008d150001000003d0df05ffff2e210001'
2021-03-03 16:04:34 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 24 under 25 request id, data: b'18497f8703008d150001020403d0df05ffff2e210001'
2021-03-03 16:04:34 DEBUG (MainThread) [zigpy_deconz.uart] Send: 0x12d0002c00250017000217bf000000210000160016497f8703008d150001000003d0df05ffff2e2100010200
2021-03-03 16:04:34 DEBUG (MainThread) [zigpy_deconz.uart] Send: 0x12d1002c00250019000217bf000000210000160018497f8703008d150001020403d0df05ffff2e2100010200
2021-03-03 16:04:41 DEBUG (MainThread) [zigpy_deconz.uart] Frame received: 0x17d8002a0023002202fdff000217bf00000013000c000317bf497f8703008d15008000afff97e23d00c9
2021-03-03 16:04:41 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0xbf17>, ep: 0, profile: 0x0000, cluster_id: 0x0013, data: b'0317bf497f8703008d150080'
2021-03-03 16:05:09 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 48 under 49 request id, data: b'30497f8703008d150001010003d0df05ffff2e210001'
2021-03-03 16:05:09 DEBUG (MainThread) [zigpy_deconz.uart] Send: 0x12fe002c00250031000217bf000000210000160030497f8703008d150001010003d0df05ffff2e2100010200
2021-03-03 16:05:11 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 52 under 53 request id, data: b'34497f8703008d150001190003d0df05ffff2e210001'
2021-03-03 16:05:11 DEBUG (MainThread) [zigpy_deconz.uart] Send: 0x1204002c00250035000217bf000000210000160034497f8703008d150001190003d0df05ffff2e2100010200
2021-03-03 16:05:11 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 56 under 57 request id, data: b'38497f8703008d150002050403d0df05ffff2e210001'
2021-03-03 16:05:11 DEBUG (MainThread) [zigpy_deconz.uart] Send: 0x120a002c00250039000217bf000000210000160038497f8703008d150002050403d0df05ffff2e2100010200
2021-03-03 16:05:11 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 58 under 59 request id, data: b'3a497f8703008d150002000003d0df05ffff2e210001'
2021-03-03 16:05:11 DEBUG (MainThread) [zigpy_deconz.uart] Send: 0x120d002c0025003b000217bf00000021000016003a497f8703008d150002000003d0df05ffff2e2100010200
2021-03-03 16:05:35 INFO (MainThread) [homeassistant.helpers.entity_registry] Registered new sensor.zha entity: sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_temperature
2021-03-03 16:05:35 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event entity_registry_updated[L]: action=create, entity_id=sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_temperature>
2021-03-03 16:05:35 INFO (MainThread) [homeassistant.helpers.entity_registry] Registered new sensor.zha entity: sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_power
2021-03-03 16:05:35 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event entity_registry_updated[L]: action=create, entity_id=sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_power>
2021-03-03 16:05:35 INFO (MainThread) [homeassistant.helpers.entity_registry] Registered new sensor.zha entity: sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_humidity
2021-03-03 16:05:35 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event entity_registry_updated[L]: action=create, entity_id=sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_humidity>
2021-03-03 16:05:35 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_temperature, old_state=None, new_state=<state sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_temperature=23.0; unit_of_measurement=°C, friendly_name=Titan Products Ltd TPZRCO2HT-Z3 497f8703 temperature, device_class=temperature @ 2021-03-03T16:05:35.970585+00:00>>
2021-03-03 16:05:35 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_power, old_state=None, new_state=<state sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_power=unknown; battery_size=AA, battery_quantity=1, battery_voltage=3.6, unit_of_measurement=%, friendly_name=Titan Products Ltd TPZRCO2HT-Z3 497f8703 power, device_class=battery @ 2021-03-03T16:05:35.971371+00:00>>
2021-03-03 16:05:35 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_humidity, old_state=None, new_state=<state sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_humidity=42.7; unit_of_measurement=%, friendly_name=Titan Products Ltd TPZRCO2HT-Z3 497f8703 humidity, device_class=humidity @ 2021-03-03T16:05:35.972025+00:00>>
2021-03-03 16:06:42 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_humidity, old_state=<state sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_humidity=42.7; unit_of_measurement=%, friendly_name=Titan Products Ltd TPZRCO2HT-Z3 497f8703 humidity, device_class=humidity @ 2021-03-03T16:05:35.972025+00:00>, new_state=<state sensor.titan_products_ltd_tpzrco2ht_z3_497f8703_humidity=41.4; unit_of_measurement=%, friendly_name=Titan Products Ltd TPZRCO2HT-Z3 497f8703 humidity, device_class=humidity @ 2021-03-03T16:06:42.568084+00:00>>
Depending on the change in the core, but most of the times you are fine using dev version of zha as a custom component with release version of the core
max measured value returns: 0.0020000000949949026 min measured value returns: 0.0
I guess it's returning the CO2 as a part of the air. And reading up to 2000 ppm
does that make sense ?
2021-03-03 16:01:42 WARNING (MainThread) [zigpy.zcl] Unknown cluster 1037
Check zigbee device signature, if it got the quirk. If you updated the core, then your modifications are gone. post debug log of you reading the measured_value attribue.
Also, post the log lines preceeding the Unknown cluster 1037
message
max measured value returns: 0.0020000000949949026
if 0.0020000000949949026
represents 2000ppm, then may want to set the _multiplier = 1e6
in the sensor, to get readings in ppm. It seems that the measure value is not in parts per million, but parts only?
The quirk is still there. I haven't updated core.
There is very little "zig" related stuff in log before that error.....
2021-03-03 16:01:42 DEBUG (MainThread) [zigpy.appdb] Loading application state from %s
2021-03-03 16:01:42 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=media_player.lounge_tv_cast, old_state=None, new_state=<state media_player.lounge_tv_cast=unavailable; friendly_name=Lounge TV, supported_features=152461 @ 2021-03-03T16:01:42.265396+00:00>>
2021-03-03 16:01:42 INFO (SyncWorker_6) [pychromecast] Querying device status
2021-03-03 16:01:42 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=sensor.alarm_log, old_state=None, new_state=<state sensor.alarm_log=unknown; friendly_name=Alarm Log @ 2021-03-03T16:01:42.282513+00:00>>
2021-03-03 16:01:42 WARNING (MainThread) [zigpy.zcl] Unknown cluster 1037
does this log help..........
2021-03-03 16:20:05 DEBUG (MainThread) [zigpy.device] [0xbf17] Extending timeout for 0x4c request
--
2021-03-03 16:20:05 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 76 under 77 request id, data: b'004c000100'
2021-03-03 16:20:05 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_request (20, 77, 0, <DeconzAddressEndpoint address_mode=2 address=0xBF17 endpoint=1>, 260, 1037, 1, b'\x00L\x00\x01\x00', 2, 0)
2021-03-03 16:20:05 DEBUG (MainThread) [zigpy_deconz.api] APS data request response: [2, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|2: 34>, 77]
2021-03-03 16:20:07 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_CONFIRM\|2: 166>, 0]
2021-03-03 16:20:07 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_confirm (0,)
2021-03-03 16:20:07 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_INDICATION\|APSDE_DATA_CONFIRM\|2: 174>, 0]
2021-03-03 16:20:07 DEBUG (MainThread) [zigpy_deconz.api] APS data confirm response for request with id 77: 00
2021-03-03 16:20:07 DEBUG (MainThread) [zigpy_deconz.api] Request id: 0x4d 'aps_data_confirm' for <DeconzAddressEndpoint address_mode=ADDRESS_MODE.NWK address=0xbf17 endpoint=1>, status: 0x00
2021-03-03 16:20:07 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_indication (1, 1)
2021-03-03 16:20:07 DEBUG (MainThread) [zigpy_deconz.api] APS data indication response: [34, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|2: 34>, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0000>, 1, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0xbf17>, 1, 260, 1037, b'\x18L\x01\x01\x00\x009\x00\x00\x00\x00', 0, 175, 255, 128, 228, 61, 0, -52]
2021-03-03 16:20:07 DEBUG (MainThread) [zigpy.zcl] [0xbf17:1:0x040d] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=76 command_id=Command.Read_Attributes_rsp>
2021-03-03 16:20:07 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0xbf17>, ep: 1, profile: 0x0104, cluster_id: 0x040d, data: b'184c010100003900000000'
2021-03-03 16:20:10 DEBUG (MainThread) [zigpy.device] [0xbf17] Extending timeout for 0x4e request
2021-03-03 16:20:10 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 78 under 79 request id, data: b'004e000200'
2021-03-03 16:20:10 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_request (20, 79, 0, <DeconzAddressEndpoint address_mode=2 address=0xBF17 endpoint=1>, 260, 1037, 1, b'\x00N\x00\x02\x00', 2, 0)
2021-03-03 16:20:10 DEBUG (MainThread) [zigpy_deconz.api] APS data request response: [2, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|2: 34>, 79]
2021-03-03 16:20:13 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_CONFIRM\|2: 166>, 0]
2021-03-03 16:20:13 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_INDICATION\|APSDE_DATA_CONFIRM\|2: 174>, 0]
2021-03-03 16:20:13 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_confirm (0,)
2021-03-03 16:20:13 DEBUG (MainThread) [zigpy_deconz.api] APS data confirm response for request with id 79: 00
2021-03-03 16:20:13 DEBUG (MainThread) [zigpy_deconz.api] Request id: 0x4f 'aps_data_confirm' for <DeconzAddressEndpoint address_mode=ADDRESS_MODE.NWK address=0xbf17 endpoint=1>, status: 0x00
2021-03-03 16:20:13 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_indication (1, 1)
2021-03-03 16:20:13 DEBUG (MainThread) [zigpy_deconz.api] APS data indication response: [34, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|2: 34>, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0000>, 1, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0xbf17>, 1, 260, 1037, b'\x18N\x01\x02\x00\x009o\x12\x03;', 0, 175, 255, 138, 228, 61, 0, -52]
2021-03-03 16:20:13 DEBUG (MainThread) [zigpy.zcl] [0xbf17:1:0x040d] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=78 command_id=Command.Read_Attributes_rsp>
2021-03-03 16:20:13 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0xbf17>, ep: 1, profile: 0x0104, cluster_id: 0x040d, data: b'184e01020000396f12033b'
2021-03-03 16:20:15 DEBUG (MainThread) [zigpy.device] [0xbf17] Extending timeout for 0x50 request
2021-03-03 16:20:15 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 80 under 81 request id, data: b'0050000000'
2021-03-03 16:20:15 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_request (20, 81, 0, <DeconzAddressEndpoint address_mode=2 address=0xBF17 endpoint=1>, 260, 1037, 1, b'\x00P\x00\x00\x00', 2, 0)
2021-03-03 16:20:15 DEBUG (MainThread) [zigpy_deconz.api] APS data request response: [2, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|2: 34>, 81]
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 82 under 83 request id, data: b'0052000b05'
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_request (20, 83, 0, <DeconzAddressEndpoint address_mode=2 address=0x0F66 endpoint=1>, 260, 2820, 1, b'\x00R\x00\x0b\x05', 2, 0)
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.zigbee.application] Sending Zigbee request with tsn 84 under 85 request id, data: b'0054000b05'
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] APS data request response: [2, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|2: 34>, 83]
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_request (20, 85, 0, <DeconzAddressEndpoint address_mode=2 address=0x0163 endpoint=1>, 260, 2820, 1, b'\x00T\x00\x0b\x05', 2, 0)
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_CONFIRM\|2: 166>, 0]
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] APS data request response: [2, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_CONFIRM\|2: 38>, 85]
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_confirm (0,)
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] APS data confirm response for request with id 83: 00
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Request id: 0x53 'aps_data_confirm' for <DeconzAddressEndpoint address_mode=ADDRESS_MODE.NWK address=0x0f66 endpoint=1>, status: 0x00
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_CONFIRM\|2: 166>, 0]
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_confirm (0,)
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_INDICATION\|APSDE_DATA_CONFIRM\|2: 174>, 0]
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] APS data confirm response for request with id 85: 00
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Request id: 0x55 'aps_data_confirm' for <DeconzAddressEndpoint address_mode=ADDRESS_MODE.NWK address=0x0163 endpoint=1>, status: 0x00
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_indication (1, 1)
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] APS data indication response: [32, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|2: 34>, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0000>, 1, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0163>, 1, 260, 2820, b'\x18T\x01\x0b\x05\x00)\x00\x00', 0, 175, 255, 138, 228, 61, 0, -38]
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy.zcl] [0x0163:1:0x0b04] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=84 command_id=Command.Read_Attributes_rsp>
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0163>, ep: 1, profile: 0x0104, cluster_id: 0x0b04, data: b'1854010b0500290000'
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_INDICATION\|2: 170>, 0]
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_indication (1, 1)
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] APS data indication response: [32, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|2: 34>, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0000>, 1, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0f66>, 1, 260, 2820, b'\x18R\x01\x0b\x05\x00)\x00\x00', 0, 175, 255, 153, 226, 61, 0, -54]
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy.zcl] [0x0f66:1:0x0b04] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=82 command_id=Command.Read_Attributes_rsp>
2021-03-03 16:20:18 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0f66>, ep: 1, profile: 0x0104, cluster_id: 0x0b04, data: b'1852010b0500290000'
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_CONFIRM\|2: 166>, 0]
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_confirm (0,)
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_INDICATION\|APSDE_DATA_CONFIRM\|2: 174>, 0]
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] APS data confirm response for request with id 81: 00
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] Request id: 0x51 'aps_data_confirm' for <DeconzAddressEndpoint address_mode=ADDRESS_MODE.NWK address=0xbf17 endpoint=1>, status: 0x00
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_indication (1, 1)
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] APS data indication response: [34, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|2: 34>, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0000>, 1, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0xbf17>, 1, 260, 1037, b'\x18P\x01\x00\x00\x009\x00\x00\xc0\x7f', 0, 175, 255, 138, 228, 61, 0, -52]
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy.zcl] [0xbf17:1:0x040d] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=80 command_id=Command.Read_Attributes_rsp>
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0xbf17>, ep: 1, profile: 0x0104, cluster_id: 0x040d, data: b'185001000000390000c07f'
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] Device state changed response: [<DeviceState.128\|APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|APSDE_DATA_INDICATION\|2: 170>, 0]
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] Command Command.aps_data_indication (1, 1)
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] APS data indication response: [30, <DeviceState.APSDE_DATA_REQUEST_SLOTS_AVAILABLE\|2: 34>, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0000>, 1, <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0163>, 1, 260, 0, b'\x18K\n\x01\x00 C', 0, 175, 255, 138, 228, 61, 0, -34]
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy.zcl] [0x0163:1:0x0000] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=False disable_default_response=True> manufacturer=None tsn=75 command_id=Command.Report_Attributes>
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy.zcl] [0x0163:1:0x0000] ZCL request 0x000a: [[Attribute(attrid=1, value=<TypeValue type=uint8_t, value=67>)]]
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy.zcl] [0x0163:1:0x0000] Attribute report received: app_version=67
2021-03-03 16:20:19 DEBUG (MainThread) [zigpy_deconz.api] 'aps_data_indication' response from <DeconzAddress address_mode=ADDRESS_MODE.NWK address=0x0163>, ep: 1, profile: 0x0104, cluster_id: 0x0000, data: b'184b0a01002043'
Is your feature request related to a problem? Please describe. Please add support for the CO2 measurement feature of the Titan Zigbee 3.0 C02 sensor. I seem to be able to see Humidity and Temperature already. But the battery level doesn't report properly and I don't see the CO2 level at all.
Product Page
Device signature - this can be acquired by removing the device from ZHA and pairing it again from the add devices screen. Be sure to add the entire content of the log panel after pairing the device to a code block below this line.
Additional context Add any other context or screenshots about the feature request here.
Endpoint Cluster Attribute Manual Attached