Noisy Polling Results for Switches?
Posted: 24 Jan 2016 21:07
I've written a node app which controls various light switches around my home. These are US switches without the ability to notify the controller when they've been manually adjusted. They also don't support the Hail command. So in order to tell what level they're at I poll them periodically.
In doing that polling I'm noticing an odd situation. I'm currently logging every polling instance where the returned level has changed from its earlier value. The log is filled with items like the following:
The polling code itself is relatively simple (this is in a node module):
In a nutshell, I'm doing a get() against a particular node in pollDevice(), and then doing a separate call to retrieve the value of the device's level in getLastLevel(). The requests are all built around bluebird promises, which simply do a POST against ZWaveAPI and then parse the result.
I'm not currently doing any kind of error checking, and I'm issuing the request for level value immediately after the initial get() against a node. I think that may be the source of the problem -- because it takes time for the z-way server to communicate with the switch -- but I thought the docs say that the pre-existing level value should be unchanged until z-way hears back from the switch, but that the pre-existing level will be marked as invalidated until z-way hears back. Which wouldn't explain why the retrieved value keeps jumping back and forth.
Thoughts on what's going on, and how to fix it/work around it would be most appreciated.
In doing that polling I'm noticing an odd situation. I'm currently logging every polling instance where the returned level has changed from its earlier value. The log is filled with items like the following:
I'm polling about eight switches every 30 seconds (so far as I can tell, it takes less than a second for the z-way server to process all the jobs involved).01/24/2016 09:10:00 AM - info: switch Kitchen (15) level changed from 99 to 0
01/24/2016 09:10:30 AM - info: switch Kitchen (15) level changed from 0 to 99
01/24/2016 09:17:00 AM - info: switch Kitchen (15) level changed from 99 to 0
01/24/2016 09:17:30 AM - info: switch Kitchen (15) level changed from 0 to 99
01/24/2016 09:18:00 AM - info: switch Front Lights (26) level changed from 0 to 99
01/24/2016 09:18:30 AM - info: switch Front Lights (26) level changed from 99 to 0
01/24/2016 09:18:30 AM - info: switch Upstairs Hallway (17) level changed from 0 to 99
01/24/2016 09:19:00 AM - info: switch Kitchen (15) level changed from 99 to 0
01/24/2016 09:19:00 AM - info: switch Upstairs Hallway (17) level changed from 99 to 0
The polling code itself is relatively simple (this is in a node module):
Code: Select all
ZWave.prototype.curLevel = function (nodeNumber) {
var self = this;
return self.pollDevice(nodeNumber).then( function( exists ) {
return self.getLastLevel( nodeNumber );
} );
};
ZWave.prototype.getLastLevel = function( nodeNumber ) {
var self = this;
return self.requestAsync( sprintf( '/Run/devices[%d].instances[0].commandClasses[0x20].data.level.valueOf()', nodeNumber ) )
.then( function( value ) {
return value;
} )
.catch( function( error ) {
winston.error( sprintf( 'getLastLevel(%d): %s', nodeNumber, error ) );
} );
};
ZWave.prototype.pollDevice = function( nodeNumber ) {
var self = this;
return self.requestAsync( sprintf( '/Run/devices[%d].instances[0].commandClasses[0x20].Get()', nodeNumber ) )
.then( function( value ) {
return ( value == 'null' );
} )
.catch( function( error ) {
winston.error( sprintf( 'pollDevice(%d): %s', nodeNumber, error ) );
} );
};
ZWave.prototype.requestAsync = function (path) {
var self = this;
return new Promise(function (resolve, reject) {
var request = http.request({
hostname: self.server,
port: self.port,
path: '/ZWaveAPI/' + path,
method: 'POST',
}, function (response) {
// Bundle the result
var body = '';
// Build the body
response.on('data', function (chunk) {
body += chunk;
});
// wait until all data received to resolve
response.on('end', function () {
resolve(body);
});
});
// Handle errors
request.on('error', function (error) {
winston.error('Problem with request', error);
reject(error);
});
// Must always call .end() even if there is no data being written to the request body
request.end();
});
};
I'm not currently doing any kind of error checking, and I'm issuing the request for level value immediately after the initial get() against a node. I think that may be the source of the problem -- because it takes time for the z-way server to communicate with the switch -- but I thought the docs say that the pre-existing level value should be unchanged until z-way hears back from the switch, but that the pre-existing level will be marked as invalidated until z-way hears back. Which wouldn't explain why the retrieved value keeps jumping back and forth.
Thoughts on what's going on, and how to fix it/work around it would be most appreciated.