Everything Xbee

engineering from Digikey looked into the micropython getting corrupted when updating the Xbee3 firmware.

After testing, I found the same issue and consulted our firmware engineering team. This is a known limitation currently on the modules. After upgrading firmware, the file system must be reformatted and the code reloaded. There is a check that determines what version the module was running when a format occurs. If this doesn't match, then the module requires a new format to occur.

At this time, you will want to backup the Python script first, update the module firmware, format the file system and then load the backed up python script.

So unfortunately it is a hardware limitation. Hopefully they address it with the next Xbee version but not really a big issue and does not affect day to day usage.

6 Likes

the XBee Presence DH also works great with SmartThings arrival sensors as well.

For the XBee Presence DH
I added :
10:"10 Minutes"

  • not really an issue with the Xbee or SmartThings presence devices but to address an issue with the hub slowing down and then during the nightly backup if it took more than 5 minutes the presence devices would go departed and then back to arrived when the hub finally booted backup by itself which could cause rules to fire so I added 10 minutes option.
    Adding additional conditions can also help stop this from happening.

and
I also added a battery change info option mainly for use when using this DH with a SmartThings arrival sensor so I knew when I last changed the battery

command "resetBatteryReplacedDate"

attribute "batteryLastReplaced", "String"

//Reset the batteryLastReplaced date to current date
def resetBatteryReplacedDate(paired) {
def newlyPaired = paired ? " for newly paired sensor" : ""
sendEvent(name: "batteryLastReplaced", value: new Date())
log.debug "Setting Battery Last Replaced to current date${newlyPaired}"
}

*** modified DH below ***

/*
 * XBee Presence
 *
 *  Copyright 2019 Daniel Terryn
 *
 *  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.
 *
 *  Change History:
 *
 *    Date        Who            What
 *    ----        ---            ----
 *    2019-05-21  Daniel Terryn  Original Creation
 *    2020-01-01  Jason Bottjen  Added options for debug and descriptionText logging
 *    2020-01-08  N0W0n		     added 10 minute departure option and battery replace date
 * 
 */
metadata {
    definition (name: "XBee Presence bat set", namespace: "dan.t", author: "Daniel Terryn") {
        capability "Sensor"
        capability "Configuration"
        capability "Battery"
        capability "Presence Sensor"

        command "resetBatteryReplacedDate"
        
        attribute "batteryLastReplaced", "String"
    }
    
    preferences {
        input "fullVoltageValue", "enum", title:"Battery 100% mV:", required:true, defaultValue:3300, options:[3000:"3000 mV",3300:"3300 mV",3600:"3600 mV"]
        input "checkInterval", "enum", title:"Minutes elapsed until sensor is not present", required:true, defaultValue:3, options:[1:"1 Minute",2:"2 Minutes",3:"3 Minutes", 4:"4 Minutes",5:"5 Minutes",10:"10 Minutes"]
        input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: false
        input name: "logDesc", type: "bool", title: "Enable descriptionText logging", defaultValue: true
    }
}

//Reset the batteryLastReplaced date to current date
def resetBatteryReplacedDate(paired) {
	def newlyPaired = paired ? " for newly paired sensor" : ""
	sendEvent(name: "batteryLastReplaced", value: new Date())
    log.debug "Setting Battery Last Replaced to current date${newlyPaired}"
}

def updated() {
    stopTimer()
    startTimer()
    if (logEnable) runIn(1800,logsOff)
}

def installed() {
// Arrival sensors only goes OFFLINE when Hub is off
}
def configure() {
    log.warn "configure..."
    return []
}
def parse(String description) {
    state.lastCheckin = now()
    
    handlePresenceEvent(true)
    if (description?.startsWith('catchall')) {
        parseCatchAllMessage(description)
    }

    return []
}

private Map parseCatchAllMessage(String description) {
    Map resultMap = [:]
    def cluster = zigbee.parse(description)
    if (cluster.clusterId == 0x0011 && cluster.command == 0x01){
        handleBatteryEvent(cluster)
    }
    
    return resultMap
}

/**
 * Create battery event from reported battery voltage.
 *
 * @param volts Battery voltage in mV
 */
private handleBatteryEvent(cluster) {
    def descriptionText
    
    def battery_string = ""
    for (element in cluster.data) {
        battery_string = battery_string + Integer.toString(element,16).padLeft(2, '0')
    }
    battery_mV = Integer.parseInt(battery_string)
    // log.debug "Battery mV: ${battery_mV}"
    if (logDesc) log.info "Battery mV: ${battery_mV}"
    def value = 100
    if (battery_mV <= 2100) {
        value = 0
    }
    else {
        /* Formula
            Minimum Voltage = 2100mV
            Divider = (100% Voltage in mV - 2100) (max and default is 3600)
        */
        def offset = battery_mV - 2100
        value = Math.round((offset / (Integer.parseInt(fullVoltageValue)-2100)) * 100)
        if (value > 100)
        value = 100
    }
    def linkText = getLinkText(device)
    def currentPercentage = device.currentState("battery")?.value
    if (currentPercentage && (Integer.parseInt(currentPercentage, 10) == value)) {
        return
    }
    descriptionText = "${linkText} battery is ${value}%"
    def eventMap = [
        name: 'battery',
        value: value,
        unit: "%",
        descriptionText: descriptionText,
        translatable: true,
        type: "digital"
    ]
    if (logEnable) log.debug "Creating battery event for voltage=${battery_mV/1000}V: ${linkText} ${eventMap.name} is ${eventMap.value}%"
    sendEvent(eventMap)
    
}

