Skip to content

Commit

Permalink
Add DS18x20 temp device
Browse files Browse the repository at this point in the history
  • Loading branch information
atrovato committed Sep 17, 2022
1 parent 1e6a676 commit 987f672
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 1 deletion.
2 changes: 1 addition & 1 deletion server/services/tasmota/lib/features/temperature.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const {

module.exports = {
// Tasmota matcher
keyMatcher: /^StatusSNS\.(DHT11|AM2301|ENERGY\.BL09XX)\.Temperature$/,
keyMatcher: /^StatusSNS\.(DHT11|AM2301|ENERGY\.BL09XX|DS18B20(-\d+)?|DS18S20(-\d+)?|DS1822(-\d+)?|MAX31850(-\d+)?)\.Temperature$/,
// Gladys feature
generateFeature: () => {
return {
Expand Down
45 changes: 45 additions & 0 deletions server/test/services/tasmota/lib/device-creation/DS18B20.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"STATUS": {
"Status": {
"ButtonRetain": 0,
"ButtonTopic": "0",
"FriendlyName": ["Tasmota"],
"LedMask": "FFFF",
"LedState": 1,
"Module": 18,
"Power": 0,
"PowerOnState": 1,
"PowerRetain": 0,
"SaveData": 1,
"SaveState": 1,
"SensorRetain": 0,
"SwitchMode": [0, 0, 0, 0, 0, 0, 0, 0],
"SwitchRetain": 0,
"SwitchTopic": "0",
"Topic": "tasmota"
}
},
"STATUS11": {
"StatusSTS": {
"MqttCount": 1,
"Sleep": 50,
"SleepMode": "Dynamic",
"Wifi": {
"AP": 1,
"BSSId": "EC:BE:DD:85:1F:E0",
"Channel": 1,
"LinkCount": 1,
"SSId": "ALEX-NETWORK"
}
}
},
"STATUS8": {
"StatusSNS": {
"Time": "2021-01-02T09:09:44",
"DS18B20-1": { "Id": "00000566CC39", "Temperature": 13.3 },
"DS18B20-2": { "Id": "0000059352D4", "Temperature": 1.2 },
"DS18B20-3": { "Id": "000005937C90", "Temperature": 22.5 },
"TempUnit": "C"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
const sinon = require('sinon');
const { expect } = require('chai');

const { fake, assert } = sinon;
const TasmotaHandler = require('../../../../../../../services/tasmota/lib');
const {
DEVICE_FEATURE_CATEGORIES,
DEVICE_FEATURE_TYPES,
DEVICE_FEATURE_UNITS,
EVENTS,
WEBSOCKET_MESSAGE_TYPES,
} = require('../../../../../../../utils/constants');

const messages = require('../../../device-creation/DS18B20.json');

const mqttService = {
device: {
publish: fake.returns(null),
},
};
const gladys = {
event: {
emit: fake.returns(null),
},
stateManager: {
get: fake.returns(null),
},
};
const serviceId = 'service-uuid-random';

describe('Tasmota - MQTT - create device with DS18B20 temperature feature', () => {
const tasmota = new TasmotaHandler(gladys, serviceId);
const tasmotaHandler = tasmota.protocols.mqtt;
tasmotaHandler.mqttService = mqttService;

beforeEach(() => {
sinon.reset();
});

it('decode STATUS message', () => {
tasmotaHandler.handleMessage('stat/tasmota-device-topic/STATUS', JSON.stringify(messages.STATUS));

expect(tasmotaHandler.discoveredDevices).to.deep.eq({});
expect(tasmotaHandler.pendingDevices).to.deep.eq({
'tasmota-device-topic': {
name: 'Tasmota',
params: [
{
name: 'protocol',
value: 'mqtt',
},
],
model: 18,
external_id: 'tasmota:tasmota-device-topic',
selector: 'tasmota-tasmota-device-topic',
service_id: serviceId,
should_poll: false,
features: [],
},
});

assert.notCalled(gladys.event.emit);
assert.notCalled(gladys.stateManager.get);
assert.calledOnceWithExactly(mqttService.device.publish, 'cmnd/tasmota-device-topic/STATUS', '11');
});

it('decode STATUS11 message', () => {
tasmotaHandler.handleMessage('stat/tasmota-device-topic/STATUS11', JSON.stringify(messages.STATUS11));

expect(tasmotaHandler.discoveredDevices).to.deep.eq({});
expect(tasmotaHandler.pendingDevices).to.deep.eq({
'tasmota-device-topic': {
name: 'Tasmota',
params: [
{
name: 'protocol',
value: 'mqtt',
},
],
model: 18,
external_id: 'tasmota:tasmota-device-topic',
selector: 'tasmota-tasmota-device-topic',
service_id: serviceId,
should_poll: false,
features: [],
},
});

assert.notCalled(gladys.event.emit);
assert.notCalled(gladys.stateManager.get);
assert.calledOnceWithExactly(mqttService.device.publish, 'cmnd/tasmota-device-topic/STATUS', '8');
});

it('decode STATUS8 message', () => {
tasmotaHandler.handleMessage('stat/tasmota-device-topic/STATUS8', JSON.stringify(messages.STATUS8));

const expectedDevice = {
name: 'Tasmota',
params: [
{
name: 'protocol',
value: 'mqtt',
},
],
model: 18,
external_id: 'tasmota:tasmota-device-topic',
selector: 'tasmota-tasmota-device-topic',
service_id: serviceId,
should_poll: false,
features: [
{
category: DEVICE_FEATURE_CATEGORIES.TEMPERATURE_SENSOR,
type: DEVICE_FEATURE_TYPES.SENSOR.DECIMAL,
unit: DEVICE_FEATURE_UNITS.CELSIUS,
external_id: 'tasmota:tasmota-device-topic:DS18B20-1:Temperature',
selector: 'tasmota-tasmota-device-topic-ds18b20-1-temperature',
name: 'Temperature',
read_only: true,
has_feedback: false,
min: -100,
max: 200,
last_value: 13.3,
},
{
category: DEVICE_FEATURE_CATEGORIES.TEMPERATURE_SENSOR,
type: DEVICE_FEATURE_TYPES.SENSOR.DECIMAL,
unit: DEVICE_FEATURE_UNITS.CELSIUS,
external_id: 'tasmota:tasmota-device-topic:DS18B20-2:Temperature',
selector: 'tasmota-tasmota-device-topic-ds18b20-2-temperature',
name: 'Temperature',
read_only: true,
has_feedback: false,
min: -100,
max: 200,
last_value: 1.2,
},
{
category: DEVICE_FEATURE_CATEGORIES.TEMPERATURE_SENSOR,
type: DEVICE_FEATURE_TYPES.SENSOR.DECIMAL,
unit: DEVICE_FEATURE_UNITS.CELSIUS,
external_id: 'tasmota:tasmota-device-topic:DS18B20-3:Temperature',
selector: 'tasmota-tasmota-device-topic-ds18b20-3-temperature',
name: 'Temperature',
read_only: true,
has_feedback: false,
min: -100,
max: 200,
last_value: 22.5,
},
],
};
expect(tasmotaHandler.discoveredDevices).to.deep.eq({
'tasmota-device-topic': expectedDevice,
});
expect(tasmotaHandler.pendingDevices).to.deep.eq({});

assert.notCalled(mqttService.device.publish);
assert.calledOnceWithExactly(gladys.stateManager.get, 'deviceByExternalId', 'tasmota:tasmota-device-topic');

assert.callCount(gladys.event.emit, 4);
assert.calledWithExactly(gladys.event.emit, EVENTS.DEVICE.NEW_STATE, {
device_feature_external_id: 'tasmota:tasmota-device-topic:DS18B20-1:Temperature',
state: 13.3,
});
assert.calledWithExactly(gladys.event.emit, EVENTS.DEVICE.NEW_STATE, {
device_feature_external_id: 'tasmota:tasmota-device-topic:DS18B20-2:Temperature',
state: 1.2,
});
assert.calledWithExactly(gladys.event.emit, EVENTS.DEVICE.NEW_STATE, {
device_feature_external_id: 'tasmota:tasmota-device-topic:DS18B20-3:Temperature',
state: 22.5,
});
assert.calledWithExactly(gladys.event.emit, EVENTS.WEBSOCKET.SEND_ALL, {
type: WEBSOCKET_MESSAGE_TYPES.TASMOTA.NEW_MQTT_DEVICE,
payload: expectedDevice,
});
});
});

0 comments on commit 987f672

Please sign in to comment.