Some nodes not reporting battery level

Hey @chris

Would you mind taking a look at the attached log file?

I’m trying to figure out why some Everspring ST-814 devices are not reporting battery level. I can’t quite follow what’s happening in the logs when nodes 5, 6, and 2 wake up. It seems like the responses don’t correlate with the requests, but I might not be interpreting it correctly.

This is the binding version (note that it’s not the new transaction code):
175 | Active | 80 | 2.0.0.201608310102 | org.openhab.binding.zwave

This file just contains the log entries for nodes 5, 6, and 2 around the time periods noted below.
https://drive.google.com/open?id=0Bwmcwu6ccTd_NVFJWUdlODhFVHc

Nodes 5 & 6 have not reported battery level in over a week, although I can see many BATTERY_GET requests in the log file.

  • Start: 03:11:43.818
  • End: 03:12:28.680

Node 2 is reporting battery level

  • Start: 03:59:57.282
  • End: 04:00:02.556

I agree, this looks strange. It appears too systematic to be a bug as such. It seems every time we request temperature, we get humidity, and when we request humidity we get temperature - it seems this happens every time. I can only guess that this is a bug in the device, but it’s quite strange for sure! We could say that requests are out of synch or something, but the multi_instance request swap the types as well, so we can be sure that this is happening.

I can’t really explain why this is happening. The log viewer independently decodes the frames sent and received and this is logged at a low level in the binding, so I can only assume that this is really happening.

Why it doesn’t respond to battery requests is another question - we seem to get temperatures!

I note that all responses take around 500ms which is quite slow - it might be normal for these devices though.

I would try power cycling one of them to see if anything changes.

Thanks for looking at this. It is very strange, isn’t it? Even node 2, which is reporting battery level, is reporting it out of sync.

I have 4 of these devices, all of which are misbehaving in this manner. Seems odd that all 4 would get into this state. I was thinking there might be something that is triggering it – perhaps the devices’ software is not handling a certain command properly, causing them to get into this state.

I thought of cycling power in one of them as well, but thought I’d get your opinion first. The devices are in another location, and I may not get to them for a week or two.

Have you had them working with OH1? And if yes, did they behave normally there?

I’ve never used OH1. I’ve been using OH2 for several months, and this is the first I’ve noticed it. Not sure when the behavior actually started. From the perspective of temp, humidity, etc. on the UI, everything would look normal even though the reports were coming in out of sync with the requests. It was the lack of battery updates that made me look into it more closely.

Oddly, node 5 got a battery report this morning in response to a sensor_multilevel_get. :-o

I shutdown OH2, upgraded to the latest build, and restarted. I doubt the upgrade had anything to do with what follows.

In the first part of this log, the binding requests battery, then requests temp/humidity using multi_instance_encap. The device appears to respond correctly.

In the second part of this log, the binding requests temp/humidity using sensor_multilevel_get, then requests battery, then requests temp/humidity using multi_instance_encap. Here the device responds incorrectly.

https://drive.google.com/open?id=0Bwmcwu6ccTd_OG1QM19RQnNNaWc

Is it possible that the sensor_multilevel_get is what’s causing the device to become confused?

Is there a way I can prevent/disable the sensor_multilevel_gets from occurring to prove or disprove?

Maybe the database has the wrong configuration for the endpoints?

This is probably caused by polling, and the polling probably uses the database configuration, so if it’s wrong, then it might request the wrong type on the endpoint. I’d be surprised if this caused the problem, it’s certainly not out of the question.

The other thing is that given the device responds on the main endpoint, we could just remove the channels from the other endpoints as they are duplicated anyway (or the other way around - remove them from the root endpoint if we get them working properly on endpoint 1 and 2).

Can you take a look in your XML and see if it looks like temperature is really endpoint 1 - I suspect it might be humidity.

If I’m reading this right, for the multi_instance command class, endpoint 1 looks like temp and endpoint 2 looks like humidity.

