@homebridge-plugins/homebridge-meross 10.19.2-beta.0 → 10.19.3-beta.0

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,15 @@
2
2
 
3
3
  All notable changes to `@homebridge-plugins/homebridge-meross` will be documented in this file.
4
4
 
5
- ## v10.19.2 (Pending Release)
5
+ ## v10.19.3 (Pending Release)
6
+
7
+ ### Changed
8
+
9
+ - feat: recognise the MA151 smoke alarm that pairs with the MSH450 hub (#803)
10
+ - fix: give the MS130 and MS130H a handler, so they stop appearing as an empty accessory (#803)
11
+ - fix: read a hub sensor's temperature and humidity whatever the model names them (#803)
12
+
13
+ ## v10.19.2 (2026-08-11)
6
14
 
7
15
  ### Changed
8
16
 
@@ -6,6 +6,25 @@ import platformConsts from '../utils/constants.js'
6
6
  import { hasProperty, parseError } from '../utils/functions.js'
7
7
  import platformLang from '../utils/lang-en.js'
8
8
 
9
+ /**
10
+ * Find the nested object in a hub sub-device entry that carries its sensor
11
+ * readings.
12
+ *
13
+ * Meross names that object after the model — `ms100` on an MS100, `ms130` on an
14
+ * MS130 — so keying on one name means every new sensor silently reports
15
+ * nothing. Match on the fields instead, which covers the models that exist and
16
+ * the ones that do not yet.
17
+ *
18
+ * @param {object} subdevice a `digest.hub.subdevice` entry
19
+ * @returns {object|undefined} the readings object, if there is one
20
+ */
21
+ export function readingsFrom(subdevice) {
22
+ return Object.values(subdevice || {}).find(value => value
23
+ && typeof value === 'object'
24
+ && !Array.isArray(value)
25
+ && (hasProperty(value, 'latestTemperature') || hasProperty(value, 'latestHumidity')))
26
+ }
27
+
9
28
  export default class {
10
29
  constructor(platform, accessory) {
11
30
  // Set up variables from the platform
@@ -139,6 +158,23 @@ export default class {
139
158
  } else if (subdevice.waterLeak) {
140
159
  // Apply the update to the accessory
141
160
  subAcc.control.applyUpdate(subdevice)
161
+ } else if (readingsFrom(subdevice)) {
162
+ // Newer sensors wrap their readings in an object named after the
163
+ // model (an MS130 reports under `ms130`, not `ms100`), so match
164
+ // on the fields rather than adding a branch per model — that is
165
+ // what left the MS130 with an accessory but no data.
166
+ const readings = readingsFrom(subdevice)
167
+ const update = {}
168
+ if (hasProperty(readings, 'latestTemperature')) {
169
+ update.temperature = readings.latestTemperature
170
+ }
171
+ if (hasProperty(readings, 'latestHumidity')) {
172
+ update.humidity = readings.latestHumidity
173
+ }
174
+ if (hasProperty(readings, 'voltage')) {
175
+ update.voltage = readings.voltage
176
+ }
177
+ subAcc.control.applyUpdate(update)
142
178
  } else if (subdevice.status === 2) {
143
179
  // If the status is 2 then has been reported offline - report a battery of 0
144
180
  subAcc.control.applyUpdate({ voltage: 0 })
package/lib/platform.js CHANGED
@@ -964,11 +964,25 @@ export default class {
964
964
 
965
965
  // Create the device type instance for this accessory
966
966
  switch (subdeviceObj.model) {
967
+ // MA151 pairs with the MSH450 hub. It is grouped with the GS559A
968
+ // because both are smoke alarms, but note what that currently
969
+ // buys: this handler exposes a battery only. Which field an MA151
970
+ // uses to report an alarm is not known yet (#803), so it appears
971
+ // in HomeKit and reports battery, and the smoke state still has
972
+ // to be mapped once a real payload has been seen.
967
973
  case 'GS559A':
974
+ case 'MA151':
968
975
  subAcc.control = new deviceTypes.deviceHubSmoke(this, subAcc)
969
976
  break
977
+ // MS130/MS130H are temperature + humidity sensors like the MS100,
978
+ // so they share its handler. They were already declared supported
979
+ // but had no case here, which meant the accessory was added and
980
+ // then silently dropped by `default` below - leaving an empty
981
+ // accessory and no explanation.
970
982
  case 'MS100':
971
983
  case 'MS100F':
984
+ case 'MS130':
985
+ case 'MS130H':
972
986
  subAcc.control = new deviceTypes.deviceHubSensor(this, subAcc)
973
987
  break
974
988
  case 'MS200':
@@ -988,6 +1002,16 @@ export default class {
988
1002
  subAcc.control = new deviceTypes.deviceHubValve(this, subAcc, accessory)
989
1003
  break
990
1004
  default:
1005
+ // Reached when a model is listed as supported but has no case
1006
+ // above. The accessory has already been added at this point, so
1007
+ // returning quietly leaves an empty one behind with nothing to
1008
+ // explain it — which is exactly how the MS130 gap went unnoticed.
1009
+ this.log.warn(
1010
+ '[%s] %s:\n%s',
1011
+ subdeviceObj.devName,
1012
+ platformLang.notSupp,
1013
+ JSON.stringify(subdeviceObj),
1014
+ )
991
1015
  return
992
1016
  }
993
1017
 
@@ -321,7 +321,7 @@ export default {
321
321
  thermostatMts215: ['MTS215', 'MTS215B'],
322
322
  sensorPresence: ['MS600'],
323
323
  hubMain: ['MSH300', 'MSH300HK', 'MSH400', 'MSH450'],
324
- hubSub: ['GS559A', 'MS100', 'MS100F', 'MS130', 'MS130H', 'MS200', 'MS400', 'MST100', 'MST200', 'MTS100', 'MTS100V3', 'MTS150', 'MTS150P'],
324
+ hubSub: ['GS559A', 'MA151', 'MS100', 'MS100F', 'MS130', 'MS130H', 'MS200', 'MS400', 'MST100', 'MST200', 'MTS100', 'MTS100V3', 'MTS150', 'MTS150P'],
325
325
  template: [],
326
326
  },
327
327
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@homebridge-plugins/homebridge-meross",
3
3
  "alias": "Meross",
4
4
  "type": "module",
5
- "version": "10.19.2-beta.0",
5
+ "version": "10.19.3-beta.0",
6
6
  "description": "Homebridge plugin to integrate Meross devices into HomeKit.",
7
7
  "author": {
8
8
  "name": "bwp91",