homebridge-homeassistant-garagedoor 1.0.3 → 1.0.4

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.
Files changed (2) hide show
  1. package/index.js +95 -64
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,76 +1,107 @@
1
- var Service, Characteristic;
2
- const axios = require('axios');
1
+ 'use strict';
3
2
 
4
- module.exports = function(homebridge) {
5
- Service = homebridge.hap.Service;
6
- Characteristic = homebridge.hap.Characteristic;
7
- homebridge.registerAccessory("homebridge-homeassistant-garagedoor", "HomeAssistantGarageDoor", HomeAssistantGarageDoor);
8
- };
3
+ const axios = require('axios');
9
4
 
10
- function HomeAssistantGarageDoor(log, config) {
5
+ class HomeAssistantGarageDoor {
6
+ constructor(log, config) {
11
7
  this.log = log;
12
- this.name = config.name || "Garage Door";
13
- this.haUrl = config.haUrl || "http://192.168.68.239:8123";
8
+ this.name = config.name;
9
+ this.haUrl = config.haUrl;
14
10
  this.haToken = config.haToken;
15
- this.entityId = config.entityId || "switch.Puerta1";
16
-
17
- // Estado inicial SIEMPRE CERRADO
18
- this.currentState = Characteristic.CurrentDoorState.CLOSED;
19
-
20
- this.service = new Service.GarageDoorOpener(this.name);
21
- this.informationService = new Service.AccessoryInformation();
22
-
23
- this.informationService
24
- .setCharacteristic(Characteristic.Manufacturer, "Home Assistant")
25
- .setCharacteristic(Characteristic.Model, "Garage Door")
26
- .setCharacteristic(Characteristic.SerialNumber, this.entityId);
27
-
28
- this.service.getCharacteristic(Characteristic.TargetDoorState)
29
- .on('set', this.setTargetState.bind(this));
30
-
31
- this.service.getCharacteristic(Characteristic.CurrentDoorState)
32
- .on('get', this.getCurrentState.bind(this))
33
- .setValue(this.currentState);
11
+ this.entityId = config.entityId;
12
+ this.pollInterval = config.pollInterval || 30;
13
+ this.currentState = 'CLOSED';
14
+ this.targetState = 'CLOSED';
15
+ this.polling = null;
16
+
17
+ this.log(`[${this.name}] Initializing HomeAssistantGarageDoor accessory...`);
34
18
 
35
- this.service.getCharacteristic(Characteristic.TargetDoorState)
36
- .setValue(Characteristic.CurrentDoorState.CLOSED);
19
+ this.service = new this.Service.GarageDoorOpener(this.name);
20
+ this.service.setCharacteristic(this.Characteristic.TargetDoorState, this.Characteristic.TargetDoorState.CLOSED);
37
21
 
38
- this.log("[%s] Initialized - HA: %s (%s)", this.name, this.haUrl, this.entityId);
39
- }
22
+ this.initHA();
23
+ }
40
24
 
41
- HomeAssistantGarageDoor.prototype = {
42
- getServices: function() {
43
- return [this.informationService, this.service];
44
- },
25
+ initHA() {
26
+ this.log(`[${this.name}] [${this.name}] Initialized - HA: ${this.haUrl} (${this.entityId})`);
27
+ this.startPolling();
28
+ }
45
29
 
46
- setTargetState: function(targetState, callback) {
47
- this.log("[%s] Target state: %s", this.name, targetState === 0 ? "OPEN" : "CLOSED");
48
-
49
- const service = targetState === 0 ? "switch.turn_on" : "switch.turn_off";
50
-
51
- axios.post(`${this.haUrl}/api/services/switch/${service}`,
52
- { entity_id: this.entityId },
53
- {
54
- headers: {
55
- 'Authorization': `Bearer ${this.haToken}`,
56
- 'Content-Type': 'application/json'
57
- },
58
- timeout: 10000
59
- }
60
- )
61
- .then(() => {
62
- this.log("[%s] Command sent to HA: %s", this.name, service);
63
- callback(null);
64
- })
65
- .catch(err => {
66
- this.log("[%s] HA Error: %s", this.name, err.message);
67
- callback(err);
68
- });
69
- },
30
+ async sendHACommand(state) {
31
+ // 🔧 FIX v1.0.3: Skip request si estado coincide
32
+ if (this.currentState === state) {
33
+ this.log(`[${this.name}] State matches target (${state}) Skipping HA request`);
34
+ return;
35
+ }
36
+
37
+ const service = state === 'OPEN' ? 'turn_on' : 'turn_off';
38
+ try {
39
+ const response = await axios.post(
40
+ `${this.haUrl}/api/services/switch/${service}`,
41
+ { entity_id: this.entityId },
42
+ {
43
+ headers: {
44
+ 'Authorization': `Bearer ${this.haToken}`,
45
+ 'Content-Type': 'application/json'
46
+ },
47
+ timeout: 5000
48
+ }
49
+ );
50
+ this.log(`[${this.name}] HA ${service} ${response.status}: ${JSON.stringify(response.data)}`);
51
+ } catch (error) {
52
+ this.log(`[${this.name}] HA Error: ${error.message}`);
53
+ }
54
+ }
55
+
56
+ async pollHA() {
57
+ try {
58
+ const response = await axios.get(
59
+ `${this.haUrl}/api/states/${this.entityId}`,
60
+ {
61
+ headers: { 'Authorization': `Bearer ${this.haToken}` },
62
+ timeout: 5000
63
+ }
64
+ );
65
+
66
+ const haState = response.data.state;
67
+ const doorState = haState === 'on' ? 'OPEN' : 'CLOSED';
68
+
69
+ if (this.currentState !== doorState) {
70
+ this.currentState = doorState;
71
+ this.service.setCharacteristic(this.Characteristic.CurrentDoorState,
72
+ doorState === 'OPEN' ?
73
+ this.Characteristic.CurrentDoorState.OPEN :
74
+ this.Characteristic.CurrentDoorState.CLOSED
75
+ );
76
+ this.log(`[${this.name}] Poll: ${doorState} (${haState})`);
77
+ }
78
+ } catch (error) {
79
+ this.log(`[${this.name}] Poll error: ${error.message}`);
80
+ }
81
+ }
70
82
 
71
- getCurrentState: function(callback) {
72
- // SIEMPRE devuelve CERRADO (como tu plugin anterior)
73
- callback(null, this.currentState);
83
+ startPolling() {
84
+ if (this.pollInterval > 0) {
85
+ this.polling = setInterval(() => this.pollHA(), this.pollInterval * 1000);
86
+ this.log(`[${this.name}] Polling started (${this.pollInterval}s)`);
74
87
  }
88
+ }
89
+
90
+ getServices() {
91
+ this.service.getCharacteristic(this.Characteristic.TargetDoorState)
92
+ .on('set', (value, callback) => {
93
+ const newState = value === this.Characteristic.TargetDoorState.OPEN ? 'OPEN' : 'CLOSED';
94
+ this.log(`[${this.name}] Target state: ${newState}`);
95
+ this.targetState = newState;
96
+ this.sendHACommand(newState);
97
+ callback();
98
+ });
99
+
100
+ return [this.service];
101
+ }
102
+ }
103
+
104
+ module.exports = (homebridge) => {
105
+ homebridge.registerAccessory("homebridge-homeassistant-garagedoor", "HomeAssistantGarageDoor", HomeAssistantGarageDoor);
75
106
  };
76
107
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "homebridge-homeassistant-garagedoor",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Homebridge plugin to control Home Assistant switches as Garage Doors",
5
5
  "main": "index.js",
6
6
  "scripts": {