This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Trying to send from a switch to a coordinator

This is probably a very easy question to answer and I apologise for not fining the solution myself but I have been trolling through the documentation for several hours now with no light in sight.

All the examples provided for Zigbee devices are set up to communicate directly from one device to another, eg. switch to light bulb. However, in the real world of home automation this is not the way it appears to work. Home automation networks have a coordinator that not only establishes the network and handles security but also manages all the interactions between devices. Switches do not talk to light bulbs directly but simply send their commands tot he coordinator or hub which is then responsible for deciding what to do in response to the command.

My problem is that there does not appear to be any documentation, at least not that I have found so far, that explains how to address the command correctly to send it to the coordinator. The coordinator is always address 0 but what about the endpoint? In my situation, using a SmartThings hub, the endpoint does not seem to matter as long as the address is set to 0. Is this correct? Is this the best practice or am I missing something here?

Parents
  • Ian,

    Did you happen to leave any calls to zb_zcl_start_attr_reporing in your final solution? I am running into an issue where my coordinator/hub will sporadically update attribute values from a sensor (updates maybe every 20-60 minutes or not at all) and have begun looking into attribute reporting. I have verified that the clusters I want to report are configured to do so and added a call to start reporting and have noticed no difference in behavior. I also changed the minimum reporting time to 0 as you did. At the moment I am calling ZB_ZCL_SET_ATTRIBUTE every 15 seconds which is working but the values don't seem to make it to the coordinator often unless I manually read the attribute.

    I thought I'd be smart and use a USB based zigbee adapter and openhab/home-assistant as a hub that would hopefully be easier to develop with than say a smartthings hub but at this point I have no idea if the issues I am having are related at all to my choice of hub or if my firmware is faulty.

    I may end up purchasing a new hub but I'd also like to cover all of my bases just in case I am missing anything. As you're aware, the documentation leaves a little to be desired when it comes to implementing some of this functionality.

  • I am finding it exceedingly tough to get going with this stuff. The documentation is very difficult to read and I keep finding references to sample code by way of example documentation but the samples don't exist!

    I am not really sure of the purpose of the zb_zcl_start_attribute_reporting unless it is to restart reporting after you stop it with the companion call. I tried inserting it but it made no difference. If my hub had not already requested attribute reporting it failed and if it had, well it was already reporting any way.

    I have discovered that there is no way to actually set the minimum reporting interval to 0 as ii had previously thought. The defined value in the header does NOT change the actual stack behaviour it is merely a reference constant for your use. The most confusing part is that once you have enabled reporting the settings are persisted in non volatile memory and are reapplied on connect. This means that once you manage to get the thing reporting you can make a lot of changes that are not having any effect but the stack is still reporting using the last good setting. I found this out by using a sniffer to watch the traffic. Unfortunately, due to the lack of any sort of meaningful debugging from the ZBoss stack a sniffer appears to be an absolutely essential tool. Fortunately it is pretty inexpensive and fairly easy to get set up. The open source Wireshark is your tool which can be downloaded used for free and the nRF52840 Dongle is your hardware. You can configure this so that you can see all the traffic. I found that no matter what I did the ZBoss stack would reject any request with a minimum report time less than 1. Having got past that and written a custom driver for the SmartThings hub to set the reporting period to between 1 and 600 seconds I am finding that reporting is working as it should. SmartThings is an excellent environment and is very easy to use with great support and a very active community.

    My big problem is that the nRF52840 locks up with a buffer allocation failure somewhere in the ZBoss stack after a random amount of time. This could be anything from 30 seconds to an hour but it will not stay up for longer. The code ends up in an infinite loop in an abort function called by an assert in the zb_free_buffer or similar function. The stack trace goes no deeper so there is no real way to find out what is going wrong here. Hardly production ready don't you think? It would seem that this is probably due to some messages not getting handled correctly but since NONE of this processing is being done in code that we have the source to it is impossible for me to track it down. I have a support ticket open with Wireshark traces and ZBoss log dumps attached. I am waiting for a developer to try and find out what is going on. This doesn't happen in a small network with only Nordic devices but that is not exactly 'real world' now is it?