<node>
  <deviceClass>
    <basicDeviceClass>ROUTING_SLAVE</basicDeviceClass>
    <genericDeviceClass>MULTILEVEL_SENSOR</genericDeviceClass>
    <specificDeviceClass>ROUTING_SENSOR_MULTILEVEL</specificDeviceClass>
  </deviceClass>
  <homeId>0xdf9dd181</homeId>
  <nodeId>6</nodeId>
  <version>3</version>
  <manufacturer>0x60</manufacturer>
  <deviceId>0x1</deviceId>
  <deviceType>0x6</deviceType>
  <listening>false</listening>
  <frequentlyListening>false</frequentlyListening>
  <routing>true</routing>
  <security>false</security>
  <beaming>true</beaming>
  <maxBaudRate>40000</maxBaudRate>
  <nodeInformationFrame>
    <commandClass>SENSOR_MULTILEVEL</commandClass>
    <commandClass>MULTI_INSTANCE</commandClass>
    <commandClass>VERSION</commandClass>
    <commandClass>MANUFACTURER_SPECIFIC</commandClass>
    <commandClass>ASSOCIATION</commandClass>
    <commandClass>WAKE_UP</commandClass>
    <commandClass>BATTERY</commandClass>
    <commandClass>CONFIGURATION</commandClass>
    <commandClass>BASIC</commandClass>
  </nodeInformationFrame>
  <supportedCommandClasses>
    <entry>
      <commandClass>BATTERY</commandClass>
      <batteryCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <batteryLevel>50</batteryLevel>
        <batteryLow>false</batteryLow>
        <isGetSupported>true</isGetSupported>
      </batteryCommandClass>
    </entry>
    <entry>
      <commandClass>MULTI_INSTANCE</commandClass>
      <multiInstanceCommandClass>
        <version>2</version>
        <instances>1</instances>
        <versionSupported>2</versionSupported>
        <endpoints>
          <entry>
            <int>1</int>
            <endPoint>
              <deviceClass>
                <basicDeviceClass>ROUTING_SLAVE</basicDeviceClass>
                <genericDeviceClass>MULTILEVEL_SENSOR</genericDeviceClass>
                <specificDeviceClass>ROUTING_SENSOR_MULTILEVEL</specificDeviceClass>
              </deviceClass>
              <endpointId>1</endpointId>
              <supportedCommandClasses>
                <entry>
                  <commandClass>BASIC</commandClass>
                  <basicCommandClass>
                    <endpoint reference="../../../.."/>
                    <version>0</version>
                    <instances>0</instances>
                    <versionSupported>0</versionSupported>
                    <isGetSupported>true</isGetSupported>
                  </basicCommandClass>
                </entry>
                <entry>
                  <commandClass>SENSOR_MULTILEVEL</commandClass>
                  <multiLevelSensorCommandClass>
                    <endpoint reference="../../../.."/>
                    <version>2</version>
                    <instances>1</instances>
                    <versionSupported>2</versionSupported>
                    <sensors>
                      <entry>
                        <multilevelSensorType>TEMPERATURE</multilevelSensorType>
                        <multilevelSensor>
                          <sensorType>TEMPERATURE</sensorType>
                          <initialised>true</initialised>
                        </multilevelSensor>
                      </entry>
                    </sensors>
                    <isGetSupported>true</isGetSupported>
                  </multiLevelSensorCommandClass>
                </entry>
              </supportedCommandClasses>
            </endPoint>
          </entry>
          <entry>
            <int>2</int>
            <endPoint>
              <deviceClass>
                <basicDeviceClass>ROUTING_SLAVE</basicDeviceClass>
                <genericDeviceClass>MULTILEVEL_SENSOR</genericDeviceClass>
                <specificDeviceClass>ROUTING_SENSOR_MULTILEVEL</specificDeviceClass>
              </deviceClass>
              <endpointId>2</endpointId>
              <supportedCommandClasses>
                <entry>
                  <commandClass>BASIC</commandClass>
                  <basicCommandClass>
                    <endpoint reference="../../../.."/>
                    <version>0</version>
                    <instances>0</instances>
                    <versionSupported>0</versionSupported>
                    <isGetSupported>true</isGetSupported>
                  </basicCommandClass>
                </entry>
                <entry>
                  <commandClass>SENSOR_MULTILEVEL</commandClass>
                  <multiLevelSensorCommandClass>
                    <endpoint reference="../../../.."/>
                    <version>2</version>
                    <instances>1</instances>
                    <versionSupported>2</versionSupported>
                    <sensors>
                      <entry>
                        <multilevelSensorType>RELATIVE_HUMIDITY</multilevelSensorType>
                        <multilevelSensor>
                          <sensorType>RELATIVE_HUMIDITY</sensorType>
                          <initialised>true</initialised>
                        </multilevelSensor>
                      </entry>
                    </sensors>
                    <isGetSupported>true</isGetSupported>
                  </multiLevelSensorCommandClass>
                </entry>
              </supportedCommandClasses>
            </endPoint>
          </entry>
        </endpoints>
        <useDestEndpointAsSource>false</useDestEndpointAsSource>
        <endpointsAreTheSameDeviceClass>true</endpointsAreTheSameDeviceClass>
      </multiInstanceCommandClass>
    </entry>
    <entry>
      <commandClass>ASSOCIATION</commandClass>
      <associationCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>2</versionSupported>
        <maxGroups>2</maxGroups>
      </associationCommandClass>
    </entry>
    <entry>
      <commandClass>MANUFACTURER_SPECIFIC</commandClass>
      <manufacturerSpecificCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <initSerialNumber>false</initSerialNumber>
      </manufacturerSpecificCommandClass>
    </entry>
    <entry>
      <commandClass>BASIC</commandClass>
      <basicCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <isGetSupported>true</isGetSupported>
      </basicCommandClass>
    </entry>
    <entry>
      <commandClass>SENSOR_MULTILEVEL</commandClass>
      <multiLevelSensorCommandClass>
        <version>2</version>
        <instances>1</instances>
        <versionSupported>2</versionSupported>
        <sensors>
          <entry>
            <multilevelSensorType>RELATIVE_HUMIDITY</multilevelSensorType>
            <multilevelSensor>
              <sensorType>RELATIVE_HUMIDITY</sensorType>
              <initialised>true</initialised>
            </multilevelSensor>
          </entry>
          <entry>
            <multilevelSensorType>TEMPERATURE</multilevelSensorType>
            <multilevelSensor>
              <sensorType>TEMPERATURE</sensorType>
              <initialised>true</initialised>
            </multilevelSensor>
          </entry>
        </sensors>
        <isGetSupported>true</isGetSupported>
      </multiLevelSensorCommandClass>
    </entry>
    <entry>
      <commandClass>NO_OPERATION</commandClass>
      <noOperationCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
      </noOperationCommandClass>
    </entry>
    <entry>
      <commandClass>VERSION</commandClass>
      <versionCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <libraryType>LIB_CONTROLLER_BRIDGE</libraryType>
        <protocolVersion>2.64</protocolVersion>
        <applicationVersion>1.6</applicationVersion>
      </versionCommandClass>
    </entry>
    <entry>
      <commandClass>WAKE_UP</commandClass>
      <WakeUpCommandClass>
        <version>2</version>
        <instances>1</instances>
        <versionSupported>2</versionSupported>
        <targetNodeId>1</targetNodeId>
        <interval>3600</interval>
        <minInterval>60</minInterval>
        <maxInterval>16777215</maxInterval>
        <defaultInterval>3600</defaultInterval>
        <intervalStep>1</intervalStep>
        <lastWakeup>2016-09-11 15:00:47.828 UTC</lastWakeup>
        <isGetSupported>true</isGetSupported>
      </WakeUpCommandClass>
    </entry>
    <entry>
      <commandClass>CONFIGURATION</commandClass>
      <configurationCommandClass>
        <version>1</version>
        <instances>1</instances>
        <versionSupported>1</versionSupported>
        <configParameters>
          <entry>
            <int>1</int>
            <configurationParameter>
              <index>1</index>
              <size>1</size>
              <value>99</value>
              <readOnly>false</readOnly>
              <writeOnly>false</writeOnly>
            </configurationParameter>
          </entry>
          <entry>
            <int>2</int>
            <configurationParameter>
              <index>2</index>
              <size>1</size>
              <value>99</value>
              <readOnly>false</readOnly>
              <writeOnly>false</writeOnly>
            </configurationParameter>
          </entry>
          <entry>
            <int>3</int>
            <configurationParameter>
              <index>3</index>
              <size>1</size>
              <value>99</value>
              <readOnly>false</readOnly>
              <writeOnly>false</writeOnly>
            </configurationParameter>
          </entry>
          <entry>
            <int>4</int>
            <configurationParameter>
              <index>4</index>
              <size>1</size>
              <value>99</value>
              <readOnly>false</readOnly>
              <writeOnly>false</writeOnly>
            </configurationParameter>
          </entry>
          <entry>
            <int>5</int>
            <configurationParameter>
              <index>5</index>
              <size>1</size>
              <value>99</value>
              <readOnly>false</readOnly>
              <writeOnly>false</writeOnly>
            </configurationParameter>
          </entry>
          <entry>
            <int>6</int>
            <configurationParameter>
              <index>6</index>
              <size>2</size>
              <value>10</value>
              <readOnly>false</readOnly>
              <writeOnly>false</writeOnly>
            </configurationParameter>
          </entry>
          <entry>
            <int>7</int>
            <configurationParameter>
              <index>7</index>
              <size>1</size>
              <value>5</value>
              <readOnly>false</readOnly>
              <writeOnly>false</writeOnly>
            </configurationParameter>
          </entry>
          <entry>
            <int>8</int>
            <configurationParameter>
              <index>8</index>
              <size>1</size>
              <value>5</value>
              <readOnly>false</readOnly>
              <writeOnly>false</writeOnly>
            </configurationParameter>
          </entry>
        </configParameters>
      </configurationCommandClass>
    </entry>
  </supportedCommandClasses>
  <securedCommandClasses/>
  <associationGroups>
    <entry>
      <int>1</int>
      <associationGroup>
        <index>1</index>
        <associations>
          <associationMember>
            <node>1</node>
            <endpoint>0</endpoint>
          </associationMember>
        </associations>
      </associationGroup>
    </entry>
    <entry>
      <int>2</int>
      <associationGroup>
        <index>2</index>
        <associations/>
      </associationGroup>
    </entry>
  </associationGroups>
  <nodeNeighbors/>
  <lastSent>2016-09-11 15:00:49.388 UTC</lastSent>
  <lastReceived>2016-09-11 15:00:50.198 UTC</lastReceived>