private handlePresenceEvent(present) {
    def wasPresent = device.currentState("presence")?.value == "present"
    if (!wasPresent && present) {
        if (logDesc) log.info "Sensor is present"
        startTimer()
    } else if (!present) {
        if (logDesc) log.info "Sensor is not present"
        stopTimer()
    } else if (wasPresent && present) {
        if (logEnable) log.debug "Sensor already present"
        return
    }
    def linkText = getLinkText(device)
    def descriptionText
    if ( present )
        descriptionText = "${linkText} has arrived"
    else
        descriptionText = "${linkText} has left"
    def eventMap = [
        name: "presence",
        value: present ? "present" : "not present",
        linkText: linkText,
        descriptionText: descriptionText,
        translatable: true,
        type: "digital"
    ]
    if (logEnable) log.debug "Creating presence event: ${device.displayName} ${eventMap.name} is ${eventMap.value}"
    sendEvent(eventMap)
}

private startTimer() {
    if (logEnable) log.debug "Scheduling periodic timer"
    runEvery1Minute("checkPresenceCallback")
}

private stopTimer() {
    if (logEnable) log.debug "Stopping periodic timer"
    // Always unschedule to handle the case where the DTH was running in the cloud and is now running locally
    unschedule("checkPresenceCallback")
}

def checkPresenceCallback() {
    def timeSinceLastCheckin = (now() - state.lastCheckin ?: 0) / 1000
    def theCheckInterval = Integer.parseInt(checkInterval) * 60
    if (logEnable) log.debug "Sensor checked in ${timeSinceLastCheckin} seconds ago"
    if (timeSinceLastCheckin >= theCheckInterval) {
        handlePresenceEvent(false)
    }
}

def logsOff(){
    log.warn "debug logging disabled..."
    device.updateSetting("logEnable",[value:"false",type:"bool"])
}
3 Likes

I noticed today that my XBee changes it's zigbee device ID number every 5 minutes. I had some zigbee issues, and was wondering what it could be. Then I noticed my Tradfi repeater is doing the same. Check your zigbee routing logs, and see if the routers are changing regularly.

Anyone else? I'm on the newest update, released today. 2.1.8.115

It's changed twice in the time taken to type this, from C1CI to 791F, to A801.

Edit: it's changed again.
Confirming I do have JV set to 0 (disabled).

Jason,
(deleted text)
Edit: it resolved after 30 minutes or so. Sorry to bother you.

Also, @NoWon Your newly updated driver is borked. It has asterix's at the start of every line. It would be good to remove them. Both in the OP and the post a few up from mine.

1 Like

@mike thanks
fat fingered that

I was a little frustrated trying to read which device was which when performing a scan on XCTU, although a great tool, its not exactly easy to see which device is which, so I created something to make it a little easier which I thought I'd share.

  1. XLS template I use is here. Its blank, but the easy steps below will explain

  2. Open XCTU and run a scan

  3. While the scan is running, you cen get a list of your devices, open your hub and Zigbee settings.
    Highlight the header columns and then down over all your devices

  4. Open Notepad ++ and copy and paste all your devices from the above, save it as a TXT file somewhere.

  5. From the XCTU scan, when its scanned enough or picked up all devices. Select "tools --> Export Table"

  6. Back in the XLS, import the Devices list from Zigbee Settings text file you created in step 4, just to provide a list of devices.
    Excel - "Data --> Get Data --> From File --> From Text/CSV" You can load the file as is, Tab delimited. I name mine "Devices" as you can reuse this template once created, and refresh the data.

  7. Do the same again, but this time with the scan from XCTU, I name this Tab "Scan"

  8. On the Scan Tab we need to insert two columns.
    Highlight Column D, right Click and then Insert. And do the same after, this time on Column F. So your sheet is as per below.

  9. On the Calcs Tab, copy the Text in the Formula Bar for the VLOOKUP in cell D1. Then in the Scan tab, highlight D1 and enter the = sign, and paste in the calculation.
    Do the same again, this time for the calculation in F1 on the Calcs Tab, pasting with = into the Scan Tab F1.

10 Save the XLS!

The output will update and your list will be somewhat easier to view. Even better if you filter Colum B to be "End Device"

You can add the Hub details into the bottom of the Scan tab for completness if you want.