Reply
  • I am finding it exceedingly tough to get going with this stuff. The documentation is very difficult to read and I keep finding references to sample code by way of example documentation but the samples don't exist!

    I am not really sure of the purpose of the zb_zcl_start_attribute_reporting unless it is to restart reporting after you stop it with the companion call. I tried inserting it but it made no difference. If my hub had not already requested attribute reporting it failed and if it had, well it was already reporting any way.

    I have discovered that there is no way to actually set the minimum reporting interval to 0 as ii had previously thought. The defined value in the header does NOT change the actual stack behaviour it is merely a reference constant for your use. The most confusing part is that once you have enabled reporting the settings are persisted in non volatile memory and are reapplied on connect. This means that once you manage to get the thing reporting you can make a lot of changes that are not having any effect but the stack is still reporting using the last good setting. I found this out by using a sniffer to watch the traffic. Unfortunately, due to the lack of any sort of meaningful debugging from the ZBoss stack a sniffer appears to be an absolutely essential tool. Fortunately it is pretty inexpensive and fairly easy to get set up. The open source Wireshark is your tool which can be downloaded used for free and the nRF52840 Dongle is your hardware. You can configure this so that you can see all the traffic. I found that no matter what I did the ZBoss stack would reject any request with a minimum report time less than 1. Having got past that and written a custom driver for the SmartThings hub to set the reporting period to between 1 and 600 seconds I am finding that reporting is working as it should. SmartThings is an excellent environment and is very easy to use with great support and a very active community.

    My big problem is that the nRF52840 locks up with a buffer allocation failure somewhere in the ZBoss stack after a random amount of time. This could be anything from 30 seconds to an hour but it will not stay up for longer. The code ends up in an infinite loop in an abort function called by an assert in the zb_free_buffer or similar function. The stack trace goes no deeper so there is no real way to find out what is going wrong here. Hardly production ready don't you think? It would seem that this is probably due to some messages not getting handled correctly but since NONE of this processing is being done in code that we have the source to it is impossible for me to track it down. I have a support ticket open with Wireshark traces and ZBoss log dumps attached. I am waiting for a developer to try and find out what is going on. This doesn't happen in a small network with only Nordic devices but that is not exactly 'real world' now is it?

