@homebridge-plugins/homebridge-ewelink 12.19.1-beta.1 → 12.19.1-beta.3

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
@@ -8,7 +8,12 @@ All notable changes to `@homebridge-plugins/homebridge-ewelink` will be document
8
8
 
9
9
  - feat(fan): add an option to show ifan speed as a percentage, so siri's levels work (#551)
10
10
  - fix(api): send fan speeds on the fan's own scale, so medium no longer turns it off
11
- - ci: update github actions to their latest versions
11
+ - ci: update github actions to their latest versions (#809)
12
+ - fix: keep the decimals of a power reading, so 5.5w is no longer shown as 6w
13
+ - fix(zigbee): stop curtain motors showing no response while they are online (#810)
14
+ - fix(zigbee): read the curtain motor's position, so home stops showing it opening (#810)
15
+ - fix(zigbee): keep a curtain motor shown as a garage door in step with its door
16
+ - fix(zigbee): flip the zbu-curt-7006 position, which counts 0 as open (#810)
12
17
 
13
18
  ## v12.19.0 (2026-10-18)
14
19
 
@@ -22,6 +22,10 @@ export default class {
22
22
  : platformConsts.defaultValues.lowBattThreshold
23
23
  const showAsMotor = deviceConf.showAsMotor || platformConsts.defaultValues.showAsMotor
24
24
 
25
+ // The ZBU-CURT-7006 counts the way Zigbee does, 0 = open and 100 = closed,
26
+ // which is the reverse of HomeKit (#810)
27
+ this.invertPosition = accessory.context.eweUIID === 7006
28
+
25
29
  // Set the correct logging variables for this accessory
26
30
  switch (deviceConf.overrideLogging) {
27
31
  case 'standard':
@@ -165,7 +169,7 @@ export default class {
165
169
  if (updateKey !== this.updateKey) {
166
170
  return
167
171
  }
168
- const params = { openPercent: value }
172
+ const params = { openPercent: this.convertPosition(value) }
169
173
  await this.platform.sendDeviceUpdate(this.accessory, params)
170
174
  this.cacheTarg = value
171
175
  if (this.enableLogging) {
@@ -186,7 +190,7 @@ export default class {
186
190
  // 0 for open, 1 for closed
187
191
  // this.cachePos is 0 for closed and >0 for open
188
192
 
189
- const params = { openPercent: value === 1 ? 0 : 100 }
193
+ const params = { openPercent: this.convertPosition(value === 1 ? 0 : 100) }
190
194
  await this.platform.sendDeviceUpdate(this.accessory, params)
191
195
  this.cacheTarg = value === 1 ? 0 : 100
192
196
  if (this.enableLogging) {
@@ -202,6 +206,15 @@ export default class {
202
206
  }
203
207
  }
204
208
 
209
+ convertPosition(value) {
210
+ // The same flip works both ways, to the device and back from it
211
+ return this.invertPosition ? 100 - value : value
212
+ }
213
+
214
+ markStatus(isOnline) {
215
+ this.isOnline = isOnline
216
+ }
217
+
205
218
  async externalUpdate(params) {
206
219
  try {
207
220
  if (hasProperty(params, 'battery') && params.battery !== this.cacheBatt) {
@@ -217,10 +230,11 @@ export default class {
217
230
  }
218
231
  }
219
232
 
220
- // currLocation is the current position of the motor
221
- if (hasProperty(params, 'curPercen')) {
222
- if (params.curPercen !== this.cachePos) {
223
- this.cachePos = params.curPercen
233
+ // curPercent is the current position of the motor
234
+ if (hasProperty(params, 'curPercent')) {
235
+ const newPos = this.convertPosition(params.curPercent)
236
+ if (newPos !== this.cachePos) {
237
+ this.cachePos = newPos
224
238
  if (!this.isGarage) {
225
239
  this.service.updateCharacteristic(this.hapChar.CurrentPosition, this.cachePos)
226
240
  }
@@ -232,8 +246,9 @@ export default class {
232
246
 
233
247
  // location is the target position of the motor
234
248
  if (hasProperty(params, 'openPercent')) {
235
- if (params.openPercent !== this.cacheTarg) {
236
- this.cacheTarg = params.openPercent
249
+ const newTarg = this.convertPosition(params.openPercent)
250
+ if (newTarg !== this.cacheTarg) {
251
+ this.cacheTarg = newTarg
237
252
  if (!this.isGarage) {
238
253
  this.service.updateCharacteristic(this.hapChar.TargetPosition, this.cacheTarg)
239
254
  }
@@ -246,7 +261,7 @@ export default class {
246
261
  // Get the target door state characteristic for use later
247
262
  let targetChar
248
263
  if (this.isGarage) {
249
- targetChar = this.service.getCharacteristic(this.TargetDoorState)
264
+ targetChar = this.service.getCharacteristic(this.hapChar.TargetDoorState)
250
265
  }
251
266
 
252
267
  // If the two are equal then the motor must have stopped at this position
package/lib/platform.js CHANGED
@@ -14,7 +14,7 @@ import deviceTypes from './device/index.js'
14
14
  import eveService from './fakegato/fakegato-history.js'
15
15
  import platformConsts from './utils/constants.js'
16
16
  import platformChars from './utils/custom-chars.js'
17
- import eveChars from './utils/eve-chars.js'
17
+ import eveChars, { currentConsumptionUUID } from './utils/eve-chars.js'
18
18
  import { parseDeviceId, parseError } from './utils/functions.js'
19
19
  import platformLang from './utils/lang.js'
20
20
 
@@ -2071,6 +2071,22 @@ export default class {
2071
2071
  )
2072
2072
  }
2073
2073
 
2074
+ // A cached accessory comes back with the characteristic props it was saved
2075
+ // with, so a power reading made before it became decimal would stay whole
2076
+ // watts and keep rounding. Every restored accessory passes through here
2077
+ // before any device handler runs, so this one place covers all of them.
2078
+ // eveChar is not created until launch, hence the uuid on its own.
2079
+ if (this.api) {
2080
+ accessory.services.forEach((service) => {
2081
+ service.characteristics
2082
+ .filter(characteristic => characteristic.UUID === currentConsumptionUUID)
2083
+ .forEach(characteristic => characteristic.setProps({
2084
+ format: this.api.hap.Formats.FLOAT,
2085
+ minStep: 0.01,
2086
+ }))
2087
+ })
2088
+ }
2089
+
2074
2090
  // Add the configured accessory to our global map
2075
2091
  devicesInHB.set(accessory.UUID, accessory)
2076
2092
  }
@@ -1,7 +1,11 @@
1
+ // Exported on its own because the platform needs it for cached accessories,
2
+ // which Homebridge restores before the characteristics below are created
3
+ export const currentConsumptionUUID = 'E863F10D-079E-48FF-8F27-9C2605A29F52'
4
+
1
5
  export default class {
2
6
  constructor(api) {
3
7
  this.uuids = {
4
- currentConsumption: 'E863F10D-079E-48FF-8F27-9C2605A29F52',
8
+ currentConsumption: currentConsumptionUUID,
5
9
  totalConsumption: 'E863F10C-079E-48FF-8F27-9C2605A29F52',
6
10
  voltage: 'E863F10A-079E-48FF-8F27-9C2605A29F52',
7
11
  electricCurrent: 'E863F126-079E-48FF-8F27-9C2605A29F52',
@@ -17,12 +21,13 @@ export default class {
17
21
  this.CurrentConsumption = class extends api.hap.Characteristic {
18
22
  constructor() {
19
23
  super('Current Consumption', uuids.currentConsumption)
24
+ // decimal, like Eve's own plugs: whole watts read 5.5W as 6W
20
25
  this.setProps({
21
- format: api.hap.Formats.UINT16,
26
+ format: api.hap.Formats.FLOAT,
22
27
  unit: 'W',
23
28
  maxValue: 100000,
24
29
  minValue: 0,
25
- minStep: 1,
30
+ minStep: 0.01,
26
31
  perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
27
32
  })
28
33
  this.value = this.getDefaultValue()
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "displayName": "Homebridge eWeLink",
4
4
  "alias": "eWeLink",
5
5
  "type": "module",
6
- "version": "12.19.1-beta.1",
6
+ "version": "12.19.1-beta.3",
7
7
  "description": "Homebridge plugin to integrate eWeLink devices into HomeKit.",
8
8
  "author": {
9
9
  "name": "bwp91",