@homebridge-plugins/homebridge-ewelink 12.11.2-beta.0 → 12.11.2-beta.1

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
@@ -2,7 +2,7 @@
2
2
 
3
3
  All notable changes to `@homebridge-plugins/homebridge-ewelink` will be documented in this file.
4
4
 
5
- ## v12.11.2 (Pending Release)
5
+ ## v12.12.0 (2026-04-09)
6
6
 
7
7
  ### Changed
8
8
 
@@ -45,10 +45,16 @@ All notable changes to `@homebridge-plugins/homebridge-ewelink` will be document
45
45
  - fix: `getHost()` unbounded recursion limit
46
46
  - fix: cap energy readings array size
47
47
  - refactor: replace per-device shutdown listeners with `destroy()`
48
- - fix: revert UIID 52 from `lightCCT`
48
+ - feat: add UIID 52 CCT light support
49
49
  - fix: simulation switches array bounds
50
50
  - fix: audit fixes from code review
51
51
  - chore: dependency updates
52
+ - feat: UIID 276 power monitoring support
53
+ - fix: suppress warnings for UIIDs 204, 223, 20000
54
+ - fix: SNZB-06P occupancy sensor `human` param
55
+ - fix: UIID 226 boolean switch format
56
+ - feat: add UIID 216 gate controller
57
+ - fix: TRVZB auto mode and target temp
52
58
 
53
59
  ## v12.11.1 (2026-04-05)
54
60
 
