Add the timestamp of last received zigbee message visible in HASS (#739)

* Add timestamp on receiving message from Zigbee

Add last_message to the payload

* Discovery on HASS restart and last_message attribute added

- On restarting Home Assistant, resending device discovery information
- Add timestamp on receiving message from Zigbee

* Add option: add_timestamp in settings

* Add option: add_timestamp in settings

* Add option: add_timestamp in settings

* typo

* Update homeassistant.js

* Update homeassistant.js

* Update homeassistant.js

* Update deviceReceive.js

* Update deviceReceive.js

* Update homeassistant.js

* Update settings.js

* Update deviceReceive.js

* Update deviceReceive.js

* Update deviceReceive.js

* Update deviceReceive.js

* Fix tests

* Fix lint

* Fix lint
This commit is contained in:
Gergely Markics
2018-12-26 17:33:39 +01:00
committed by Koen Kanters
parent a1eea76dd4
commit 5d3461c4c6
6 changed files with 80 additions and 15 deletions
+40
View File
@@ -239,6 +239,7 @@ sensor:
- "voltage"
- "action"
- "duration"
- "last_seen"
force_update: true
```
{% endraw %}
@@ -258,6 +259,7 @@ sensor:
- "voltage"
- "action"
- "duration"
- "last_seen"
force_update: true
```
{% endraw %}
@@ -277,6 +279,7 @@ sensor:
- "voltage"
- "action"
- "duration"
- "last_seen"
force_update: true
```
{% endraw %}
@@ -296,6 +299,7 @@ sensor:
- "voltage"
- "action"
- "duration"
- "last_seen"
force_update: true
```
{% endraw %}
@@ -315,6 +319,7 @@ sensor:
- "voltage"
- "action"
- "duration"
- "last_seen"
force_update: true
```
{% endraw %}
@@ -359,6 +364,7 @@ sensor:
- "consumption"
- "current"
- "power_factor"
- "last_seen"
```
{% endraw %}
@@ -432,6 +438,7 @@ sensor:
- "consumption"
- "current"
- "power_factor"
- "last_seen"
```
{% endraw %}
@@ -449,6 +456,7 @@ sensor:
- "linkquality"
- "battery"
- "voltage"
- "last_seen"
sensor:
- platform: "mqtt"
@@ -461,6 +469,7 @@ sensor:
- "linkquality"
- "battery"
- "voltage"
- "last_seen"
```
{% endraw %}
@@ -478,6 +487,7 @@ sensor:
- "linkquality"
- "battery"
- "voltage"
- "last_seen"
sensor:
- platform: "mqtt"
@@ -490,6 +500,7 @@ sensor:
- "linkquality"
- "battery"
- "voltage"
- "last_seen"
sensor:
- platform: "mqtt"
@@ -502,6 +513,7 @@ sensor:
- "linkquality"
- "battery"
- "voltage"
- "last_seen"
```
{% endraw %}
@@ -528,6 +540,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -554,6 +567,7 @@ sensor:
- "linkquality"
- "battery"
- "voltage"
- "last_seen"
sensor:
- platform: "mqtt"
@@ -566,6 +580,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -592,6 +607,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -618,6 +634,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -644,6 +661,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -671,6 +689,7 @@ sensor:
- "angle_y"
- "angle_x"
- "unknown_data"
- "last_seen"
force_update: true
```
{% endraw %}
@@ -701,6 +720,7 @@ sensor:
- "consumption"
- "current"
- "power_factor"
- "last_seen"
```
{% endraw %}
@@ -730,6 +750,7 @@ sensor:
- "consumption"
- "current"
- "power_factor"
- "last_seen"
```
{% endraw %}
@@ -756,6 +777,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -782,6 +804,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -798,6 +821,7 @@ sensor:
- "linkquality"
- "forgotten"
- "keyerror"
- "last_seen"
```
{% endraw %}
@@ -825,6 +849,7 @@ sensor:
- "angle_y"
- "angle_x"
- "unknown_data"
- "last_seen"
force_update: true
```
{% endraw %}
@@ -963,6 +988,7 @@ sensor:
value_template: "{{ value_json.brightness }}"
json_attributes:
- "linkquality"
- "last_seen"
```
{% endraw %}
@@ -1313,6 +1339,7 @@ sensor:
- "angle_y"
- "angle_x"
- "unknown_data"
- "last_seen"
force_update: true
```
{% endraw %}
@@ -1340,6 +1367,7 @@ sensor:
- "linkquality"
- "battery"
- "voltage"
- "last_seen"
sensor:
- platform: "mqtt"
@@ -1352,6 +1380,7 @@ sensor:
- "linkquality"
- "battery"
- "voltage"
- "last_seen"
sensor:
- platform: "mqtt"
@@ -1364,6 +1393,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -1406,6 +1436,7 @@ sensor:
- "consumption"
- "current"
- "power_factor"
- "last_seen"
```
{% endraw %}
@@ -1430,6 +1461,7 @@ sensor:
- "description"
- "type"
- "rssi"
- "last_seen"
```
{% endraw %}
@@ -1835,6 +1867,7 @@ sensor:
- "linkquality"
- "battery"
- "voltage"
- "last_seen"
```
{% endraw %}
@@ -2119,6 +2152,7 @@ sensor:
- "consumption"
- "current"
- "power_factor"
- "last_seen"
```
{% endraw %}
@@ -2367,6 +2401,7 @@ sensor:
- "consumption"
- "current"
- "power_factor"
- "last_seen"
```
{% endraw %}
@@ -2464,6 +2499,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -2490,6 +2526,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -2584,6 +2621,7 @@ sensor:
- "voltage"
- "action"
- "sensitivity"
- "last_seen"
```
{% endraw %}
@@ -2624,6 +2662,7 @@ sensor:
- "linkquality"
- "battery"
- "voltage"
- "last_seen"
```
{% endraw %}
@@ -2723,6 +2762,7 @@ sensor:
- "consumption"
- "current"
- "power_factor"
- "last_seen"
```
{% endraw %}
+4
View File
@@ -99,6 +99,10 @@ class DeviceReceive {
payload.linkquality = message.linkquality;
}
// Add last seen timestamp
const now = new Date();
payload.last_seen = now.toISOString();
this.publishDeviceState(device, payload, cache);
};
+13 -10
View File
@@ -84,7 +84,7 @@ const configurations = {
unit_of_measurement: 'lx',
device_class: 'illuminance',
value_template: '{{ value_json.illuminance }}',
json_attributes: ['linkquality', 'battery', 'voltage'],
json_attributes: ['linkquality', 'battery', 'voltage', 'last_seen'],
},
},
'sensor_humidity': {
@@ -94,7 +94,7 @@ const configurations = {
unit_of_measurement: '%',
device_class: 'humidity',
value_template: '{{ value_json.humidity }}',
json_attributes: ['linkquality', 'battery', 'voltage'],
json_attributes: ['linkquality', 'battery', 'voltage', 'last_seen'],
},
},
'sensor_temperature': {
@@ -104,7 +104,7 @@ const configurations = {
unit_of_measurement: '°C',
device_class: 'temperature',
value_template: '{{ value_json.temperature }}',
json_attributes: ['linkquality', 'battery', 'voltage'],
json_attributes: ['linkquality', 'battery', 'voltage', 'last_seen'],
},
},
'sensor_pressure': {
@@ -114,7 +114,7 @@ const configurations = {
unit_of_measurement: 'hPa',
device_class: 'pressure',
value_template: '{{ value_json.pressure }}',
json_attributes: ['linkquality', 'battery', 'voltage'],
json_attributes: ['linkquality', 'battery', 'voltage', 'last_seen'],
},
},
'sensor_click': {
@@ -123,7 +123,7 @@ const configurations = {
discovery_payload: {
icon: 'mdi:toggle-switch',
value_template: '{{ value_json.click }}',
json_attributes: ['linkquality', 'battery', 'voltage', 'action', 'duration'],
json_attributes: ['linkquality', 'battery', 'voltage', 'action', 'duration', 'last_seen'],
force_update: true,
},
},
@@ -134,7 +134,9 @@ const configurations = {
unit_of_measurement: 'Watt',
icon: 'mdi:flash',
value_template: '{{ value_json.power }}',
json_attributes: ['linkquality', 'voltage', 'temperature', 'consumption', 'current', 'power_factor'],
json_attributes: [
'linkquality', 'voltage', 'temperature', 'consumption', 'current', 'power_factor', 'last_seen',
],
},
},
'sensor_action': {
@@ -146,6 +148,7 @@ const configurations = {
json_attributes: [
'linkquality', 'battery', 'voltage', 'angle', 'side', 'from_side', 'to_side', 'brightness',
'angle_x_absolute', 'angle_y_absolute', 'angle_z', 'angle_y', 'angle_x', 'unknown_data',
'last_seen',
],
force_update: true,
},
@@ -157,7 +160,7 @@ const configurations = {
unit_of_measurement: 'brightness',
icon: 'mdi:brightness-5',
value_template: '{{ value_json.brightness }}',
json_attributes: ['linkquality'],
json_attributes: ['linkquality', 'last_seen'],
},
},
'sensor_lock': {
@@ -166,7 +169,7 @@ const configurations = {
discovery_payload: {
icon: 'mdi:lock',
value_template: '{{ value_json.inserted }}',
json_attributes: ['linkquality', 'forgotten', 'keyerror'],
json_attributes: ['linkquality', 'forgotten', 'keyerror', 'last_seen'],
},
},
'sensor_battery': {
@@ -175,7 +178,7 @@ const configurations = {
discovery_payload: {
device_class: 'battery',
value_template: '{{ value_json.battery }}',
json_attributes: ['linkquality', 'voltage', 'action', 'sensitivity'],
json_attributes: ['linkquality', 'voltage', 'action', 'sensitivity', 'last_seen'],
},
},
'sensor_linkquality': {
@@ -183,7 +186,7 @@ const configurations = {
object_id: 'linkquality',
discovery_payload: {
value_template: '{{ value_json.linkquality }}',
json_attributes: ['description', 'type', 'rssi'],
json_attributes: ['description', 'type', 'rssi', 'last_seen'],
},
},
+5 -2
View File
@@ -29,7 +29,10 @@ describe('Controller', () => {
const message = utils.zigbeeMessage(device, 'genOnOff', 'devChange', {onOff: 1}, 1);
controller.onZigbeeMessage(message);
chai.assert.isTrue(mqttPublish.calledOnce);
chai.assert.strictEqual(mqttPublish.getCall(0).args[1], JSON.stringify({state: 'ON'}));
chai.assert.strictEqual(
utils.withoutLastSeen(mqttPublish.getCall(0).args[1]),
JSON.stringify({state: 'ON'})
);
});
it('Should handle a zigbee message when include_device_information is set', () => {
@@ -49,7 +52,7 @@ describe('Controller', () => {
controller.onZigbeeMessage(message);
chai.assert.isTrue(mqttPublish.calledOnce);
chai.assert.strictEqual(
mqttPublish.getCall(0).args[1],
utils.withoutLastSeen(mqttPublish.getCall(0).args[1]),
`{"state":"ON","device":{"ieeeAddr":"0x12345678","friendlyName":"test",` +
`"modelId":"TRADFRI bulb E27 CWS opal 600lm"}}`
);
+3 -3
View File
@@ -36,7 +36,7 @@ describe('DeviceReceive', () => {
const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1);
deviceReceive.onZigbeeMessage(message, device, WXKG11LM);
chai.assert.isTrue(publishDeviceState.calledOnce);
chai.assert.deepEqual(publishDeviceState.getCall(0).args[1], {click: 'single'});
chai.assert.deepEqual(utils.withoutLastSeen(publishDeviceState.getCall(0).args[1]), {click: 'single'});
});
it('Should handle a zigbee message which uses ep (left)', () => {
@@ -44,7 +44,7 @@ describe('DeviceReceive', () => {
const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 1);
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishDeviceState.calledOnce);
chai.assert.deepEqual(publishDeviceState.getCall(0).args[1], {click: 'left'});
chai.assert.deepEqual(utils.withoutLastSeen(publishDeviceState.getCall(0).args[1]), {click: 'left'});
});
it('Should handle a zigbee message which uses ep (right)', () => {
@@ -52,7 +52,7 @@ describe('DeviceReceive', () => {
const message = utils.zigbeeMessage(device, 'genOnOff', 'attReport', {onOff: 1}, 2);
deviceReceive.onZigbeeMessage(message, device, WXKG02LM);
chai.assert.isTrue(publishDeviceState.calledOnce);
chai.assert.deepEqual(publishDeviceState.getCall(0).args[1], {click: 'right'});
chai.assert.deepEqual(utils.withoutLastSeen(publishDeviceState.getCall(0).args[1]), {click: 'right'});
});
it('Should handle a zigbee message with default precision', () => {
+15
View File
@@ -10,4 +10,19 @@ module.exports = {
zigbeeMessage: (device, cid, type, data, epId) => {
return {data: {cid: cid, data: data}, type: type, endpoints: [{device: device, epId: epId}]};
},
withoutLastSeen: (obj) => {
const isString = typeof obj === 'string';
if (isString) {
obj = JSON.parse(obj);
}
delete obj.last_seen;
if (isString) {
obj = JSON.stringify(obj);
}
return obj;
},
};