matterbridge-homey 0.1.0 → 0.2.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
@@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.2.0] - 2026-10-18
8
+
9
+ ### Added
10
+
11
+ - [devices]: Robotic vacuum cleaners with the standard Homey capabilities: start, stop, pause, resume and go home, the state, the clean modes and the battery.
12
+
13
+ ### Changed
14
+
15
+ - [docs]: The README explains the default color temperature range of lights and installing the plugin from npm.
16
+
17
+ ### Fixed
18
+
19
+ - [devices]: The Off mode of a thermostat or air conditioner turns `onoff` off instead of setting the `off` mode, which some drivers ignore.
20
+ - [platform]: A device that fails to build is skipped with an error instead of stopping the plugin from starting.
21
+ - [build]: Test builds of `npm run pack:tarball` are marked private, so Matterbridge reinstalls them from the uploaded tarball when the Docker container is recreated, instead of failing to find a `dev` version on npm.
22
+
7
23
  ## [0.1.0] - 2026-10-13
8
24
 
9
25
  ### Added
package/README.md CHANGED
@@ -52,6 +52,9 @@ The Matter device type follows the Homey device class (or the class you chose fo
52
52
  | `windowcoverings`, `blinds`, `curtain`, `sunshade`, `shutterblinds` | `windowcoverings_set`, `windowcoverings_state` | Window covering (lift) |
53
53
  | `lock` | `locked` | Door lock |
54
54
  | `fan`, `airpurifier` | `onoff`, `fan_speed` | Fan |
55
+ | `vacuumcleaner` | `vacuumcleaner_state` or `onoff`, `operational_state`, `vacuumcleaner_job_mode` | Robotic vacuum cleaner |
56
+
57
+ The Off mode of a thermostat or air conditioner turns `onoff` off, and the other modes turn it back on. Only devices without `onoff` get the `off` value of `thermostat_mode`, because some drivers don't switch the device off with it.
55
58
 
56
59
  Sensors are added to any device that has them:
57
60
 
@@ -67,6 +70,26 @@ Sensors are added to any device that has them:
67
70
 
68
71
  Sub-capabilities of sensors, e.g. `measure_temperature.inside`, are exposed too. The outdoor temperature of a thermostat or air conditioner (e.g. `measure_temperature.outdoorTemperature`) is part of the thermostat.
69
72
 
73
+ ### Color temperature of lights
74
+
75
+ Homey doesn't give the color temperature of a light in Kelvin or mireds. Its `light_temperature` goes from 0 (the coldest white of the light) to 1 (the warmest white), and Homey doesn't tell which Kelvin range that is for the light.
76
+
77
+ The plugin therefore maps it onto a default range of 6500 K (153 mireds) to 2000 K (500 mireds) for every light. The coldest and warmest settings of the controller are the coldest and warmest white of the light, but the Kelvin values in between are approximate: a light that only goes from 2700 K to 6500 K looks colder than the controller shows.
78
+
79
+ ### Robotic vacuum cleaners
80
+
81
+ Vacuums are supported with the standard Homey capabilities and values only:
82
+
83
+ - Start and stop (the Matter run modes Idle and Cleaning) set `vacuumcleaner_state` to `cleaning` or `stopped`, or turn `onoff` on or off.
84
+ - Go home sets `vacuumcleaner_state` to `docked`. Homey has no standard pause: pause stops the vacuum, resume starts it again.
85
+ - The state comes from `vacuumcleaner_state` (cleaning, docked, charging, stopped) and the standard values of `operational_state` (paused, error).
86
+ - The standard values of `vacuumcleaner_job_mode` (normal, high, turbo, mop, auto) are the Matter clean modes. Matter only changes them while the vacuum is idle.
87
+ - No rooms or maps: Homey has no standard capability for them.
88
+
89
+ Vacuums without `vacuumcleaner_state` or `onoff` aren't exposed. This includes Matter vacuums paired with Homey: Homey's Matter driver uses the Matter state and mode numbers instead of the standard values. Add such a vacuum to your Matter controller directly instead.
90
+
91
+ Apple Home doesn't support a vacuum in a bridge, and the whole bridge becomes unstable. If you use Apple Home, add your vacuums to the black list.
92
+
70
93
  ### How devices are composed
71
94
 
72
95
  Each Homey device is one Matter bridged device. Its main function and as many sensors as possible share one endpoint, so controllers show one device instead of one per function (Alexa shows every endpoint as a separate device). A function that can't share the endpoint gets a child endpoint: a second sensor of the same kind (e.g. `alarm_motion` and `alarm_presence`) or a sub-capability (e.g. `onoff.output2`).
@@ -92,11 +115,15 @@ The white and black lists accept Homey device IDs as well as names. Entries by n
92
115
 
93
116
  - New Homey devices need a Matterbridge restart; the frontend asks for it. Deleted devices are removed right away.
94
117
  - Devices with the same name get their zone appended, e.g. `Ceiling light Kitchen`.
95
- - Not supported yet: buttons and remotes, media players and TVs (only their `onoff`), vacuum cleaners, window covering tilt, plant moisture, `level_aqi`.
118
+ - Not supported yet: buttons and remotes, media players and TVs (only their `onoff`), window covering tilt, plant moisture, `level_aqi`.
96
119
 
97
120
  ## Install
98
121
 
99
- The plugin isn't published on npm yet. Build a tarball and upload it to Matterbridge:
122
+ On the Home page of the Matterbridge frontend, enter `matterbridge-homey` in the **Install plugins** panel and click **Install**. Then set the address and API key in the plugin configuration and restart.
123
+
124
+ ### Test builds
125
+
126
+ To test changes before they are published, build a tarball and upload it to Matterbridge:
100
127
 
101
128
  ```bash
102
129
  npm install
@@ -104,9 +131,9 @@ npm link matterbridge
104
131
  npm run pack:tarball
105
132
  ```
106
133
 
107
- This creates `matterbridge-homey-<version>-dev-<date>-<time>.tgz` in the project folder (`npm run pack:tarball -- --release` keeps the plain version). On the Home page of the Matterbridge frontend, click **Upload** in the **Install plugins** panel and choose the tarball (the panel is hidden when Matterbridge runs read-only). Matterbridge installs it with `npm install -g <tarball> --omit=dev`, so the host needs access to the npm registry for `homey-api`. Then set the address and API key in the plugin configuration and restart.
134
+ This creates `matterbridge-homey-<version>-dev-<date>-<time>.tgz` in the project folder (`npm run pack:tarball -- --release` keeps the plain version). On the Home page of the Matterbridge frontend, click **Upload** in the **Install plugins** panel and choose the tarball (the panel is hidden when Matterbridge runs read-only). Matterbridge installs it with `npm install -g <tarball> --omit=dev`, so the host needs access to the npm registry for `homey-api`.
108
135
 
109
- Uploading a newer tarball replaces the installed version.
136
+ Uploading a newer tarball replaces the installed version. Test builds are marked private in their `package.json`: when the plugin is missing at start, e.g. after Docker recreated the Matterbridge container for an image update, Matterbridge reinstalls a private plugin from the last uploaded tarball instead of from npm. Release builds are reinstalled from npm.
110
137
 
111
138
  ## Development
112
139
 
package/dist/features.js CHANGED
@@ -1,5 +1,6 @@
1
- import { airQualitySensor, colorTemperatureLight, contactSensor, dimmableLight, dimmablePlugInUnit, doorLock, electricalSensor, extendedColorLight, fan, humiditySensor, lightSensor, occupancySensor, onOffLight, onOffPlugInUnit, pressureSensor, rainSensor, smokeCoAlarm, temperatureSensor, thermostat, waterLeakDetector, windowCovering, } from 'matterbridge';
2
- import { AirQuality, BooleanState, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, ColorControl, DoorLock, ElectricalEnergyMeasurement, ElectricalPowerMeasurement, FanControl, IlluminanceMeasurement, LevelControl, OccupancySensing, OnOff, Pm10ConcentrationMeasurement, Pm25ConcentrationMeasurement, PressureMeasurement, RelativeHumidityMeasurement, SmokeCoAlarm, TemperatureMeasurement, Thermostat, TotalVolatileOrganicCompoundsConcentrationMeasurement, WindowCovering, } from 'matterbridge/matter/clusters';
1
+ import { airQualitySensor, colorTemperatureLight, contactSensor, dimmableLight, dimmablePlugInUnit, doorLock, electricalSensor, extendedColorLight, fan, humiditySensor, lightSensor, occupancySensor, onOffLight, onOffPlugInUnit, pressureSensor, rainSensor, roboticVacuumCleaner, smokeCoAlarm, temperatureSensor, thermostat, waterLeakDetector, windowCovering, } from 'matterbridge';
2
+ import { MatterbridgeRvcCleanModeServer, MatterbridgeRvcOperationalStateServer, MatterbridgeRvcRunModeServer } from 'matterbridge/devices';
3
+ import { AirQuality, BooleanState, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, ColorControl, DoorLock, ElectricalEnergyMeasurement, ElectricalPowerMeasurement, FanControl, IlluminanceMeasurement, LevelControl, OccupancySensing, OnOff, Pm10ConcentrationMeasurement, Pm25ConcentrationMeasurement, PressureMeasurement, RelativeHumidityMeasurement, RvcCleanMode, RvcOperationalState, RvcRunMode, SmokeCoAlarm, TemperatureMeasurement, Thermostat, TotalVolatileOrganicCompoundsConcentrationMeasurement, WindowCovering, } from 'matterbridge/matter/clusters';
3
4
  import { kelvinToRGB, miredToKelvin, rgbColorToHslColor, xyToHsl } from 'matterbridge/utils';
4
5
  import { colorTemperatureMaxMireds, colorTemperatureMinMireds, dimToLevel, levelToDim, lightTemperatureToMireds, liftToWindowCoveringsSet, luxToMatter, matterColorToUnit, miredsToLightTemperature, setpointToTargetTemperature, toHundredths, toThousandths, unitToMatterColor, windowCoveringsSetToLift, } from './converters.js';
5
6
  const lightClasses = new Set(['light']);
@@ -8,6 +9,7 @@ const coolingClasses = new Set(['airconditioning']);
8
9
  const coveringClasses = new Set(['windowcoverings', 'blinds', 'curtain', 'sunshade', 'shutterblinds']);
9
10
  const fanClasses = new Set(['fan', 'airpurifier']);
10
11
  const lockClasses = new Set(['lock']);
12
+ const vacuumClasses = new Set(['vacuumcleaner']);
11
13
  const outputClasses = new Set(['socket', 'other']);
12
14
  export function hasCapability(device, capabilityId) {
13
15
  return device.capabilities.includes(capabilityId);
@@ -44,6 +46,8 @@ export function planFeatures(device) {
44
46
  features.push(doorLockFeature());
45
47
  else if (fanClasses.has(deviceClass) && hasOnOff)
46
48
  features.push(fanFeature(device));
49
+ else if (vacuumClasses.has(deviceClass) && (hasOnOff || hasCapability(device, 'vacuumcleaner_state')))
50
+ features.push(vacuumFeature(device));
47
51
  else if (hasOnOff && deviceClass !== 'sensor')
48
52
  features.push(plugFeature(device, 'onoff'));
49
53
  if (!climate)
@@ -61,7 +65,7 @@ export function planFeatures(device) {
61
65
  addSensor(features, device, 'measure_luminance', illuminanceFeature);
62
66
  if (['measure_co2', 'measure_co', 'measure_pm25', 'measure_pm10', 'measure_tvoc'].some((id) => hasCapability(device, id)))
63
67
  features.push(airQualityFeature(device));
64
- let hasMainFunction = features.length > 0 && features[0].clusters.some((cluster) => ['OnOff', 'Thermostat', 'WindowCovering', 'DoorLock', 'FanControl'].includes(cluster));
68
+ let hasMainFunction = features.length > 0 && features[0].clusters.some((cluster) => ['OnOff', 'Thermostat', 'WindowCovering', 'DoorLock', 'FanControl', 'RvcRunMode'].includes(cluster));
65
69
  for (const capabilityId of device.capabilities) {
66
70
  const [base, sub] = capabilityId.split('.');
67
71
  if (sub === undefined)
@@ -319,7 +323,7 @@ function climateFeature(device, isCooling) {
319
323
  if (!isFromController(actionContext))
320
324
  return;
321
325
  const modeId = Object.keys(systemModes).find((id) => systemModes[id] === value);
322
- if (value === Thermostat.SystemMode.Off && !modeIds.has('off') && hasOnOff)
326
+ if (value === Thermostat.SystemMode.Off && hasOnOff)
323
327
  context.set('onoff', false);
324
328
  else if (modeId !== undefined && modeIds.has(modeId))
325
329
  context.set('thermostat_mode', modeId);
@@ -469,6 +473,149 @@ function doorLockFeature() {
469
473
  },
470
474
  };
471
475
  }
476
+ const vacuumIdleMode = 1;
477
+ const vacuumCleaningMode = 2;
478
+ const vacuumCleanModes = {
479
+ normal: { label: 'Normal', mode: 1, modeTags: [{ value: RvcCleanMode.ModeTag.Vacuum }] },
480
+ high: { label: 'High', mode: 2, modeTags: [{ value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.DeepClean }] },
481
+ turbo: { label: 'Turbo', mode: 3, modeTags: [{ value: RvcCleanMode.ModeTag.Vacuum }, { value: RvcCleanMode.ModeTag.Max }] },
482
+ mop: { label: 'Mop', mode: 4, modeTags: [{ value: RvcCleanMode.ModeTag.Mop }] },
483
+ auto: { label: 'Auto', mode: 5, modeTags: [{ value: RvcCleanMode.ModeTag.Auto }, { value: RvcCleanMode.ModeTag.Vacuum }] },
484
+ };
485
+ const vacuumStates = {
486
+ cleaning: RvcOperationalState.OperationalState.Running,
487
+ spot_cleaning: RvcOperationalState.OperationalState.Running,
488
+ docked: RvcOperationalState.OperationalState.Docked,
489
+ charging: RvcOperationalState.OperationalState.Charging,
490
+ stopped: RvcOperationalState.OperationalState.Stopped,
491
+ };
492
+ const vacuumOperationalStates = {
493
+ stopped: RvcOperationalState.OperationalState.Stopped,
494
+ running: RvcOperationalState.OperationalState.Running,
495
+ paused: RvcOperationalState.OperationalState.Paused,
496
+ error: RvcOperationalState.OperationalState.Error,
497
+ };
498
+ export function getVacuumCleanModes(device) {
499
+ if (!hasCapability(device, 'vacuumcleaner_job_mode'))
500
+ return [];
501
+ const values = getCapability(device, 'vacuumcleaner_job_mode')?.values?.map((value) => value.id) ?? Object.keys(vacuumCleanModes);
502
+ return values.filter((value) => Object.hasOwn(vacuumCleanModes, value));
503
+ }
504
+ function mapStandardValue(mapping, value) {
505
+ return typeof value === 'string' && Object.hasOwn(mapping, value) ? mapping[value] : undefined;
506
+ }
507
+ function vacuumFeature(device) {
508
+ const hasState = hasCapability(device, 'vacuumcleaner_state');
509
+ const cleanModeIds = getVacuumCleanModes(device);
510
+ const { OperationalState } = RvcOperationalState;
511
+ return {
512
+ name: 'vacuum',
513
+ capabilities: ['vacuumcleaner_state', 'onoff', 'operational_state', 'vacuumcleaner_job_mode'],
514
+ deviceTypes: [roboticVacuumCleaner],
515
+ clusters: ['RvcRunMode', 'RvcCleanMode', 'RvcOperationalState'],
516
+ build: (context) => {
517
+ const { endpoint } = context;
518
+ const operationalState = () => {
519
+ const operational = mapStandardValue(vacuumOperationalStates, context.value('operational_state'));
520
+ if (operational === OperationalState.Paused || operational === OperationalState.Error)
521
+ return operational;
522
+ return (mapStandardValue(vacuumStates, context.value('vacuumcleaner_state')) ??
523
+ operational ??
524
+ (context.value('onoff') === true ? OperationalState.Running : OperationalState.Stopped));
525
+ };
526
+ const operationalError = (state) => state === OperationalState.Error
527
+ ? { errorStateId: RvcOperationalState.ErrorState.UnableToCompleteOperation }
528
+ : { errorStateId: RvcOperationalState.ErrorState.NoError, errorStateDetails: 'Fully operational' };
529
+ const runMode = (state) => state === OperationalState.Running || state === OperationalState.Paused ? vacuumCleaningMode : vacuumIdleMode;
530
+ const cleanMode = () => {
531
+ const jobMode = context.value('vacuumcleaner_job_mode');
532
+ return vacuumCleanModes[typeof jobMode === 'string' && cleanModeIds.includes(jobMode) ? jobMode : cleanModeIds[0]].mode;
533
+ };
534
+ const state = operationalState();
535
+ endpoint.behaviors.require(MatterbridgeRvcRunModeServer, {
536
+ supportedModes: [
537
+ { label: 'Idle', mode: vacuumIdleMode, modeTags: [{ value: RvcRunMode.ModeTag.Idle }] },
538
+ { label: 'Cleaning', mode: vacuumCleaningMode, modeTags: [{ value: RvcRunMode.ModeTag.Cleaning }] },
539
+ ],
540
+ currentMode: runMode(state),
541
+ });
542
+ if (cleanModeIds.length > 0) {
543
+ endpoint.behaviors.require(MatterbridgeRvcCleanModeServer, { supportedModes: cleanModeIds.map((id) => vacuumCleanModes[id]), currentMode: cleanMode() });
544
+ }
545
+ endpoint.behaviors.require(MatterbridgeRvcOperationalStateServer, {
546
+ phaseList: null,
547
+ currentPhase: null,
548
+ countdownTime: null,
549
+ operationalStateList: [
550
+ OperationalState.Stopped,
551
+ OperationalState.Running,
552
+ OperationalState.Paused,
553
+ OperationalState.Error,
554
+ OperationalState.SeekingCharger,
555
+ OperationalState.Charging,
556
+ OperationalState.Docked,
557
+ ].map((operationalStateId) => ({ operationalStateId })),
558
+ operationalState: state,
559
+ operationalError: operationalError(state),
560
+ });
561
+ const start = () => {
562
+ if (hasState)
563
+ context.set('vacuumcleaner_state', 'cleaning', true);
564
+ else
565
+ context.set('onoff', true, true);
566
+ };
567
+ const stop = (vacuumState, reflect) => {
568
+ if (hasState)
569
+ context.set('vacuumcleaner_state', vacuumState, reflect);
570
+ else
571
+ context.set('onoff', false, reflect);
572
+ };
573
+ endpoint.addCommandHandler('RvcRunMode.changeToMode', ({ request, attributes }) => {
574
+ if (request.newMode === attributes.currentMode)
575
+ return;
576
+ if (request.newMode === vacuumCleaningMode)
577
+ start();
578
+ else if (request.newMode === vacuumIdleMode)
579
+ stop('stopped', true);
580
+ });
581
+ endpoint.addCommandHandler('RvcOperationalState.pause', ({ attributes }) => {
582
+ if (attributes.operationalState === OperationalState.Running || attributes.operationalState === OperationalState.SeekingCharger)
583
+ stop('stopped', false);
584
+ });
585
+ endpoint.addCommandHandler('RvcOperationalState.resume', ({ attributes }) => {
586
+ if (attributes.operationalState === OperationalState.Paused)
587
+ start();
588
+ });
589
+ endpoint.addCommandHandler('RvcOperationalState.goHome', ({ attributes }) => {
590
+ if (attributes.operationalState === OperationalState.Stopped ||
591
+ attributes.operationalState === OperationalState.Running ||
592
+ attributes.operationalState === OperationalState.Paused)
593
+ stop('docked', true);
594
+ });
595
+ if (cleanModeIds.length > 0) {
596
+ endpoint.addCommandHandler('RvcCleanMode.changeToMode', ({ request, attributes }) => {
597
+ const modeId = cleanModeIds.find((id) => vacuumCleanModes[id].mode === request.newMode);
598
+ if (modeId === undefined || request.newMode === attributes.currentMode || endpoint.getAttribute(RvcRunMode, 'currentMode') !== vacuumIdleMode)
599
+ return;
600
+ context.set('vacuumcleaner_job_mode', modeId, true);
601
+ });
602
+ }
603
+ const update = async () => {
604
+ const newState = operationalState();
605
+ await endpoint.updateAttribute(RvcOperationalState, 'operationalState', newState, endpoint.log);
606
+ await endpoint.updateAttribute(RvcOperationalState, 'operationalError', operationalError(newState), endpoint.log);
607
+ await endpoint.updateAttribute(RvcRunMode, 'currentMode', runMode(newState), endpoint.log);
608
+ };
609
+ for (const capabilityId of ['vacuumcleaner_state', 'operational_state', 'onoff'])
610
+ context.bind(capabilityId, update);
611
+ if (cleanModeIds.length > 0) {
612
+ context.bind('vacuumcleaner_job_mode', async () => {
613
+ await endpoint.updateAttribute(RvcCleanMode, 'currentMode', cleanMode(), endpoint.log);
614
+ });
615
+ }
616
+ },
617
+ };
618
+ }
472
619
  function temperatureFeature(capabilityId) {
473
620
  return {
474
621
  name: capabilityId,
package/dist/module.js CHANGED
@@ -1,5 +1,5 @@
1
- import { MatterbridgeDynamicPlatform } from 'matterbridge';
2
- import { CYAN, db, idn, nf, rs } from 'matterbridge/logger';
1
+ import { MatterbridgeDynamicPlatform, roboticVacuumCleaner } from 'matterbridge';
2
+ import { CYAN, db, idn, nf, rs, wr } from 'matterbridge/logger';
3
3
  import { fireAndForget, getErrorMessage, inspectError, isValidArray, isValidObject, isValidString } from 'matterbridge/utils';
4
4
  import { getExposedCapabilities } from './features.js';
5
5
  import { HomeyApiConnection } from './homey.js';
@@ -179,22 +179,25 @@ export class HomeyPlatform extends MatterbridgeDynamicPlatform {
179
179
  if (!this.validateDevice(keys))
180
180
  return;
181
181
  const excludedCapabilities = new Set([...this.config.capabilityBlackList, ...keys.flatMap((key) => this.config.deviceCapabilityBlackList[key] ?? [])]);
182
- const bridgedDevice = HomeyBridgedDevice.create({
183
- device: customizeDevice(remapped, undefined, excludedCapabilities),
184
- name,
185
- connection: this.homey,
186
- vendorId: this.matterbridge.aggregatorVendorId,
187
- logLevel: this.log.logLevel,
188
- configUrl,
189
- });
190
- if (!bridgedDevice) {
191
- this.log.info(`Device ${CYAN}${name}${nf} has no capabilities left after the capability black lists. Skipping...`);
192
- return;
193
- }
194
182
  try {
183
+ const bridgedDevice = HomeyBridgedDevice.create({
184
+ device: customizeDevice(remapped, undefined, excludedCapabilities),
185
+ name,
186
+ connection: this.homey,
187
+ vendorId: this.matterbridge.aggregatorVendorId,
188
+ logLevel: this.log.logLevel,
189
+ configUrl,
190
+ });
191
+ if (!bridgedDevice) {
192
+ this.log.info(`Device ${CYAN}${name}${nf} has no capabilities left after the capability black lists. Skipping...`);
193
+ return;
194
+ }
195
195
  this.log.info(`Registering device ${idn}${name}${rs}${nf} class ${CYAN}${remapped.virtualClass ?? remapped.class}${nf}...`);
196
196
  await this.registerDevice(bridgedDevice.endpoint);
197
197
  this.bridgedDevices.set(device.id, bridgedDevice);
198
+ if (bridgedDevice.endpoint.deviceTypes.has(roboticVacuumCleaner.code)) {
199
+ this.log.warn(`Device ${CYAN}${name}${wr} is a robotic vacuum cleaner: Apple Home doesn't support it in a bridge. If you use Apple Home, add it to the black list.`);
200
+ }
198
201
  }
199
202
  catch (error) {
200
203
  inspectError(this.log, `Failed to register device ${name}`, error);
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "matterbridge-homey",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge-homey",
9
- "version": "0.1.0",
9
+ "version": "0.2.0",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "homey-api": "3.20.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge-homey",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Matterbridge plugin that exposes Athom Homey Pro devices to Matter",
5
5
  "author": "Stefan Schweiger",
6
6
  "license": "Apache-2.0",