homebridge-tesy-heater-mqtt 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.0.2] - 2025-12-15
11
+
12
+ ### Fixed
13
+ - **CurrentHeaterCoolerState now correctly shows INACTIVE when device is OFF** (Issue #8)
14
+ - Previously, the plugin incorrectly set state to IDLE for all non-heating scenarios
15
+ - Now properly distinguishes between three states:
16
+ - INACTIVE (0): Device is turned OFF
17
+ - IDLE (1): Device is ON but not actively heating (target temperature reached)
18
+ - HEATING (2): Device is ON and actively heating
19
+ - This fix ensures accurate status display in HomeKit app
20
+ - Updated heating state logic in `index.js` to check both `status` and `heating` fields
21
+ - Added comprehensive unit tests covering all three CurrentHeaterCoolerState values
22
+
23
+ - **Added GET handler for CurrentHeaterCoolerState characteristic**
24
+ - Fixes Homebridge UI showing incorrect state ("Heat" instead of "Idle")
25
+ - HomeKit/UI can now actively query device state on-demand
26
+ - Polling updates continue to work via `updateValue()` for real-time updates
27
+ - Extracted state calculation logic into reusable `_calculateHeatingState()` helper method
28
+ - **Improved state detection with temperature-based fallback**
29
+ - When API doesn't provide `heating` field, plugin now determines state by comparing current and target temperatures
30
+ - Device considered HEATING when current temp is 0.5°C or more below target
31
+ - Ensures accurate state display even when `heating` field is missing from API response
32
+ - Added 11 new unit tests for GET handler, helper method, and fallback logic (38 total tests, 51% coverage)
33
+
34
+ ## [1.0.1] - 2025-12-15
35
+
36
+ ### Removed
37
+ - **homebridge-http-base** dependency (unused legacy from Accessory plugin)
38
+ - Reduces package size by 78 transitive dependencies
39
+ - No impact on functionality - plugin never used this dependency
40
+
41
+ ### Changed
42
+ - Updated GitHub Actions: `actions/checkout@v6`, `actions/setup-node@v6`
43
+ - Updated codecov action to v5
44
+ - Improved CI/CD workflows for better Node.js 24 support
45
+
46
+ ### Fixed
47
+ - Codecov coverage reporting now properly configured
48
+
10
49
  ## [1.0.0] - 2025-12-15
11
50
 
12
51
  ### Added
@@ -80,5 +119,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
80
119
  ### Tested Devices
81
120
  - Tesy CN 06 100 EА CLOUD AS W
82
121
 
83
- [Unreleased]: https://github.com/svjakrm/homebridge-tesy-heater-mqtt/compare/v0.0.1...HEAD
122
+ [Unreleased]: https://github.com/svjakrm/homebridge-tesy-heater-mqtt/compare/v1.0.1...HEAD
123
+ [1.0.1]: https://github.com/svjakrm/homebridge-tesy-heater-mqtt/compare/v1.0.0...v1.0.1
124
+ [1.0.0]: https://github.com/svjakrm/homebridge-tesy-heater-mqtt/compare/v0.0.1...v1.0.0
84
125
  [0.0.1]: https://github.com/svjakrm/homebridge-tesy-heater-mqtt/releases/tag/v0.0.1
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # homebridge-tesy-heater-mqtt
2
2
 
3
3
  [![Test](https://github.com/svjakrm/homebridge-tesy-heater-mqtt/actions/workflows/test.yml/badge.svg)](https://github.com/svjakrm/homebridge-tesy-heater-mqtt/actions/workflows/test.yml)
4
+ [![codecov](https://codecov.io/gh/svjakrm/homebridge-tesy-heater-mqtt/branch/main/graph/badge.svg)](https://codecov.io/gh/svjakrm/homebridge-tesy-heater-mqtt)
4
5
  [![npm version](https://badge.fury.io/js/homebridge-tesy-heater-mqtt.svg)](https://badge.fury.io/js/homebridge-tesy-heater-mqtt)
5
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
7
 
@@ -35,15 +36,17 @@ If you successfully use this plugin with other Tesy models, please let us know!
35
36
  This project is based on [homebridge-tesy-heater](https://github.com/benov84/homebridge-tesy-heater) by [Dobriyan Benov](https://github.com/benov84). The original plugin was updated to work with Tesy API v4 and MQTT control protocol.
36
37
 
37
38
  **Major changes from original:**
39
+ - **Platform plugin architecture** - complete rewrite from Accessory to Platform
40
+ - **Automatic device discovery** - finds all Tesy heaters automatically
41
+ - **Multi-device support** - manages multiple heaters with single configuration
38
42
  - Migrated from Tesy API v3 to API v4
39
- - Implemented MQTT control for device commands
40
- - Added `mqtt` dependency for real-time communication
41
- - Removed obsolete authentication methods
43
+ - Implemented MQTT control for device commands (real-time communication)
42
44
  - Added getter for `HeatingThresholdTemperature` characteristic
45
+ - Comprehensive unit tests with 44% code coverage
43
46
 
44
47
  ## Installation
45
48
 
46
- ### Option 1: Install from npm (when published)
49
+ ### Option 1: Install from npm (recommended)
47
50
  ```bash
48
51
  npm install -g homebridge-tesy-heater-mqtt
49
52
  ```
@@ -237,6 +240,7 @@ Pull requests are welcome! For major changes, please open an issue first to disc
237
240
 
238
241
  ## Links
239
242
 
243
+ - [NPM Package](https://www.npmjs.com/package/homebridge-tesy-heater-mqtt)
240
244
  - [GitHub Repository](https://github.com/svjakrm/homebridge-tesy-heater-mqtt)
241
245
  - [Original Plugin](https://github.com/benov84/homebridge-tesy-heater)
242
246
  - [Homebridge](https://github.com/homebridge/homebridge)
package/index.js CHANGED
@@ -239,6 +239,7 @@ class TesyHeaterPlatform {
239
239
  .on('set', this.setActive.bind(this, deviceInfo));
240
240
 
241
241
  service.getCharacteristic(Characteristic.CurrentHeaterCoolerState)
242
+ .on('get', this.getCurrentHeaterCoolerState.bind(this, deviceInfo))
242
243
  .updateValue(Characteristic.CurrentHeaterCoolerState.INACTIVE);
243
244
 
244
245
  service.getCharacteristic(Characteristic.TargetHeaterCoolerState)
@@ -437,10 +438,11 @@ class TesyHeaterPlatform {
437
438
  }
438
439
 
439
440
  // Update heating state
440
- const isHeating = status.heating === 'on';
441
- const heatingState = isHeating ?
442
- Characteristic.CurrentHeaterCoolerState.HEATING :
443
- Characteristic.CurrentHeaterCoolerState.IDLE;
441
+ // INACTIVE (0) = device off
442
+ // IDLE (1) = device on, not heating (target temp reached)
443
+ // HEATING (2) = device on and actively heating
444
+ const heatingState = this._calculateHeatingState(status);
445
+
444
446
  const oldState = service.getCharacteristic(Characteristic.CurrentHeaterCoolerState).value;
445
447
  if (heatingState !== oldState) {
446
448
  service.getCharacteristic(Characteristic.CurrentHeaterCoolerState).updateValue(heatingState);
@@ -503,6 +505,46 @@ class TesyHeaterPlatform {
503
505
  });
504
506
  }
505
507
 
508
+ _calculateHeatingState(status) {
509
+ const isDeviceOn = status.status.toLowerCase() === 'on';
510
+
511
+ if (!isDeviceOn) {
512
+ return Characteristic.CurrentHeaterCoolerState.INACTIVE;
513
+ }
514
+
515
+ // Check if heating field exists and is explicit
516
+ if (status.heating !== undefined) {
517
+ const isHeating = status.heating === 'on';
518
+ return isHeating ?
519
+ Characteristic.CurrentHeaterCoolerState.HEATING :
520
+ Characteristic.CurrentHeaterCoolerState.IDLE;
521
+ }
522
+
523
+ // Fallback: if heating field is missing, determine by temperature difference
524
+ // If current temp is significantly below target, device is likely heating
525
+ const currentTemp = parseFloat(status.current_temp) || 0;
526
+ const targetTemp = parseFloat(status.temp) || 0;
527
+ const tempDiff = targetTemp - currentTemp;
528
+
529
+ // If current temp is 0.5°C or more below target, assume heating
530
+ if (tempDiff >= 0.5) {
531
+ return Characteristic.CurrentHeaterCoolerState.HEATING;
532
+ } else {
533
+ return Characteristic.CurrentHeaterCoolerState.IDLE;
534
+ }
535
+ }
536
+
537
+ getCurrentHeaterCoolerState(deviceInfo, callback) {
538
+ this.fetchDeviceStatus(deviceInfo, (error, status) => {
539
+ if (error) {
540
+ return callback(error);
541
+ }
542
+
543
+ const state = this._calculateHeatingState(status);
544
+ callback(null, state);
545
+ });
546
+ }
547
+
506
548
  setHeatingThresholdTemperature(deviceInfo, value, callback) {
507
549
  // Clamp value
508
550
  if (value < this.minTemp) value = this.minTemp;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "homebridge-tesy-heater-mqtt",
3
3
  "displayName": "Homebridge Tesy Heater MQTT",
4
- "version": "1.0.0",
4
+ "version": "1.0.2",
5
5
  "description": "Tesy heater plugin for Homebridge using MQTT control (API v4). Supports on/off control and temperature adjustment.",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -32,7 +32,6 @@
32
32
  "url": "git+https://github.com/svjakrm/homebridge-tesy-heater-mqtt.git"
33
33
  },
34
34
  "dependencies": {
35
- "homebridge-http-base": "2.1.6",
36
35
  "mqtt": "^5.14.1",
37
36
  "request": "^2.65.0"
38
37
  },