@@ -91,6 +91,7 @@ export default class {
91
91
  case 32:
92
92
  case 182:
93
93
  case 190:
94
+ case 276:
94
95
  // Add Eve power characteristics
95
96
  this.powerReadings = true
96
97
  if (!this.service.testCharacteristic(this.hapChar.OutletInUse)) {
@@ -94,6 +94,7 @@ export default class {
94
94
  case 32:
95
95
  case 182:
96
96
  case 190:
97
+ case 276:
97
98
  // Add Eve power characteristics
98
99
  this.powerReadings = true
99
100
  if (!this.service.testCharacteristic(this.hapChar.OutletInUse)) {
@@ -114,7 +115,7 @@ export default class {
114
115
  if (!this.service.testCharacteristic(this.eveChar.ResetTotal)) {
115
116
  this.service.addCharacteristic(this.eveChar.ResetTotal)
116
117
  }
117
- if (this.accessory.context.eweUIID === 190) {
118
+ if ([190, 276].includes(this.accessory.context.eweUIID)) {
118
119
  this.divisor = 100
119
120
  }
120
121
  break
@@ -256,6 +257,8 @@ export default class {
256
257
  if (this.accessory.context.eweUIID === 190) {
257
258
  params.operSide = 1
258
259
  }
260
+ } else if (this.accessory.context.eweUIID === 226) {
261
+ params.switch = value
259
262
  } else {
260
263
  params.switch = newValue
261
264
  }
@@ -290,12 +293,17 @@ export default class {
290
293
 
291
294
  async externalUpdate(params) {
292
295
  try {
293
- if (!this.isSCM && params.switch && params.switch !== this.cacheState) {
294
- this.cacheState = params.switch
295
- this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
296
- this.accessory.eveService.addEntry({ status: this.cacheState === 'on' ? 1 : 0 })
297
- if (params.updateSource && this.enableLogging) {
298
- this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
296
+ if (!this.isSCM && hasProperty(params, 'switch')) {
297
+ const newState = typeof params.switch === 'boolean'
298
+ ? (params.switch ? 'on' : 'off')
299
+ : params.switch
300
+ if (newState !== this.cacheState) {
301
+ this.cacheState = newState
302
+ this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
303
+ this.accessory.eveService.addEntry({ status: this.cacheState === 'on' ? 1 : 0 })
304
+ if (params.updateSource && this.enableLogging) {
305
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
306
+ }
299
307
  }
300
308
  }
301
309
  if (this.isSCM && params.switches && params.switches[0].switch !== this.cacheState) {
@@ -88,6 +88,7 @@ export default class {
88
88
  case 32:
89
89
  case 182:
90
90
  case 190:
91
+ case 276:
91
92
  // Add Eve power characteristics
92
93
  this.powerReadings = true
93
94
  if (!this.service.testCharacteristic(this.hapChar.OutletInUse)) {
@@ -103,7 +104,7 @@ export default class {
103
104
  this.service.addCharacteristic(this.eveChar.Voltage)
104
105
  }
105
106
 
106
- if (this.accessory.context.eweUIID === 190) {
107
+ if ([190, 276].includes(this.accessory.context.eweUIID)) {
107
108
  this.divisor = 100
108
109
  }
109
110
  break
@@ -184,6 +185,8 @@ export default class {
184
185
  if (this.accessory.context.eweUIID === 190) {
185
186
  params.operSide = 1
186
187
  }
188
+ } else if (this.accessory.context.eweUIID === 226) {
189
+ params.switch = value
187
190
  } else {
188
191
  params.switch = newValue
189
192
  }
@@ -222,12 +225,18 @@ export default class {
222
225
 
223
226
  async externalUpdate(params) {
224
227
  try {
225
- if (!this.isSCM && params.switch && params.switch !== this.cacheState) {
226
- this.cacheState = params.switch
227
- this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
228
- this.accessory.eveService.addEntry({ status: this.cacheState === 'on' ? 1 : 0 })
229
- if (params.updateSource && this.enableLogging) {
230
- this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
228
+ if (!this.isSCM && hasProperty(params, 'switch')) {
229
+ // Normalize boolean switch values (UIID 226 uses true/false)
230
+ const newState = typeof params.switch === 'boolean'
231
+ ? (params.switch ? 'on' : 'off')
232
+ : params.switch
233
+ if (newState !== this.cacheState) {
234
+ this.cacheState = newState
235
+ this.service.updateCharacteristic(this.hapChar.On, this.cacheState === 'on')
236
+ this.accessory.eveService.addEntry({ status: this.cacheState === 'on' ? 1 : 0 })
237
+ if (params.updateSource && this.enableLogging) {
238
+ this.log('[%s] %s [%s].', this.name, this.lang.curState, this.cacheState)
239
+ }
231
240
  }
232
241
  }
233
242
  if (this.isSCM && params.switches && params.switches[0].switch !== this.cacheState) {
@@ -85,13 +85,13 @@ export default class {
85
85
  if (
86
86
  hasProperty(params, 'human')
87
87
  && hasProperty(params, 'trigTime')
88
- && params.occupancy !== this.cacheState
88
+ && params.human !== this.cacheState
89
89
  ) {
90
- this.cacheState = params.occupancy
90
+ this.cacheState = params.human
91
91
  const timeDiff = (Date.now() - params.trigTime) / 1000
92
92
  const occupancyDetected = !!(
93
93
  params.updateSource
94
- && params.occupancy === 1
94
+ && params.human === 1
95
95
  && timeDiff < this.sensorTimeDifference
96
96
  )
97
97
  this.service.updateCharacteristic(this.hapChar.OccupancyDetected, occupancyDetected)
@@ -201,9 +201,13 @@ export default class {
201
201
 
202
202
  async internalTargetUpdate(value) {
203
203
  try {
204
- const params = {
205
- workMode: '0',
206
- curTargetTemp: value * 10,
204
+ const params = {}
205
+ if (this.cacheMode === 'auto') {
206
+ params.workMode = '2'
207
+ params.autoTargetTemp = value * 10
208
+ } else {
209
+ params.workMode = '0'
210
+ params.manTargetTemp = value * 10
207
211
  }
208
212
  await this.platform.sendDeviceUpdate(this.accessory, params)
209
213
  this.cacheTarg = value
@@ -262,10 +266,12 @@ export default class {
262
266
  }
263
267
  }
264
268
 
265
- if (hasProperty(params, 'curTargetTemp')) {
266
- const curTargetTemp = Number(params.curTargetTemp) / 10
267
- if (this.cacheTarg !== curTargetTemp) {
268
- this.cacheTarg = curTargetTemp
269
+ // Handle target temp from curTargetTemp, manTargetTemp, or autoTargetTemp
270
+ const rawTarget = params.curTargetTemp ?? params.manTargetTemp ?? params.autoTargetTemp
271
+ if (rawTarget !== undefined) {
272
+ const targetTemp = Number(rawTarget) / 10
273
+ if (this.cacheTarg !== targetTemp) {
274
+ this.cacheTarg = targetTemp
269
275
  this.service.updateCharacteristic(this.hapChar.TargetTemperature, this.cacheTarg)
270
276
  if (params.updateSource && this.enableLogging) {
271
277
  this.log('[%s] %s [%s°C].', this.name, this.lang.curTarg, this.cacheTarg)
@@ -289,7 +289,7 @@ export default {
289
289
  275,
290
290
  277,
291
291
  ],
292
- switchSingle: [1, 6, 14, 24, 27, 225, 226, 268, 1009, 1256, 7004, 7005, 7010, 7032, 20001],
292
+ switchSingle: [1, 6, 14, 24, 27, 216, 225, 226, 268, 1009, 1256, 7004, 7005, 7010, 7032, 20001],
293
293
  switchSCM: [77, 78, 81, 107, 112, 138, 160, 191, 209, 264],
294
294
  switchSCMPower: [182, 190, 276],
295
295
  switchSinglePower: [5, 32],
@@ -330,7 +330,7 @@ export default {
330
330
  switchMan: [174],
331
331
  lightDimmer: [36, 44, 57, 277],
332
332
  lightRGB: [22],
333
- lightCCT: [103],
333
+ lightCCT: [52, 103],
334
334
  lightRGBCCT: [33, 59, 104, 135, 136, 137, 173],
335
335
  curtain: [11, 67, 91, 258],
336
336
  sensorContact: [102, 154],
@@ -362,7 +362,7 @@ export default {
362
362
  zbWaterValve: [7027],
363
363
  group: [5000],
364
364
  template: [130], // SPM sub unit
365
- cannotSupport: [0, 65, 118, 119, 120, 121],
365
+ cannotSupport: [0, 65, 118, 119, 120, 121, 204, 223, 20000],
366
366
  garageSensors: [102, 154, 3026],
367
367
  skipUpdateRequest: [1000],
368
368
  },
@@ -392,7 +392,9 @@ export default {
392
392
  'currentTemperature',
393
393
  'current_',
394
394
  'currLocation',
395
+ 'autoTargetTemp',
395
396
  'curTargetTemp',
397
+ 'manTargetTemp',
396
398
  'fan',
397
399
  'hue',
398
400
  'human',
@@ -473,7 +475,7 @@ export default {
473
475
  36: 1, // "SINGLE_CHANNEL_DIMMER_SWITCH" (KING-M4)
474
476
  41: 4, // "CUN_YOU_DOOR"
475
477
  44: 1, // "SNOFF_LIGHT" (D1)
476
- // 52 removed - uses channel0/channel1 params, not white.br/ct (needs own handler)
478
+ 52: 1, // "DOUBLE_COLOR_DEMO_LIGHT" (CCT bulb, e.g. Cygnett WiFi LED)
477
479
  57: 1, // "MONOCHROMATIC_BALL_LIGHT" (mosquito killer)
478
480
  59: 1, // "MUSIC_LIGHT_BELT" (L1)
479
481
  66: 1, // "ZIGBEE_MAIN_DEVICE"
@@ -524,6 +526,7 @@ export default {
524
526
  210: 2, // Sonoff Ultimate Switch T5-2C-86
525
527
  211: 3, // Sonoff Ultimate Switch T5-3C-86
526
528
  212: 4, // Sonoff Ultimate Switch T5-4C-86
529
+ 216: 1, // Electric gate controller (use showAs 'garage' or 'gate' for door behavior)
527
530
  225: 1, // CK-BL602-PCSW-01 (Single switch with power monitoring)
528
531
  228: 1, // NSPanel Pro 120
529
532
  226: 1, // https://github.com/homebridge-plugins/homebridge-ewelink/issues/636
@@ -581,6 +584,9 @@ export default {
581
584
  120: 0, // "2.4G-3C" (eWeLink 2.4G Remote)
582
585
  121: 0, // "2.4G-6C" (eWeLink 2.4G Remote)
583
586
  147: 0, // NSPanel linked device (bulb) but no controls available
587
+ 204: 0, // Sonoff iHost hub (no controllable services)
588
+ 223: 0, // eWeLink CAST Tablet (display only)
589
+ 20000: 0, // iHost gateway parent (sub-devices handled separately)
584
590
  },
585
591
 
586
592
  yetToSupportDevices: {
@@ -600,7 +606,6 @@ export default {
600
606
  46: 0, // "AIR_CLEANER"
601
607
  49: 0, // "MACHINE_BED"
602
608
  51: 0, // "COLD_WARM_DESK_LIGHT"
603
- 52: 0, // "DOUBLE_COLOR_DEMO_LIGHT" (uses channel0/channel1 format)
604
609
  53: 0, // "ELECTRIC_FAN_WITH_LAMP"
605
610
  55: 0, // "SWEEPING_ROBOT"
606
611
  56: 0, // "RGB_BALL_LIGHT_4"
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "displayName": "Homebridge eWeLink",
4
4
  "alias": "eWeLink",
5
5
  "type": "module",
6
- "version": "12.11.2-beta.0",
6
+ "version": "12.11.2-beta.1",
7
7
  "description": "Homebridge plugin to integrate eWeLink devices into HomeKit.",
8
8
  "author": {
9
9
  "name": "bwp91",
@@ -62,13 +62,13 @@
62
62
  },
63
63
  "dependencies": {
64
64
  "@homebridge/plugin-ui-utils": "^2.2.3",
65
- "axios": "^1.14.0",
65
+ "axios": "^1.15.0",
66
66
  "node-persist": "^4.0.4",
67
67
  "p-queue": "^9.1.2",
68
68
  "websocket-as-promised": "^3.0.1",
69
69
  "ws": "^8.20.0"
70
70
  },
71
71
  "devDependencies": {
72
- "@antfu/eslint-config": "^8.0.0"
72
+ "@antfu/eslint-config": "^8.1.0"
73
73
  }
74
74
  }