homebridge-tuya-without-developer-account 1.0.12 → 1.0.13

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
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.13
4
+
5
+ - Changed Smart Pet Feeder presentation to use a refined HomeKit `Valve` service as the main **Feed Now** control.
6
+ - `Active` triggers the configured `manual_feed` amount when available, falling back to `quick_feed` when needed.
7
+ - `InUse` reflects `feed_state` so HomeKit can show when the feeder is currently feeding.
8
+ - Kept the dedicated Quick Feed switch, optional Slow Feed switch, Battery service, and Feeding occupancy/status sensor.
9
+ - Removes the old cached Manual Feed switch from feeder accessories when reconfigured, since the Valve now handles manual feeding.
10
+
3
11
  ## 1.0.12
4
12
 
5
13
  - Stopped exposing `switch_inching` as a HomeKit switch because it is an internal Tuya inching/timer configuration DP, not a user-facing relay.
package/README.md CHANGED
@@ -351,6 +351,6 @@ Version **1.0.5** adds support for DP10-style Tuya dimmer plugs that expose `swi
351
351
 
352
352
  ## Version 1.0.7 device support
353
353
 
354
- This release adds native support for Tuya Smart Pet Feeders and Tuya alarm panels that expose `master_mode`. Pet feeders expose quick/manual feed controls, optional slow-feed control, feed-state sensor, and battery when available. Alarm panels are exposed as HomeKit Security System accessories, with optional extra switches controlled through `deviceOverrides[].alarm`.
354
+ This release adds native support for Tuya Smart Pet Feeders and Tuya alarm panels that expose `master_mode`. Pet feeders expose a refined HomeKit Valve-style **Feed Now** control, Quick Feed switch, optional Slow Feed switch, feed-state sensor, and battery when available. Alarm panels are exposed as HomeKit Security System accessories, with optional extra switches controlled through `deviceOverrides[].alarm`.
355
355
 
356
356
  Aroma diffuser devices whose Tuya QR cloud schema is empty remain visible as unsupported direct devices, but any diffuser scenes returned by Tuya are still exposed separately.
@@ -222,6 +222,8 @@ They are exposed to HomeKit as a Lightbulb with On and Brightness. After upgradi
222
222
 
223
223
  Supported when Tuya exposes one or more of: `quick_feed`, `manual_feed`, `slow_feed`, `feed_state`, `battery_percentage`, `charge_state`.
224
224
 
225
+ From v1.0.13 the feeder uses a refined HomeKit `Valve` service as the main **Feed Now** control. Activating it sends the configured `manual_feed` amount when available, or falls back to `quick_feed`. `InUse` reflects `feed_state`. The plugin also keeps the Quick Feed switch, optional Slow Feed switch, Feeding occupancy/status sensor, and Battery service.
226
+
225
227
  ### Alarm / Security System
226
228
 
227
229
  Supported when Tuya exposes `master_mode`. Alarm-triggered state is detected from `master_state=alarm`, `sos_state=true`, or `master_mode=sos` when available. Optional extra switches can be enabled through `deviceOverrides[].alarm`.
@@ -135,12 +135,12 @@
135
135
  "petFeeder": {
136
136
  "type": "object",
137
137
  "title": "Smart Pet Feeder Options",
138
- "description": "Optional settings for Tuya pet feeders. The plugin exposes quick/manual feed switches, feed-state sensor, and battery when supported.",
138
+ "description": "Optional settings for Tuya pet feeders. The plugin exposes a refined HomeKit Valve-style Feed Now control, Quick Feed switch, optional Slow Feed switch, feeding-state sensor, and battery when supported.",
139
139
  "properties": {
140
140
  "manualFeedAmount": {
141
141
  "type": "integer",
142
142
  "title": "Manual feed amount",
143
- "description": "Portions sent when the Manual Feed switch is turned on.",
143
+ "description": "Portions sent when the Valve-style Feed Now control is activated.",
144
144
  "minimum": 1,
145
145
  "maximum": 12,
146
146
  "default": 1
@@ -27,10 +27,92 @@ class PetFeederAccessory extends BaseAccessory_1.default {
27
27
  };
28
28
  }
29
29
  configureServices() {
30
+ this.configureFeedNowValve();
30
31
  this.configureQuickFeed();
31
- this.configureManualFeed();
32
32
  this.configureSlowFeed();
33
33
  this.configureFeedState();
34
+ this.removeLegacyManualFeedSwitch();
35
+ }
36
+ isFeeding() {
37
+ const schema = this.getSchema(...SCHEMA_CODE.FEED_STATE);
38
+ if (!schema) {
39
+ return false;
40
+ }
41
+ const status = this.getStatus(schema.code);
42
+ if (!status) {
43
+ return false;
44
+ }
45
+ const value = status.value;
46
+ if (typeof value === 'boolean') {
47
+ return value;
48
+ }
49
+ if (typeof value === 'number') {
50
+ return value > 0;
51
+ }
52
+ const text = String(value ?? '').trim().toLowerCase();
53
+ if (!text) {
54
+ return false;
55
+ }
56
+ return !['0', 'false', 'idle', 'standby', 'normal', 'done', 'finish', 'finished', 'complete', 'completed', 'none', 'ready'].includes(text);
57
+ }
58
+ getFeedNowCommand() {
59
+ const manualSchema = this.getSchema(...SCHEMA_CODE.MANUAL_FEED);
60
+ if (manualSchema) {
61
+ const { manualFeedAmount } = this.getPetFeederConfig();
62
+ return [{ code: manualSchema.code, value: manualFeedAmount }];
63
+ }
64
+ const quickSchema = this.getSchema(...SCHEMA_CODE.QUICK_FEED);
65
+ if (quickSchema) {
66
+ return [{ code: quickSchema.code, value: true }];
67
+ }
68
+ return undefined;
69
+ }
70
+ configureFeedNowValve() {
71
+ const commands = this.getFeedNowCommand();
72
+ if (!commands) {
73
+ return;
74
+ }
75
+ const name = `${this.device?.name || 'Pet Feeder'} Feed Now`;
76
+ const service = this.accessory.getServiceById(this.Service.Valve, 'feed_now')
77
+ || this.accessory.addService(this.Service.Valve, name, 'feed_now');
78
+ (0, Name_1.configureName)(this, service, name);
79
+ const valveType = this.Characteristic.ValveType.GENERIC_VALVE ?? this.Characteristic.ValveType.IRRIGATION;
80
+ service.setCharacteristic(this.Characteristic.ValveType, valveType);
81
+ const { ACTIVE, INACTIVE } = this.Characteristic.Active;
82
+ const { IN_USE, NOT_IN_USE } = this.Characteristic.InUse;
83
+ service.getCharacteristic(this.Characteristic.Active)
84
+ .onGet(() => {
85
+ this.checkOnlineStatus();
86
+ return this.isFeeding() ? ACTIVE : INACTIVE;
87
+ })
88
+ .onSet(async (value) => {
89
+ this.checkOnlineStatus();
90
+ if (value === ACTIVE) {
91
+ await this.sendCommands(commands, true);
92
+ service.getCharacteristic(this.Characteristic.Active).updateValue(ACTIVE);
93
+ service.getCharacteristic(this.Characteristic.InUse).updateValue(IN_USE);
94
+ setTimeout(() => {
95
+ if (!this.isFeeding()) {
96
+ service.getCharacteristic(this.Characteristic.Active).updateValue(INACTIVE);
97
+ service.getCharacteristic(this.Characteristic.InUse).updateValue(NOT_IN_USE);
98
+ }
99
+ }, 2500);
100
+ }
101
+ else {
102
+ // Tuya pet feeders usually expose manual_feed/quick_feed as momentary actions,
103
+ // not cancellable feed sessions. Show HomeKit as inactive but do not send a
104
+ // fake cancel command that the device does not support.
105
+ service.getCharacteristic(this.Characteristic.Active).updateValue(INACTIVE);
106
+ if (!this.isFeeding()) {
107
+ service.getCharacteristic(this.Characteristic.InUse).updateValue(NOT_IN_USE);
108
+ }
109
+ }
110
+ });
111
+ service.getCharacteristic(this.Characteristic.InUse)
112
+ .onGet(() => {
113
+ this.checkOnlineStatus();
114
+ return this.isFeeding() ? IN_USE : NOT_IN_USE;
115
+ });
34
116
  }
35
117
  configureActionSwitch(schema, name, subtype, onSet) {
36
118
  if (!schema) {
@@ -42,7 +124,7 @@ class PetFeederAccessory extends BaseAccessory_1.default {
42
124
  service.getCharacteristic(this.Characteristic.On)
43
125
  .onGet(() => {
44
126
  this.checkOnlineStatus();
45
- // quick_feed/manual_feed are momentary actions. Always display them as off.
127
+ // quick_feed is a momentary action. Always display it as off.
46
128
  return false;
47
129
  })
48
130
  .onSet(async (value) => {
@@ -74,13 +156,6 @@ class PetFeederAccessory extends BaseAccessory_1.default {
74
156
  await this.sendCommands([{ code: schema.code, value: true }], true);
75
157
  });
76
158
  }
77
- configureManualFeed() {
78
- const schema = this.getSchema(...SCHEMA_CODE.MANUAL_FEED);
79
- const { manualFeedAmount } = this.getPetFeederConfig();
80
- this.configureActionSwitch(schema, `${this.device?.name || 'Pet Feeder'} Manual Feed`, 'manual_feed', async () => {
81
- await this.sendCommands([{ code: schema.code, value: manualFeedAmount }], true);
82
- });
83
- }
84
159
  configureSlowFeed() {
85
160
  const schema = this.getSchema(...SCHEMA_CODE.SLOW_FEED);
86
161
  const { exposeSlowFeed } = this.getPetFeederConfig();
@@ -101,10 +176,16 @@ class PetFeederAccessory extends BaseAccessory_1.default {
101
176
  service.getCharacteristic(this.Characteristic.OccupancyDetected)
102
177
  .onGet(() => {
103
178
  this.checkOnlineStatus();
104
- const value = this.getStatus(schema.code)?.value;
105
- return value === 'feeding' ? OCCUPANCY_DETECTED : OCCUPANCY_NOT_DETECTED;
179
+ return this.isFeeding() ? OCCUPANCY_DETECTED : OCCUPANCY_NOT_DETECTED;
106
180
  });
107
181
  }
182
+ removeLegacyManualFeedSwitch() {
183
+ const service = this.accessory.getServiceById(this.Service.Switch, 'manual_feed');
184
+ if (service) {
185
+ this.log.warn(`Removing old pet feeder Manual Feed switch from cache: ${service.displayName}`);
186
+ this.accessory.removeService(service);
187
+ }
188
+ }
108
189
  }
109
190
  exports.default = PetFeederAccessory;
110
191
  //# sourceMappingURL=PetFeederAccessory.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "homebridge-tuya-without-developer-account",
3
3
  "displayName": "Tuya without developer account for Homebridge",
4
- "version": "1.0.12",
4
+ "version": "1.0.13",
5
5
  "description": "Homebridge plugin for Tuya and Smart Life devices using QR cloud authentication without a Tuya IoT developer account.",
6
6
  "license": "MIT",
7
7
  "author": "Kosztyk",