add support for local ISO8601 timestamp format (#1171)

* add support for local ISO8601 timestamp format

added local ISO8601 timestamp format for local rather than UTC-based timestamps

ISO8601 = 2019-03-01T15:32:45.941+0000
ISO8601_Local = 2019-03-01T16:32:45.941+0100 (for TZ GMT+1)

* fixed indentation

* tabs to spaces

* comply with Travis

* comply with Travis once again

* Removed spaces to make Travis happy

* updates
This commit is contained in:
Andreas Brett 2019-03-02 16:47:36 +01:00 committed by Koen Kanters
parent ae14fa5cd6
commit 1cde620d70
5 changed files with 44 additions and 1 deletions

View File

@ -76,7 +76,7 @@ class BridgeConfig {
}
lastSeen(topic, message) {
const allowed = ['disable', 'ISO_8601', 'epoch'];
const allowed = ['disable', 'ISO_8601', 'epoch', 'ISO_8601_local'];
message = message.toString();
if (!allowed.includes(message)) {

View File

@ -1,5 +1,6 @@
const settings = require('../util/settings');
const logger = require('../util/logger');
const utils = require('../util/utils');
const dontCacheProperties = [
'action', 'button', 'button_left', 'button_right', 'click', 'forgotten', 'keyerror',
@ -123,6 +124,9 @@ class DeviceReceive {
case 'ISO_8601':
payload.last_seen = new Date(now).toISOString();
break;
case 'ISO_8601_local':
payload.last_seen = utils.toLocalISOString(new Date(now));
break;
case 'epoch':
payload.last_seen = now;
break;

View File

@ -44,6 +44,7 @@ const defaults = {
/**
* Add a last_seen attribute to mqtt messages, contains date/time of zigbee message arrival
* "ISO_8601": ISO 8601 format
* "ISO_8601_local": Local ISO 8601 format (instead of UTC-based)
* "epoch": milliseconds elapsed since the UNIX epoch
* "disable": no last_seen attribute (default)
*/

View File

@ -33,6 +33,28 @@ function resolveEntity(ID) {
return {ID: ID, type: type, friendlyName: friendlyName};
}
// construct a local ISO8601 string (instead of UTC-based)
// Example:
// - ISO8601 (UTC) = 2019-03-01T15:32:45.941+0000
// - ISO8601 (local) = 2019-03-01T16:32:45.941+0100 (for timezone GMT+1)
function toLocalISOString(dDate) {
const tzOffset = -dDate.getTimezoneOffset();
const plusOrMinus = tzOffset >= 0 ? '+' : '-';
const pad = function(num) {
const norm = Math.floor(Math.abs(num));
return (norm < 10 ? '0' : '') + norm;
};
return dDate.getFullYear() +
'-' + pad(dDate.getMonth() + 1) +
'-' + pad(dDate.getDate()) +
'T' + pad(dDate.getHours()) +
':' + pad(dDate.getMinutes()) +
':' + pad(dDate.getSeconds()) +
plusOrMinus + pad(tzOffset / 60) +
':' + pad(tzOffset % 60);
}
module.exports = {
millisecondsToSeconds: (milliseconds) => milliseconds / 1000,
secondsToMilliseconds: (seconds) => seconds * 1000,
@ -40,4 +62,5 @@ module.exports = {
isIkeaTradfriDevice: (device) => ikeaTradfriManufacturerID.includes(device.manufId),
isNumeric: (string) => /^\d+$/.test(string),
resolveEntity: (ID) => resolveEntity(ID),
toLocalISOString: (dDate) => toLocalISOString(dDate),
};

View File

@ -225,5 +225,20 @@ describe('DeviceReceive', () => {
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.equal(typeof publishEntityState.getCall(0).args[1].last_seen, 'string');
});
it('Should publish last_seen ISO_8601_local', () => {
const device = {ieeeAddr: '0x12345678'};
const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1);
sandbox.stub(settings, 'get').callsFake(() => {
return {
advanced: {
last_seen: 'ISO_8601_local',
},
};
});
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishEntityState.calledOnce);
chai.assert.equal(typeof publishEntityState.getCall(0).args[1].last_seen, 'string');
});
});
});