</node>

So if that’s the case, then leave the endpoints and remove them from the root?

Well, it’s strange… So the device says (during the device scan) that it supports humidity on endpoint 2, but then when we request humidity on endpoint 2, it responds with temperature, from endpoint 2.

So, currently I think no endpoints respond with their ‘correct’ type (ie I think in all these logs, if we request temperature, we get humidity and vice versa. So, it’s a bit of a case of ‘pick one’ - we could disable the endpoints, or the root, and see what happens.

My vote would be to disable the root. I say that because when the endpoints are used, the battery get seems to work. When the root is used, the battery get returns the temperature!

OTOH, this thing is so whacked up, it’s anyone’s guess what will happen. :wink:

As an additional thought… If you have the device set up to auto-report on a given frequency, then the polling for temperature and humidity is a bit redundant.

Yes - polling in OH2 is really there as a device health check. If you only rely on the auto reports, and they stop, then there’s no way to know if that’s because the reports have stopped, or the device is dead.

Another thing to try - change the wakeup period to 10 minutes and see what happens. I’m interested to see what the device sends when there’s no polling.

Yes, good point. I forgot about that.

Good idea. I’m going to lengthen the polling interval as well.

Test conditions:

  • wake_up every 600 seconds
  • polling interval every 3600 seconds

Since I’m not physically with the device, I need to wait for the next wake_up for the new wake_up setting to take effect.

Note that the device also will be sending auto-reports every 10 minutes, as that’s how I have it configured currently.

Not my day today…

I tried to set the wake_up interval to 600 seconds. I see this in the log. but when the device wake’s up, I don’t see the new wake_up interval being sent to the device. Oddly, when I change the wake_up interval, HABmin doesn’t show it as pending like it does for the config parameters. Is this change not being placed in the wakeup queue?

2016-09-11 17:20:49.965 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 6: Configuration update received
2016-09-11 17:20:49.972 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 6: Configuration update wakeup_interval to 600

I just had a quick look at the code - it’s all implemented, but there must be something fundamentally wrong if that’s all you see in the log. I’ll have to take a look at this, but it won’t be tonight I’m afraid…

No worries. I realize it’s already 11:00 your time…

Not sure if this will help track this down…

After I set the wakeup interval in HABmin, I see the 2 log entries above.

However, if I look at the config of that node using the REST interface I see the old value.

It’s almost like this conditional is not being executed; otherwise I’d see that debug statement below in the logs.

    } else if ("wakeup".equals(cfg[0])) {
        ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node
                .getCommandClass(CommandClass.WAKE_UP);
        if (wakeupCommandClass == null) {
            logger.error("NODE {}: Error getting wakeupCommandClass", nodeId);
            continue;
        }
        Integer value;
        try {
            value = ((BigDecimal) configurationParameter.getValue()).intValue();
        } catch (NumberFormatException e) {
            logger.error("NODE {}: Error converting wakeup value from {}", nodeId,
                    configurationParameter.getValue());
            continue;
        }
        logger.debug("NODE {}: Set wakeup interval to '{}'", nodeId, value);

One other thing.

If I change the polling period, I see this:

2016-09-12 08:06:57.962 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 6: Configuration update received
2016-09-12 08:06:57.977 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 6: Configuration update binding_pollperiod to 3700.0
2016-09-12 08:06:57.978 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 6: Polling intialised at 3700 seconds - start in 3700000 milliseconds.

But when I chance the wakeup interval, I see this:

2016-09-12 08:11:33.395 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 6: Configuration update received
2016-09-12 08:11:33.403 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 6: Configuration update wakeup_interval to 601

Note the lack of decimal point on the wakeup. Is that significant?

I also see that the POLLPERIOD config item is defined as integer, while the WAKEUPINTERVAL config item is defined as text.

It shouldn’t be. This shouldn’t impact the conditional check that you mentioned earlier which is why I said last night that something fundamental appears wrong.

I’ll try and take a look tonight.

I’ve written a test to test this, and it seems to work ok. I’ll push the test shortly, but I’m not sure what’s happening given that this seems to work :confused:.

That cast to BigDecimal is ok when the config parameter is a string?