This is also a handy way to see devices on your network, which arent actually in He. So looks like I have some work to do :slight_smile:

The next time you would like to check, you don'tneed to do the long winded process. If you run the scan, and copy out your device list each time, save the files in the same location and name, when you open the XLS next time, you can simply hit "Data --> Refresh All" and the table will update :+1:

image

You may need to import the text files and format differently depending on which Excel, or Sheets you use etc, I'm using Office 365.

Enjoy!!

8 Likes

Damn you, Roy.
You’ve just removed another obstacle stopping me purchasing a Xbee.
I’ve been holding off but now you’ve made it even more attractive.

Really nice work though. Thx :blush:

1 Like

Cheers :+1:

It’s a little long winded on the first go, but once you’ve done it, you only save the HE device list, and export the data, then in Excel just do a refresh data, whenever you want to :wink:

Okay, so, I got new Xbee 3 pro to replace one that I burned up accidentally. I followed the same directions that you gave earlier with the profile files. And it pairs to hubitat. But it only checks in once and then stops. It doesn't continue to send messages to the hub. Any idea what could be causing this? I tried installing the profile, then updating the firmware to 1009 and then installing the micropython file and that didn't work. So, i tired not updating the firmware and just installing the micropython file and that didn't work either. It will check in again when I power cycle it again without having to re-discover it. So, this is not the same problem I was having before. It just appears that the board is going to sleep and not waking back up.

Update: This does not happen with the router configuration...that works fine. So i know it's not the board.

Update2: So, important lesson learned, importing the profile does not also load the firmware taht was associated with that profile. Also, sometimes you just have to load it 5 times to get it to work. (I swear, these board are going to be the death of me.)

1 Like

Are the 2 xbee boards linked in the OP still the best hardware for this? Those both appear to be out of stock currently at digikey, so I wonder if there's a newer model or or something.
How about the grove dev board? That's in stock, is it still the recommended board to buy?
The usb adapter from ebay, am I understanding correctly that it is suitable for powering an xbee device 'in the field', and the grove (or other?) board is only needed for the initial programming?

The boards have been out of stock EVERYWHERE! The only place that I have been able to find stock recently is SparkFun. They have some of the Pro Boards available with the U.Fl connector or the SMA connector. Everywhere else expects to get stock back by end of January or mid February.

I've used the XB3-24Z8UT-J and XB3-24Z8UT and the XB3-24X8PT-J. All three have worked great with the profiles linked here. Had some trouble in the beginning but they all got worked out.

Is this the same thing as the Pro board linked in the OP? It looks like it, but at almost half the price I wanted to double check...

And is this a suitable alternative to the Grove board linked in the OP?

That is the same one, yes. Yes, the sparkfun explorer will work to program/run them.

Now, with the SMA one, you will have to have a RP-SMA antenna as well. The PCB antenna units do not quire an external antenna.

1 Like

@Ryan780
So end device profile is working for you now?
I am out of the country for the next 4 weeks so can not double check to make sure nothing has changed with the profile and firmware 1009.
Going off memory I believe mine are running 1009 and both profiles without any issues.

Yes...it just took me a while to get it to work. Had to clear back to baseline a couple times.

1 Like

I received my xbee pro and xbee explorer usb today and am trying to get started following the guide in the OP. In XCTU, when I click the + button to add a module, the dialog doesn't list any serial ports to select, but if I choose the magnifying glass option next to it, it does show up. Searching that way, it finds the xbee, though it detects it at 9600 baud instead of the 115200 recommended here.

Assuming that isn't a problem, I try to proceed with updating the firmware, but when I click on the xbee in the left column, I get a message that it couldn't find a fimrware for the device. It offers to update the firmware library, but still doesn't find a firmware to install.

Where did I go wrong?

Do you have the windows driver installed for the xbee?

The explorer USB was detected and installed as a USB Serial port, using an FTDI driver. Is there a driver for the Xbee itself that's needed beyond what was included with the XCTU install?

I ran xbee recovery, and that seems to have loaded the firmware successfully. Now after removing and re-adding the device in xctu, it shows the name as something other than just '1003' and gives me a UI to work with.

I can confirm that these settings work on a DIGI XSTICK2 ZB with 23A7 router firmware.

I had everything setup in HASSIO and Windows, but wanted to get it on my Linux laptop so I could wander about and diagnose weak links. I had one Zigbee plug routing a bunch of traffic. It had been outside for Christmas lights and when the lights came down....everything broke and wouldn't re-mesh.

In order to save someone 2 hours of Google.....Do these steps:

  • Install XCTU from Digi Website
  • Click on "Tools" -> "Firmware Explorer" -> "Can't Find Your Firmware? Click Here" -> "Install Legacy Firmware Package"
  • Use the 23A7 firmware
  • Apply those settings I mentioned. Key settings are Encryption Key and Name. The firmware should already be set for router mode.
  • You may need to install a couple extra libraries via apt to make Java happy with XCTU.....so there may still be Google in your future.

2 Likes