Children
  • Thanks for taking the time to respond Ian. There is no question that the zigbee documentation is extremely lacking. I don't necessarily blame Nordic for that entirely. I imagine DSR ties the hands of anyone who uses their ZBoss stack. Hopefully a more complete set of examples and documentation is in the pipeline.

    Your findings regarding reporting are very interesting and actually make a little sense of the device behavior I have been seeing. Although I thought I had completely wiped the flash of my dev board at least once since possibly configuring reporting using a deCONZ USB stick and their software I now have a device that reports to a different central at what seems to be a 15 minute interval but sometimes longer, and never on an attribute change of value which is currently set to update every 15 seconds. Unfortunately the software I am currently using does not appear to have any method of changing Zigbee reporting parameters so it is another case of "it works but I have no idea why or how it is configured". Seems to be a theme when working with ZBoss. I have picked up a SmartThings hub though and will be looking into creating a custom device handler. While not perfect from what I have read, at least the SmartThings hub is one of the big players unlike the homebrew solution I have been using thus far. It seems every solution has its trade-offs.

    I did flash another board with the sniffer firmware and have configured wireshark but have yet to do any kind of deep dive into understanding what I am seeing. I have a mix of packets that are specifically marked as Zigbee packets and others that are detected as plain 802.15.4 packets. I'll get around to learning more about sniffing zigbee some other time.

    Fortunately I have not yet seen any issues with my nrf52840 locking up even after days of being online with the exception of two connection drops that occurred almost exactly 24 hours apart for whatever reason. The chart below illustrates the weird reporting intervals I mentioned but otherwise seemingly stable connection.

    A lot could be said about the ZBoss stack and how much of a hassle it is to work with but I have a feeling that the options offered by other vendors probably aren't much, if any better. It would certainly be nice if even in the examples provided, features were implemented in a consistent manner. Comments on why certain things are implemented a given way would also make developing a Zigbee device a little easier.

  • If it is of any use to you, here is my testing device handler for SmartThings that seems to work with the Nordic light switch example once you set it up to join the SmartThings network.

    /**
     *  Copyright 2017 Cedar Technology
     *
     *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
     *  in compliance with the License. You may obtain a copy of the License at:
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
     *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
     *  for the specific language governing permissions and limitations under the License.
     *
     *  ZigBee Test Device
     *
     *  Author: Ian Abercrombie
     *  Date: 2019-03-22
     */
    
    metadata {
    	definition(name: "ZigBee test device", namespace: "cedar", author: "Ian Abercrombie", runLocally: false, minHubCoreVersion: '000.019.00012', executeCommandsLocally: true) {
    
    		capability "Actuator"
    		capability "Configuration"
            capability "Light"
    		capability "Refresh"
    		capability "Switch"
    
    		fingerprint profileId: "0104", inClusters: "0000,0003,0005,0004,0006,0008", outClusters: "", manufacturer: "Nordic", model: "Dimable_Light_v0.1", deviceJoinName: ""
    	}
    
    	// UI tile definitions
    	tiles(scale: 2) {
    		multiAttributeTile(name: "switch", type: "lighting", width: 6, height: 4, canChangeIcon: true) {
    			tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
    				attributeState "on", label: '${name}', action: "switch.off", icon: "st.switches.light.on", backgroundColor: "#00A0DC", nextState: "turningOff"
    				attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.light.off", backgroundColor: "#ffffff", nextState: "turningOn"
    				attributeState "turningOn", label: '${name}', action: "switch.off", icon: "st.switches.light.on", backgroundColor: "#00A0DC", nextState: "turningOff"
    				attributeState "turningOff", label: '${name}', action: "switch.on", icon: "st.switches.light.off", backgroundColor: "#ffffff", nextState: "turningOn"
    			}
    		}
    
    		standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
    			state "default", label: "", action: "refresh.refresh", icon: "st.secondary.refresh"
    		}
    
    		main(["switch"])
    		details(["switch", "colorTempSliderControl", "colorName", "refresh"])
    	}
    }
    
    // Globals
    
    // Parse incoming device messages to generate events
    /*
    Layout of the catchall packet
    FIELD       BYTES
    profile ID: 2
    cluster ID: 2
    source EP:  1
    dest EP:    1
    options:    2
    type:       1
    source:     2
    clustersp:  1
    mfgsp:      1
    mfgcode:    2
    cmd ID:     1
    direction:  1
    */
    def parse(String description) {
    	log.debug "description is $description"
    	def event = zigbee.getEvent(description)
    	if (event)
        {
    		sendEvent(event)
    	}
        else
        {
    		def cluster = zigbee.parse(description)
    
    		if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) {
    			if (cluster.data[0] == 0x00)
                {
    				log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster
    				sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
    			}
                else
                {
    				log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
    			}
    		}
            else
            {
    			log.warn "DID NOT PARSE MESSAGE for description : $description"
    			log.debug "${cluster}"
    		}
    	}
    }
    
    def off() {
    	zigbee.off()
    }
    
    def on() {
    	zigbee.on()
    }
    
    def setLevel(value) {
    	zigbee.setLevel(value)
    }
    
    /**
     * PING is used by Device-Watch in attempt to reach the Device
     * */
    /*
    def ping() {
    	return zigbee.onOffRefresh()
    }
    */
    
    def refresh() {
    	log.debug "Refresh and set up reporting"
        
        // Configure reporting between 1 and 600 seconds
    	return zigbee.onOffRefresh() + zigbee.configureReporting(0x06, 0x00, 0x10, 1, 600, null)
    }
    
    def configure() {
    	log.debug "Configure."
    	
        refresh()
    }
    
    
    
    def installed() {
    	log.debug "Installed."
    }
    
    

Related