From 2e2e64d2d04c1734c51248bf5b4317116042302c Mon Sep 17 00:00:00 2001 From: Pascal Bourque Date: Sat, 7 Jun 2025 09:35:48 -0400 Subject: [PATCH] feat: Temperature and humidity sensors (#6) --- src/thermostat.ts | 48 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/thermostat.ts b/src/thermostat.ts index 507b812..51b54f3 100644 --- a/src/thermostat.ts +++ b/src/thermostat.ts @@ -28,6 +28,8 @@ export class Thermostat { private isStarted = false; private readonly mqttDevice: DeviceConfiguration; private readonly mqttClimate: Climate; + private readonly mqttTemperature: Sensor; + private readonly mqttHumidity: Sensor; private readonly mqttPower: Sensor; private readonly mysaStatusUpdateHandler = this.handleMysaStatusUpdate.bind(this); @@ -104,6 +106,38 @@ export class Thermostat { } ); + this.mqttTemperature = new Sensor({ + mqtt: this.mqttSettings, + logger: this.logger, + component: { + component: 'sensor', + device: this.mqttDevice, + unique_id: `mysa_${mysaDevice.Id}_temperature`, + name: 'Current temperature', + device_class: 'temperature', + state_class: 'measurement', + unit_of_measurement: '°C', + suggested_display_precision: 1, + force_update: true + } + }); + + this.mqttHumidity = new Sensor({ + mqtt: this.mqttSettings, + logger: this.logger, + component: { + component: 'sensor', + device: this.mqttDevice, + unique_id: `mysa_${mysaDevice.Id}_humidity`, + name: 'Current humidity', + device_class: 'humidity', + state_class: 'measurement', + unit_of_measurement: '%', + suggested_display_precision: 0, + force_update: true + } + }); + this.mqttPower = new Sensor({ mqtt: this.mqttSettings, logger: this.logger, @@ -111,6 +145,7 @@ export class Thermostat { component: 'sensor', device: this.mqttDevice, unique_id: `mysa_${mysaDevice.Id}_power`, + name: 'Current power', device_class: 'power', state_class: 'measurement', unit_of_measurement: 'W', @@ -136,9 +171,14 @@ export class Thermostat { this.mqttClimate.currentMode = state.TstatMode.v === 1 ? 'off' : state.TstatMode.v === 3 ? 'heat' : undefined; this.mqttClimate.currentAction = this.computeCurrentAction(undefined, state.Duty.v); this.mqttClimate.targetTemperature = this.mqttClimate.currentMode !== 'off' ? state.SetPoint.v : undefined; - await this.mqttClimate.writeConfig(); + await this.mqttTemperature.setState('state_topic', state.CorrectedTemp.v.toFixed(2)); + await this.mqttTemperature.writeConfig(); + + await this.mqttHumidity.setState('state_topic', state.Humidity.v.toFixed(2)); + await this.mqttHumidity.writeConfig(); + // `state.Current.v` always has a non-zero value, even for thermostats that are off, so we can't use it to determine initial power state. await this.mqttPower.setState('state_topic', 'None'); await this.mqttPower.writeConfig(); @@ -166,6 +206,8 @@ export class Thermostat { this.mysaApiClient.emitter.off('stateChanged', this.mysaStateChangeHandler); await this.mqttPower.setState('state_topic', 'None'); + await this.mqttTemperature.setState('state_topic', 'None'); + await this.mqttHumidity.setState('state_topic', 'None'); } private async handleMysaStatusUpdate(status: Status) { @@ -184,6 +226,9 @@ export class Thermostat { } else { await this.mqttPower.setState('state_topic', 'None'); } + + await this.mqttTemperature.setState('state_topic', status.temperature.toFixed(2)); + await this.mqttHumidity.setState('state_topic', status.humidity.toFixed(2)); } private async handleMysaStateChange(state: StateChange) { @@ -200,6 +245,7 @@ export class Thermostat { case 'heat': this.mqttClimate.currentMode = 'heat'; + this.mqttClimate.targetTemperature = state.setPoint; break; } }