homebridge-multiple-switch 1.0.0 → 1.1.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/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # Homebridge Multiple Switch Plugin
2
+
3
+ ## Overview
4
+ The **Homebridge Multiple Switch** plugin allows you to create and manage multiple virtual switches within the HomeKit environment. This plugin is ideal for users who want to control multiple devices or scenarios using a single accessory with multiple switch options.
5
+
6
+ ## Features
7
+ - **Multiple Switches**: Add, manage, and control multiple virtual switches under one accessory in HomeKit.
8
+ - **Master Switch**: Optionally add a master switch that controls all other switches simultaneously.
9
+ - **Customizable**: Easily configure the number of switches and their names through the Homebridge UI.
10
+ - **Flexible**: Supports dynamic addition of switches, allowing for easy scaling to your needs.
11
+
12
+ ## Installation
13
+ 1. Ensure you have [Homebridge](https://homebridge.io) installed and running.
14
+ 2. Install the plugin via Homebridge or npm:
15
+ ```bash
16
+ npm install -g homebridge-multiple-switch
17
+ 3. Configure the plugin through the Homebridge UI or manually edit your config.json.
@@ -1,51 +1,41 @@
1
1
  {
2
2
  "pluginAlias": "MultipleSwitchAccessory",
3
3
  "pluginType": "accessory",
4
+ "headerDisplay": "Multiple Switch Accessory",
4
5
  "schema": {
5
6
  "type": "object",
6
7
  "properties": {
7
8
  "name": {
8
9
  "title": "Accessory Name",
9
10
  "type": "string",
10
- "required": true
11
+ "default": "Multiple Switch"
11
12
  },
12
- "addMasterSwitch": {
13
- "title": "Add Master Switch",
14
- "type": "boolean",
15
- "default": false
13
+ "switchBehavior": {
14
+ "title": "Switch Behavior Mode",
15
+ "type": "string",
16
+ "default": "independent",
17
+ "oneOf": [
18
+ { "title": "Independent", "enum": ["independent"] },
19
+ { "title": "Master", "enum": ["master"] },
20
+ { "title": "Single", "enum": ["single"] }
21
+ ]
16
22
  },
17
- "switchNames": {
23
+ "switches": {
18
24
  "title": "Switches",
19
25
  "type": "array",
20
26
  "items": {
21
- "type": "string",
22
- "title": "Switch Name",
23
- "required": true
27
+ "type": "object",
28
+ "properties": {
29
+ "name": {
30
+ "title": "Switch Name",
31
+ "type": "string"
32
+ }
33
+ },
34
+ "required": ["name"]
24
35
  },
25
- "minItems": 1,
26
- "default": ["Switch 1"]
36
+ "default": [{ "name": "Switch 1" }]
27
37
  }
28
- }
29
- },
30
- "layout": [
31
- {
32
- "key": "name",
33
- "title": "Accessory Name"
34
- },
35
- {
36
- "key": "addMasterSwitch",
37
- "title": "Add Master Switch"
38
38
  },
39
- {
40
- "key": "switchNames",
41
- "title": "Switches",
42
- "type": "array",
43
- "items": {
44
- "key": "switchNames[]",
45
- "title": "Switch Name",
46
- "required": true
47
- },
48
- "add": "ADD SWITCH"
49
- }
50
- ]
51
- }
39
+ "required": ["name", "switches"]
40
+ }
41
+ }
package/index.js CHANGED
@@ -1,61 +1,72 @@
1
- let Service, Characteristic;
1
+ let Accessory, Service, Characteristic, UUIDGen;
2
2
 
3
- module.exports = (homebridge) => {
4
- Service = homebridge.hap.Service;
5
- Characteristic = homebridge.hap.Characteristic;
6
- homebridge.registerAccessory("MultipleSwitchAccessory", MultipleSwitchAccessory);
3
+ module.exports = (api) => {
4
+ Accessory = api.hap.Accessory;
5
+ Service = api.hap.Service;
6
+ Characteristic = api.hap.Characteristic;
7
+ UUIDGen = api.hap.uuid;
8
+
9
+ api.registerAccessory("MultipleSwitchAccessory", MultipleSwitchAccessory);
7
10
  };
8
11
 
9
12
  class MultipleSwitchAccessory {
10
- constructor(log, config) {
11
- this.log = log;
12
- this.name = config.name || "Multiple Switch";
13
- this.addMasterSwitch = config.addMasterSwitch || false;
14
- this.switchNames = config.switchNames.map((name, index) => name || `Switch ${index + 1}`);
15
-
16
- this.switchStates = Array(this.switchNames.length).fill(false);
17
- this.services = [];
18
-
19
- if (this.addMasterSwitch) {
20
- const masterSwitchService = new Service.Switch(`${this.name} Master`, 'masterSwitch');
21
- masterSwitchService.getCharacteristic(Characteristic.On)
22
- .on('set', this.setMasterSwitch.bind(this))
23
- .on('get', this.getMasterSwitch.bind(this));
24
- this.services.push(masterSwitchService);
25
- }
26
-
27
- this.switchNames.forEach((name, i) => {
28
- const switchService = new Service.Switch(name, `switch${i + 1}`);
29
- switchService.getCharacteristic(Characteristic.On)
30
- .on('set', this.setOn.bind(this, i))
31
- .on('get', this.getOn.bind(this, i));
32
- this.services.push(switchService);
33
- });
34
- }
13
+ constructor(log, config, api) {
14
+ this.log = log;
15
+ this.config = config;
16
+ this.name = config.name;
17
+ this.switches = config.switches || [];
18
+ this.mode = config.switchBehavior || "independent";
19
+ this.services = [];
35
20
 
36
- setMasterSwitch(value, callback) {
37
- this.switchStates = this.switchStates.map(() => value);
38
- this.services.slice(1).forEach((service, i) => {
39
- service.getCharacteristic(Characteristic.On).updateValue(value);
40
- });
41
- callback(null);
42
- }
21
+ const uuid = UUIDGen.generate(this.name);
22
+ this.accessory = new Accessory(this.name, uuid);
23
+ this.switchStates = Array(this.switches.length).fill(false);
43
24
 
44
- getMasterSwitch(callback) {
45
- const allOn = this.switchStates.every(state => state === true);
46
- callback(null, allOn);
47
- }
25
+ this.switches.forEach((sw, index) => {
26
+ const service = new Service.Outlet(sw.name, "switch_" + index);
27
+ service
28
+ .getCharacteristic(Characteristic.On)
29
+ .onGet(() => this.switchStates[index])
30
+ .onSet((value) => this.setState(index, value));
31
+ this.accessory.addService(service);
32
+ this.services.push(service);
33
+ });
48
34
 
49
- setOn(index, value, callback) {
50
- this.switchStates[index] = value;
51
- callback(null);
35
+ if (this.mode === "master") {
36
+ const master = new Service.Outlet("Master", "master");
37
+ master
38
+ .getCharacteristic(Characteristic.On)
39
+ .onGet(() => this.switchStates.every((s) => s))
40
+ .onSet((value) => this.setAll(value));
41
+ this.accessory.addService(master);
42
+ this.services.unshift(master);
52
43
  }
44
+ }
53
45
 
54
- getOn(index, callback) {
55
- callback(null, this.switchStates[index]);
46
+ setState(index, value) {
47
+ if (this.mode === "single" && value) {
48
+ this.switchStates = this.switchStates.map((_, i) => i === index);
49
+ } else {
50
+ this.switchStates[index] = value;
56
51
  }
52
+ this.updateStates();
53
+ }
57
54
 
58
- getServices() {
59
- return this.services;
60
- }
61
- }
55
+ setAll(value) {
56
+ this.switchStates = this.switchStates.map(() => value);
57
+ this.updateStates();
58
+ }
59
+
60
+ updateStates() {
61
+ this.switches.forEach((_, i) => {
62
+ this.services
63
+ .find((s) => s.subtype === "switch_" + i)
64
+ ?.getCharacteristic(Characteristic.On)
65
+ .updateValue(this.switchStates[i]);
66
+ });
67
+ }
68
+
69
+ getServices() {
70
+ return [this.accessory.getService(Service.AccessoryInformation), ...this.accessory.services];
71
+ }
72
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "homebridge-multiple-switch",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "Multiple switch accessory for Homebridge",
5
5
  "main": "index.js",
6
6
  "author": "Azad Aydınlı",
@@ -11,7 +11,7 @@
11
11
  "repository": {
12
12
  "type": "git",
13
13
  "url": "https://github.com/azadaydinli/homebridge-multiple-switch.git"
14
- },
14
+ },
15
15
  "engines": {
16
16
  "node": ">=14.17.0",
17
17
  "homebridge": ">=1.3.0"