Skip to content

Commit 7e231d5

Browse files
committed
feat(THERMOSTAT): Support modes HEAT, COOL, AUTO, and OFF; close #57, #69
1 parent 0fd8333 commit 7e231d5

File tree

3 files changed

+116
-24
lines changed

3 files changed

+116
-24
lines changed

device-types.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,15 @@ const temperatureScale = (val) => {
351351
return { key: 'scale', value: val }
352352
}
353353

354+
const thermostatMode = (val) => {
355+
const isValid =
356+
val === 'AUTO' || val === 'HEAT' || val === 'COOL' || val === 'OFF'
357+
if (!isValid) {
358+
return false
359+
}
360+
return { key: 'thermostatMode', value: val }
361+
}
362+
354363
//---DECORATORS---
355364

356365
const diffDecoratorFactory = (anotherDecorator) => {
@@ -658,10 +667,13 @@ const types = {
658667
scale: 'CELSIUS',
659668
targetTemperature: 0,
660669
targetScale: 'CELSIUS',
670+
thermostatMode: 'OFF',
671+
powerState: 'OFF',
661672
},
662673
validators: {
663674
temperature: temperatureValue,
664675
scale: temperatureScale,
676+
thermostatMode,
665677
targetTemperature: wrapValidator(temperatureValue, 'targetTemperature'),
666678
targetScale: wrapValidator(temperatureScale, 'targetScale'),
667679
},

directives.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ const directives = {
4444
? 'Position.Up'
4545
: 'Position.Down'
4646
}
47-
4847
return newState
4948
},
5049
SetVolume: (request, currentState) => ({
@@ -153,6 +152,20 @@ const directives = {
153152
targetTemperature: request.directive.payload.targetSetpoint.value,
154153
targetScale: request.directive.payload.targetSetpoint.scale,
155154
}),
155+
SetThermostatMode: (request, currentState) => {
156+
const newState = {
157+
thermostatMode: request.directive.payload.thermostatMode.value,
158+
}
159+
if (
160+
request.directive.payload.thermostatMode.value === 'COOL' ||
161+
request.directive.payload.thermostatMode.value === 'HEAT'
162+
) {
163+
newState['powerState'] = 'ON'
164+
} else if (request.directive.payload.thermostatMode.value === 'OFF') {
165+
newState['powerState'] = 'OFF'
166+
}
167+
return newState
168+
},
156169
AdjustRangeValue: (request, currentState) => {
157170
if (currentState.template === 'FAN') {
158171
const currentSpeed = currentState.speed
@@ -309,6 +322,16 @@ function buildPropertiesFromState(state) {
309322
)
310323
}
311324

325+
if (state.hasOwnProperty('thermostatMode')) {
326+
properties.push(
327+
makeProperty(
328+
'Alexa.ThermostatController',
329+
'thermostatMode',
330+
state.thermostatMode
331+
)
332+
)
333+
}
334+
312335
if (state.hasOwnProperty('muted')) {
313336
properties.push(
314337
makeProperty('Alexa.Speaker', 'muted', {

examples/thermostat.json

Lines changed: 80 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
"id": "f8d7ccba.de9cf",
44
"type": "vsh-virtual-device",
55
"z": "7ecdfb0b.fa7794",
6-
"name": "bedroom thermostat",
6+
"name": "bedroom",
77
"topic": "bedroom/thermostat",
8-
"connection": "",
8+
"connection": "c653a955.290d98",
99
"template": "THERMOSTAT",
1010
"passthrough": true,
11+
"diff": false,
12+
"filter": false,
1113
"x": 940,
12-
"y": 940,
14+
"y": 1400,
1315
"wires": [["185af96.c50b507"]]
1416
},
1517
{
@@ -26,8 +28,8 @@
2628
"once": false,
2729
"onceDelay": 0.1,
2830
"topic": "",
29-
"x": 660,
30-
"y": 940,
31+
"x": 700,
32+
"y": 1400,
3133
"wires": [["f8d7ccba.de9cf"]]
3234
},
3335
{
@@ -42,8 +44,8 @@
4244
"complete": "false",
4345
"statusVal": "",
4446
"statusType": "auto",
45-
"x": 1190,
46-
"y": 940,
47+
"x": 1230,
48+
"y": 1400,
4749
"wires": []
4850
},
4951
{
@@ -60,8 +62,8 @@
6062
"once": false,
6163
"onceDelay": 0.1,
6264
"topic": "",
63-
"x": 660,
64-
"y": 980,
65+
"x": 700,
66+
"y": 1440,
6567
"wires": [["f8d7ccba.de9cf"]]
6668
},
6769
{
@@ -78,8 +80,8 @@
7880
"once": false,
7981
"onceDelay": 0.1,
8082
"topic": "",
81-
"x": 650,
82-
"y": 1060,
83+
"x": 690,
84+
"y": 1520,
8385
"wires": [["f8d7ccba.de9cf"]]
8486
},
8587
{
@@ -96,8 +98,8 @@
9698
"once": false,
9799
"onceDelay": 0.1,
98100
"topic": "",
99-
"x": 660,
100-
"y": 1100,
101+
"x": 700,
102+
"y": 1560,
101103
"wires": [["f8d7ccba.de9cf"]]
102104
},
103105
{
@@ -106,8 +108,8 @@
106108
"z": "7ecdfb0b.fa7794",
107109
"name": "THERMOSTAT",
108110
"info": "",
109-
"x": 640,
110-
"y": 700,
111+
"x": 680,
112+
"y": 1160,
111113
"wires": []
112114
},
113115
{
@@ -116,8 +118,8 @@
116118
"z": "7ecdfb0b.fa7794",
117119
"name": "Alexa, make it warmer in here.",
118120
"info": "",
119-
"x": 720,
120-
"y": 780,
121+
"x": 760,
122+
"y": 1240,
121123
"wires": []
122124
},
123125
{
@@ -126,8 +128,8 @@
126128
"z": "7ecdfb0b.fa7794",
127129
"name": "Alexa, make it cooler in here.",
128130
"info": "",
129-
"x": 720,
130-
"y": 820,
131+
"x": 760,
132+
"y": 1280,
131133
"wires": []
132134
},
133135
{
@@ -136,8 +138,8 @@
136138
"z": "7ecdfb0b.fa7794",
137139
"name": "Alexa, set bedroom thermostat to twenty.",
138140
"info": "",
139-
"x": 760,
140-
"y": 740,
141+
"x": 800,
142+
"y": 1200,
141143
"wires": []
142144
},
143145
{
@@ -146,8 +148,63 @@
146148
"z": "7ecdfb0b.fa7794",
147149
"name": "Alexa, what's the temperature of bedroom thermostat?",
148150
"info": "",
149-
"x": 800,
150-
"y": 860,
151+
"x": 840,
152+
"y": 1320,
151153
"wires": []
154+
},
155+
{
156+
"id": "7b1a6735.ced7a8",
157+
"type": "inject",
158+
"z": "7ecdfb0b.fa7794",
159+
"name": "mode = AUTO",
160+
"props": [{ "p": "payload.thermostatMode", "v": "AUTO", "vt": "str" }],
161+
"repeat": "",
162+
"crontab": "",
163+
"once": false,
164+
"onceDelay": 0.1,
165+
"topic": "",
166+
"x": 670,
167+
"y": 1640,
168+
"wires": [["f8d7ccba.de9cf"]]
169+
},
170+
{
171+
"id": "5e3718a.25277e8",
172+
"type": "inject",
173+
"z": "7ecdfb0b.fa7794",
174+
"name": "mode = HEAT",
175+
"props": [{ "p": "payload.thermostatMode", "v": "HEAT", "vt": "str" }],
176+
"repeat": "",
177+
"crontab": "",
178+
"once": false,
179+
"onceDelay": 0.1,
180+
"topic": "",
181+
"x": 670,
182+
"y": 1680,
183+
"wires": [["f8d7ccba.de9cf"]]
184+
},
185+
{
186+
"id": "1072ec7.feef314",
187+
"type": "inject",
188+
"z": "7ecdfb0b.fa7794",
189+
"name": "mode = COOL",
190+
"props": [{ "p": "payload.thermostatMode", "v": "COOL", "vt": "str" }],
191+
"repeat": "",
192+
"crontab": "",
193+
"once": false,
194+
"onceDelay": 0.1,
195+
"topic": "",
196+
"x": 680,
197+
"y": 1720,
198+
"wires": [["f8d7ccba.de9cf"]]
199+
},
200+
{
201+
"id": "c653a955.290d98",
202+
"type": "vsh-connection",
203+
"name": "SANDBOX: cornelius.suermann@gmail.com",
204+
"port": "8883",
205+
"accessTokenExpiry": "1623058880575",
206+
"debug": true,
207+
"backendUrl": "https://hbsky6oavf.execute-api.eu-west-1.amazonaws.com/dev",
208+
"lwaClientId": "amzn1.application-oa2-client.cc2605d7d7d64fb28b90e75f64622bfa"
152209
}
153210
]

0 commit comments

Comments
 (0)