Skip to content

Commit 83d6c91

Browse files
committed
Adding support for thermostats
1 parent 86b7443 commit 83d6c91

11 files changed

Lines changed: 494 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
All notable changes to homebridge-dummy will be documented in this file.
44

5-
## 1.3.0-beta.3 (2025-09-XX)
5+
## 1.3.0-beta.4 (2025-09-XX)
66

77
### HELP NEEDED! (no coding experience required)
88

99
Would you like to see Homebridge Easy MQTT in your language? Please consider [getting involved](https://github.com/mpatfield/homebridge-easy-mqtt/issues/4).
1010

1111
### Added
12+
- Support for Thermostats
1213
- Support for CO, CO2, Contact, Humidity, Leak, Motion, Occupancy, and Smoke sensors
1314
- Support for arbitrary custom characteristics ([documentation](https://github.com/mpatfield/homebridge-easy-mqtt#custom-characteristics))
1415
- JSONPath support in setter topics ([documentation](https://github.com/mpatfield/homebridge-easy-mqtt#jsonpaths))

README.md

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ This plugin is designed to be a simple replacement for the fantastic [homebridge
3939
- `SmokeSensor`
4040
- `Switch`
4141
- `TemperatureSensor`
42+
- `Thermostat`
4243

4344
## Configuration
4445

@@ -197,14 +198,34 @@ As with topics, you will also need to populate the appropriate values based on t
197198
- `topicSetTargetSecurityState*` — For setting the target state of the system
198199
- `topicGetStatusFault` — For getting whether there is a system error
199200
- `topicGetStatusTampered` — For getting whether the system has been tampered with
200-
- `valueArmStay` - system armed in stay mode, e.g. "SA" or "stay"
201-
- `valueArmAway` - system armed in away mode, e.g. "AA" or "away"
202-
- `valueArmNight` - system armed in night mode, e.g. "NA" or "night"
203-
- `valueDisarm` - system armed in away mode, e.g. "D" or "disarmed"
204-
- `valueAlarmTriggered` - when the alarm has been triggered, e.g. "true" or "1" or "triggered"
201+
- `valueArmStay` - System armed in stay mode, e.g. "SA" or "stay"
202+
- `valueArmAway` - System armed in away mode, e.g. "AA" or "away"
203+
- `valueArmNight` - System armed in night mode, e.g. "NA" or "night"
204+
- `valueDisarm` - System armed in away mode, e.g. "D" or "disarmed"
205+
- `valueAlarmTriggered` - When the alarm has been triggered, e.g. "true" or "1" or "triggered"
205206
- `valueFault` - Accessory has a fault
206207
- `valueTampered` - Accessory has been tampered with
207208

209+
### Thermostat
210+
- `temperatureUnits` - The temperature units of the incoming value supplied by the thermostat, `C` for Celsius (default) `F` for Fahrenheit
211+
- `topicGetCurrentHeatingCoolingState*` - Get the current mode (i.e. cooling, heating, off)
212+
- `topicGetTargetHeatingCoolingState*` - Get the target mode (i.e. auto, cooling, heating, off)
213+
- `topicSetTargetHeatingCoolingState*` - Set the target mode (i.e. auto, cooling, heating, off)
214+
- `topicGetCurrentTemperature*` - Get the current temperature
215+
- `topicGetTargetTemperature*` - Get the target temperature
216+
- `topicSetTargetTemperature*` - Set the target temperature
217+
- `topicGetCurrentRelativeHumidity` - Get the current humidity
218+
- `topicGetTargetRelativeHumidity` - Get the target humidity
219+
- `topicSetTargetRelativeHumidity` - Set the target humidity
220+
- `topicGetCoolingThresholdTemperature` - Get the cooling threshold temperature
221+
- `topicSetCoolingThresholdTemperature` - Set the cooling threshold temparture
222+
- `topicGetHeatingThresholdTemperature` - Get the heating threshold temperature
223+
- `topicSetHeatingThresholdTemperature` - Set the heating threshold temperature
224+
- `valueModeAuto` - Auto mode
225+
- `valueModeCool` - Cool mode
226+
- `valueModeHeat` - Heat mode
227+
- `valueModeOff` - Thermostat off
228+
208229
## Logging/Debugging:
209230

210231
By default, devices will log activity, for example when a Switch is turned on or a LockMechanism is unlocked.

config.schema.json

Lines changed: 211 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
"type": {
2222
"type": "string",
2323
"title": "${config.title.type}",
24-
"enum": [ "CarbonMonoxideSensor", "CarbonDioxideSensor", "ContactSensor", "HumiditySensor", "LeakSensor", "Lightbulb", "LockMechanism", "MotionSensor", "OccupancySensor", "Outlet", "SecuritySystem", "SmokeSensor", "Switch", "TemperatureSensor"],
25-
"enumNames": ["${config.enumNames.carbonMonoxideSensor}", "${config.enumNames.carbonDioxideSensor}", "${config.enumNames.contactSensor}", "${config.enumNames.humiditySensor}", "${config.enumNames.leakSensor}", "${config.enumNames.lightbulb}", "${config.enumNames.lockMechanism}", "${config.enumNames.motionSensor}", "${config.enumNames.occupancySensor}", "${config.enumNames.outlet}", "${config.enumNames.securitySystem}", "${config.enumNames.smokeSensor}", "${config.enumNames.switch}", "${config.enumNames.temperatureSensor}"],
24+
"enum": [ "CarbonMonoxideSensor", "CarbonDioxideSensor", "ContactSensor", "HumiditySensor", "LeakSensor", "Lightbulb", "LockMechanism", "MotionSensor", "OccupancySensor", "Outlet", "SecuritySystem", "SmokeSensor", "Switch", "TemperatureSensor", "Thermostat"],
25+
"enumNames": ["${config.enumNames.carbonMonoxideSensor}", "${config.enumNames.carbonDioxideSensor}", "${config.enumNames.contactSensor}", "${config.enumNames.humiditySensor}", "${config.enumNames.leakSensor}", "${config.enumNames.lightbulb}", "${config.enumNames.lockMechanism}", "${config.enumNames.motionSensor}", "${config.enumNames.occupancySensor}", "${config.enumNames.outlet}", "${config.enumNames.securitySystem}", "${config.enumNames.smokeSensor}", "${config.enumNames.switch}", "${config.enumNames.temperatureSensor}", "${config.enumNames.thermostat}"],
2626
"required": true
2727
},
2828
"manufacturer": {
@@ -247,6 +247,50 @@
247247
"type": "string",
248248
"title": "${config.title.topicGetCurrentTemperature}"
249249
},
250+
"topicGetCurrentHeatingCoolingState": {
251+
"type": "string",
252+
"title": "${config.title.topicGetCurrentHeatingCoolingState}"
253+
},
254+
"topicGetTargetHeatingCoolingState": {
255+
"type": "string",
256+
"title": "${config.title.topicGetTargetHeatingCoolingState}"
257+
},
258+
"topicSetTargetHeatingCoolingState": {
259+
"type": "string",
260+
"title": "${config.title.topicSetTargetHeatingCoolingState}"
261+
},
262+
"topicGetTargetTemperature": {
263+
"type": "string",
264+
"title": "${config.title.topicGetTargetTemperature}"
265+
},
266+
"topicSetTargetTemperature": {
267+
"type": "string",
268+
"title": "${config.title.topicSetTargetTemperature}"
269+
},
270+
"topicGetTargetRelativeHumidity": {
271+
"type": "string",
272+
"title": "${config.title.topicGetTargetRelativeHumidity}"
273+
},
274+
"topicSetTargetRelativeHumidity": {
275+
"type": "string",
276+
"title": "${config.title.topicSetTargetRelativeHumidity}"
277+
},
278+
"topicGetCoolingThresholdTemperature": {
279+
"type": "string",
280+
"title": "${config.title.topicGetCoolingThresholdTemperature}"
281+
},
282+
"topicSetCoolingThresholdTemperature": {
283+
"type": "string",
284+
"title": "${config.title.topicSetCoolingThresholdTemperature}"
285+
},
286+
"topicGetHeatingThresholdTemperature": {
287+
"type": "string",
288+
"title": "${config.title.topicGetHeatingThresholdTemperature}"
289+
},
290+
"topicSetHeatingThresholdTemperature": {
291+
"type": "string",
292+
"title": "${config.title.topicSetHeatingThresholdTemperature}"
293+
},
250294
"valueBatteryLow": {
251295
"type": "string",
252296
"title": "${config.title.valueBatteryLow}"
@@ -335,6 +379,22 @@
335379
"type": "string",
336380
"title": "${config.title.valueSmokeDetected}"
337381
},
382+
"valueModeAuto": {
383+
"type": "string",
384+
"title": "${config.title.valueModeAuto}"
385+
},
386+
"valueModeCool": {
387+
"type": "string",
388+
"title": "${config.title.valueModeCool}"
389+
},
390+
"valueModeHeat": {
391+
"type": "string",
392+
"title": "${config.title.valueModeHeat}"
393+
},
394+
"valueModeOff": {
395+
"type": "string",
396+
"title": "${config.title.valueModeOff}"
397+
},
338398
"disableLogging": {
339399
"type": "boolean",
340400
"title": "${config.title.disableLogging}"
@@ -768,6 +828,129 @@
768828
}
769829
]
770830
},
831+
{
832+
"type": "fieldset",
833+
"notitle": true,
834+
"condition": {
835+
"functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Thermostat';"
836+
},
837+
"items": [
838+
{
839+
"type": "div",
840+
"displayFlex": true,
841+
"flex-direction": "row",
842+
"items": [
843+
{
844+
"key": "accessories[].topicGetCurrentHeatingCoolingState",
845+
"flex": "0 0 50%"
846+
}
847+
]
848+
},
849+
{
850+
"type": "div",
851+
"displayFlex": true,
852+
"flex-direction": "row",
853+
"items": [
854+
{
855+
"key": "accessories[].topicGetTargetHeatingCoolingState",
856+
"flex": "0 0 50%"
857+
},
858+
{
859+
"key": "accessories[].topicSetTargetHeatingCoolingState",
860+
"flex": "0 0 50%"
861+
}
862+
]
863+
},
864+
{
865+
"type": "div",
866+
"displayFlex": true,
867+
"flex-direction": "row",
868+
"items": [
869+
{
870+
"key": "accessories[].topicGetCurrentTemperature",
871+
"flex": "0 0 50%"
872+
},
873+
{
874+
"key": "accessories[].temperatureUnits",
875+
"title": "${config.title.sourceUnits}",
876+
"flex": "0 0 33%"
877+
}
878+
]
879+
},
880+
{
881+
"type": "div",
882+
"displayFlex": true,
883+
"flex-direction": "row",
884+
"items": [
885+
{
886+
"key": "accessories[].topicGetTargetTemperature",
887+
"flex": "0 0 50%"
888+
},
889+
{
890+
"key": "accessories[].topicSetTargetTemperature",
891+
"flex": "0 0 50%"
892+
}
893+
]
894+
},
895+
{
896+
"type": "div",
897+
"displayFlex": true,
898+
"flex-direction": "row",
899+
"items": [
900+
{
901+
"key": "accessories[].topicGetCurrentRelativeHumidity",
902+
"title": "${config.title.topicGetCurrentRelativeHumidityOptional}",
903+
"flex": "0 0 50%"
904+
}
905+
]
906+
},
907+
{
908+
"type": "div",
909+
"displayFlex": true,
910+
"flex-direction": "row",
911+
"items": [
912+
{
913+
"key": "accessories[].topicGetTargetRelativeHumidity",
914+
"flex": "0 0 50%"
915+
},
916+
{
917+
"key": "accessories[].topicSetTargetRelativeHumidity",
918+
"flex": "0 0 50%"
919+
}
920+
]
921+
},
922+
{
923+
"type": "div",
924+
"displayFlex": true,
925+
"flex-direction": "row",
926+
"items": [
927+
{
928+
"key": "accessories[].topicGetCoolingThresholdTemperature",
929+
"flex": "0 0 50%"
930+
},
931+
{
932+
"key": "accessories[].topicSetCoolingThresholdTemperature",
933+
"flex": "0 0 50%"
934+
}
935+
]
936+
},
937+
{
938+
"type": "div",
939+
"displayFlex": true,
940+
"flex-direction": "row",
941+
"items": [
942+
{
943+
"key": "accessories[].topicGetHeatingThresholdTemperature",
944+
"flex": "0 0 50%"
945+
},
946+
{
947+
"key": "accessories[].topicSetHeatingThresholdTemperature",
948+
"flex": "0 0 50%"
949+
}
950+
]
951+
}
952+
]
953+
},
771954
{
772955
"type": "div",
773956
"displayFlex": true,
@@ -926,6 +1109,32 @@
9261109
}
9271110
]
9281111
},
1112+
{
1113+
"type": "div",
1114+
"displayFlex": true,
1115+
"flex-direction": "row",
1116+
"condition": {
1117+
"functionBody": "return model.accessories?.[arguments[1]]?.info?.type === 'Thermostat';"
1118+
},
1119+
"items": [
1120+
{
1121+
"key": "accessories[].valueModeAuto",
1122+
"flex": "0 0 25%"
1123+
},
1124+
{
1125+
"key": "accessories[].valueModeCool",
1126+
"flex": "0 0 25%"
1127+
},
1128+
{
1129+
"key": "accessories[].valueModeHeat",
1130+
"flex": "0 0 25%"
1131+
},
1132+
{
1133+
"key": "accessories[].valueModeOff",
1134+
"flex": "0 0 25%"
1135+
}
1136+
]
1137+
},
9291138
{
9301139
"type": "div",
9311140
"displayFlex": true,

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"displayName": "Homebridge Easy MQTT",
55
"description": "Homebridge plugin for easy control of MQTT devices",
66
"type": "module",
7-
"version": "1.3.0-beta.3",
7+
"version": "1.3.0-beta.4",
88
"homepage": "https://github.com/mpatfield/homebridge-easy-mqtt#readme",
99
"repository": {
1010
"type": "git",

src/accessory/abstract/mqtt.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,12 @@ export abstract class MQTTAccessory<C extends MQTTAccessoryConfig> {
206206
return assert(this.log, this.name, this.config, ...keys);
207207
}
208208

209+
protected setCharacteristicValue(key: CharacteristicKey, value: CharacteristicValue) {
210+
this.accessoryService.getCharacteristic(this.Characteristic[key]).onGet( () => {
211+
return value;
212+
});
213+
}
214+
209215
protected onUpdate(key: CharacteristicKey, value: CharacteristicValue, logString: string | undefined = undefined): boolean {
210216

211217
if (value === this.properties.get(key)) {

0 commit comments

Comments
 (0)