homebridge-openwrt-control 0.0.2-beta.3 → 0.0.2-beta.30

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.
@@ -4,7 +4,7 @@
4
4
  "singular": true,
5
5
  "fixArrays": true,
6
6
  "strictValidation": true,
7
- "headerDisplay": "This plugin works with OpenWrt Devices based on Dashboard API. Devices are exposed to HomeKit as separate accessories and each needs to be manually paired.",
7
+ "headerDisplay": "This plugin works with OpenWrt flashed devices. Devices are exposed to HomeKit as separate accessories and each needs to be manually paired.",
8
8
  "footerDisplay": "For documentation please see [GitHub repository](https://github.com/grzegorz914/homebridge-openwrt-control).",
9
9
  "schema": {
10
10
  "type": "object",
package/index.js CHANGED
@@ -14,7 +14,6 @@ class OpenWrtPlatform {
14
14
  return;
15
15
  }
16
16
  this.accessories = [];
17
- this.devices = [];
18
17
 
19
18
  //check if prefs directory exist
20
19
  const prefDir = join(api.user.storagePath(), 'openWrt');
@@ -26,34 +25,34 @@ class OpenWrtPlatform {
26
25
  }
27
26
 
28
27
  api.on('didFinishLaunching', async () => {
29
- for (const config of config.devices) {
30
- const { name, host, port, displayType } = config;
31
- if (!name || !host || !port || !displayType) {
32
- log.warn(`Device: ${host || 'host missing'}, ${name || 'name missing'}, ${port || 'port missing'}${!displayType ? ', disply type disabled' : ''} in config, will not be published in the Home app`);
28
+ for (const deviceConfig of config.devices) {
29
+ const { name, host, displayType } = deviceConfig;
30
+ if (!name || !host || !displayType) {
31
+ log.warn(`Device: ${host || 'host missing'}, ${name || 'name missing'}, ${!displayType ? ', disply type disabled' : ''} in config, will not be published in the Home app`);
33
32
  continue;
34
33
  }
35
34
 
36
35
  //log config
37
36
  const logLevel = {
38
- devInfo: config.log?.deviceInfo,
39
- success: config.log?.success,
40
- info: config.log?.info,
41
- warn: config.log?.warn,
42
- error: config.log?.error,
43
- debug: config.log?.debug
37
+ devInfo: deviceConfig.log?.deviceInfo,
38
+ success: deviceConfig.log?.success,
39
+ info: deviceConfig.log?.info,
40
+ warn: deviceConfig.log?.warn,
41
+ error: deviceConfig.log?.error,
42
+ debug: deviceConfig.log?.debug
44
43
  };
45
44
 
46
45
  if (logLevel.debug) {
47
46
  log.info(`Device: ${host} ${name}, did finish launching.`);
48
47
  const safeConfig = {
49
- ...config,
48
+ ...deviceConfig,
50
49
  auth: {
51
- ...config.auth,
50
+ ...deviceConfig.auth,
52
51
  passwd: 'removed',
53
52
  },
54
53
  mqtt: {
55
54
  auth: {
56
- ...config.mqtt?.auth,
55
+ ...deviceConfig.mqtt?.auth,
57
56
  passwd: 'removed',
58
57
  }
59
58
  },
@@ -61,18 +60,18 @@ class OpenWrtPlatform {
61
60
  log.info(`Device: ${host} ${name}, Config: ${JSON.stringify(safeConfig, null, 2)}`);
62
61
  }
63
62
 
64
- const refreshInterval = (config.refreshInterval ?? 5) * 1000;
65
- if (config.accessPoint?.enable) this.devices.push('accessPoint');
66
- if (config.switch?.enable) this.devices.push('switch');
63
+ const configuredDevices = [];
64
+ const refreshInterval = (deviceConfig.refreshInterval ?? 5) * 1000;
65
+ if (deviceConfig.accessPoint?.enable) configuredDevices.push('accessPoint');
66
+ if (deviceConfig.switch?.enable) configuredDevices.push('switch');
67
+ if (configuredDevices.length === 0) return;
67
68
 
68
- if (this.devices.length === 0) return;
69
-
70
- const openWrt = new OpenWrt(config)
69
+ const openWrt = new OpenWrt(deviceConfig)
71
70
  .on('success', msg => logLevel.success && log.success(`Device: ${host}, ${msg}`))
72
- .on('info', msg => log.info(`Device: ${host}, ${msg}`))
73
- .on('debug', msg => log.info(`Device: ${host}, debug: ${msg}`))
74
- .on('warn', msg => log.warn(`Device: ${host}, ${msg}`))
75
- .on('error', msg => log.error(`Device: ${host}, ${msg}`))
71
+ .on('info', msg => log.info(`Device: ${host} ${name}, ${msg}`))
72
+ .on('debug', msg => log.info(`Device: ${host} ${name}, debug: ${msg}`))
73
+ .on('warn', msg => log.warn(`Device: ${host} ${name}, ${msg}`))
74
+ .on('error', msg => log.error(`Device: ${host} ${name}, ${msg}`))
76
75
 
77
76
  const openWrtInfo = await openWrt.connect();
78
77
  if (!openWrtInfo.state) {
@@ -81,7 +80,8 @@ class OpenWrtPlatform {
81
80
  }
82
81
 
83
82
  try {
84
- for (const device of this.devices) {
83
+ for (const device of configuredDevices) {
84
+
85
85
  // create impulse generator
86
86
  const impulseGenerator = new ImpulseGenerator()
87
87
  .on('start', async () => {
@@ -90,8 +90,8 @@ class OpenWrtPlatform {
90
90
  // create device instance
91
91
  let type;
92
92
  switch (device) {
93
- case 'accessPoint': type = new AccessPoint(api, config, openWrt, openWrtInfo); break;
94
- case 'switch': type = new Switch(api, config, openWrt, openWrtInfo); break;
93
+ case 'accessPoint': type = new AccessPoint(api, deviceConfig, openWrt, openWrtInfo); break;
94
+ case 'switch': type = new Switch(api, deviceConfig, openWrt, openWrtInfo); break;
95
95
  default:
96
96
  if (logLevel.warn) log.warn(`Device: ${host} ${name}, unknown device: ${device}`);
97
97
  return;
@@ -111,7 +111,7 @@ class OpenWrtPlatform {
111
111
  if (logLevel.success) log.success(`Device: ${host} ${name}, Published as external accessory.`);
112
112
  }
113
113
 
114
- // stop master impulse generator
114
+ // stop accessory impulse generator
115
115
  await impulseGenerator.state(false);
116
116
  } catch (error) {
117
117
  if (logLevel.error) log.error(`Device: ${host} ${name}, Start impulse generator error: ${error.message ?? error}, trying again.`);
@@ -121,7 +121,7 @@ class OpenWrtPlatform {
121
121
  if (logLevel.debug) log.info(`Device: ${host} ${name}, Start impulse generator ${state ? 'started' : 'stopped'}.`);
122
122
  });
123
123
 
124
- // start impulse generator
124
+ // start accessory impulse generator
125
125
  await impulseGenerator.state(true, [{ name: 'start', sampling: 120000 }]);
126
126
  }
127
127
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "OpenWrt Control",
3
3
  "name": "homebridge-openwrt-control",
4
- "version": "0.0.2-beta.3",
4
+ "version": "0.0.2-beta.30",
5
5
  "description": "Homebridge plugin to control OpenWrt flashed devices.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
package/src/apdevice.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import EventEmitter from 'events';
2
2
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
3
3
 
4
- class AccessPointDevice extends EventEmitter {
4
+ class AccessPoint extends EventEmitter {
5
5
  constructor(api, config, openWrt, openWrtInfo) {
6
6
  super();
7
7
 
@@ -12,6 +12,7 @@ class AccessPointDevice extends EventEmitter {
12
12
  AccessoryUUID = api.hap.uuid;
13
13
 
14
14
  //config
15
+ this.host = config.host;
15
16
  this.name = config.accessPoint.name || openWrtInfo.systemInfo.hostname;
16
17
  this.accessPoint = config.accessPoint;
17
18
  this.logInfo = config.log?.info || false;
@@ -121,23 +122,24 @@ class AccessPointDevice extends EventEmitter {
121
122
  //prepare accessory
122
123
  if (this.logDebug) this.emit('debug', `prepare accessory`);
123
124
  const accessoryName = this.name;
124
- const accessoryUUID = AccessoryUUID.generate(this.openWrtInfo.systemInfo.hostname);
125
+ const accessoryUUID = AccessoryUUID.generate(`${this.host}${this.openWrtInfo.systemInfo.hostname}`);
125
126
  const accessoryCategory = Categories.AIRPORT;
126
127
  const accessory = new Accessory(accessoryName, accessoryUUID, accessoryCategory);
127
128
 
128
129
  //prepare information service
129
130
  if (this.logDebug) this.emit('debug', `prepare information service`);
130
131
  accessory.getService(Service.AccessoryInformation)
131
- .setCharacteristic(Characteristic.Manufacturer, 'OpenWrt')
132
+ .setCharacteristic(Characteristic.Manufacturer, this.openWrtInfo.systemInfo.release.distribution || 'OpenWrt')
132
133
  .setCharacteristic(Characteristic.Model, this.openWrtInfo.systemInfo.model)
133
134
  .setCharacteristic(Characteristic.SerialNumber, this.openWrtInfo.systemInfo.system)
134
- .setCharacteristic(Characteristic.FirmwareRevision, this.openWrtInfo.systemInfo.release?.description)
135
+ .setCharacteristic(Characteristic.FirmwareRevision, this.openWrtInfo.systemInfo.release?.version)
135
136
  .setCharacteristic(Characteristic.ConfiguredName, accessoryName);
136
137
 
137
138
  if (this.logDebug) this.emit('debug', `prepare service`);
138
139
 
139
- //device
140
+ //services
140
141
  this.services = [];
142
+ this.sensorServices = [];
141
143
  for (const ssid of this.ssids) {
142
144
  const name = ssid.name;
143
145
  if (this.logDebug) this.emit('debug', `prepare ssid: ${name} service`);
@@ -165,8 +167,6 @@ class AccessPointDevice extends EventEmitter {
165
167
 
166
168
  if (this.accessPoint.sensor) {
167
169
  if (this.logDebug) this.emit('debug', `prepare ssid: ${name} sensor service`);
168
-
169
- this.sensorServices = [];
170
170
  const sensorService = accessory.addService(Service.ContactSensor, serviceName, `sensorService${name}`);
171
171
  sensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
172
172
  sensorService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
@@ -192,39 +192,42 @@ class AccessPointDevice extends EventEmitter {
192
192
  if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
193
193
 
194
194
  this.emit('devInfo', `-------- Access Point ${this.name} --------`);
195
- this.emit('devInfo', `Name: ${this.openWrtInfo.systemInfo.hostname}`);
196
- this.emit('devInfo', `Model: ${this.openWrtInfo.systemInfo.model}`);
195
+ this.emit('devInfo', `Model: ${this.openWrtInfo.systemInfo.model || this.openWrtInfo.systemInfo.board_name}`);
197
196
  this.emit('devInfo', `System: ${this.openWrtInfo.systemInfo.system}`);
197
+ this.emit('devInfo', `Kernel: ${this.openWrtInfo.systemInfo.kernel}`);
198
198
  this.emit('devInfo', `Firmware: ${this.openWrtInfo.systemInfo.release?.description}`);
199
+ this.emit('devInfo', `Target: ${this.openWrtInfo.systemInfo.release?.target}`);
200
+ this.emit('devInfo', `SSIDs: ${this.ssids.length}`);
199
201
  this.emit('devInfo', `----------------------------------`);
200
202
 
201
203
  //openwrt client
202
204
  this.openWrt.on('systemInfo', (info) => {
203
- this.informationService?.updateCharacteristic(Characteristic.FirmwareRevision, info.release?.description);
205
+ this.informationService?.updateCharacteristic(Characteristic.FirmwareRevision, info.release?.version);
204
206
  })
205
207
  .on('wirelessStatus', async (status) => {
206
208
  })
207
209
  .on('wirelessRadios', async (radios) => {
208
210
  })
209
211
  .on('ssids', async (ssids) => {
212
+ this.ssids = ssids;
213
+
210
214
  // sensors
211
215
  for (let i = 0; i < ssids.length; i++) {
212
216
  const ssid = ssids[i];
213
-
214
- const name = ssid[i].name;
215
- const state = ssid[i].state;
217
+ const name = ssid.name;
218
+ const state = ssid.state;
216
219
  const serviceName = this.accessPoint.namePrefix ? `${this.name} ${name}` : name;
217
220
  this.services?.[i]
218
221
  ?.setCharacteristic(Characteristic.ConfiguredName, serviceName)
219
222
  .updateCharacteristic(Characteristic.On, state);
220
223
 
221
224
  this.sensorServices?.[i]
222
- ?.setCharacteristic(Characteristic.ConfiguredName, name)
223
- .updateCharacteristic(Characteristic.ContactSensorState, state ? 0 : 1);
225
+ ?.setCharacteristic(Characteristic.ConfiguredName, serviceName)
226
+ .updateCharacteristic(Characteristic.ContactSensorState, !state);
224
227
 
225
228
  if (this.logInfo) {
226
- this.emit('info', `SSID name: ${ssid.name}`);
227
- this.emit('info', `Name: ${ssid.state}`);
229
+ this.emit('info', `Name: ${ssid.name}`);
230
+ this.emit('info', `State: ${ssid.state}`);
228
231
  this.emit('info', `Mode: ${ssid.mode}`);
229
232
  }
230
233
  }
@@ -244,4 +247,4 @@ class AccessPointDevice extends EventEmitter {
244
247
  }
245
248
  }
246
249
  };
247
- export default AccessPointDevice;
250
+ export default AccessPoint;
package/src/openwrt.js CHANGED
@@ -1,16 +1,14 @@
1
- import EventEmitter from "events";
2
- import axios from "axios";
1
+ import EventEmitter from 'events';
2
+ import axios from 'axios';
3
3
  import Functions from './functions.js';
4
- import ImpulseGenerator from "./impulsegenerator.js";
4
+ import ImpulseGenerator from './impulsegenerator.js';
5
5
 
6
6
  class OpenWrt extends EventEmitter {
7
7
  constructor(config) {
8
8
  super();
9
9
 
10
- this.name = config.name;
11
- this.host = config.host;
12
- this.user = config.user;
13
- this.passwd = config.passwd;
10
+ this.user = config.auth?.user || 'root';
11
+ this.passwd = config.auth?.passwd;
14
12
  this.logError = config.log?.error;
15
13
  this.logDebug = config.log?.debug;
16
14
 
@@ -26,7 +24,7 @@ class OpenWrt extends EventEmitter {
26
24
 
27
25
  this.functions = new Functions();
28
26
  this.axiosInstance = axios.create({
29
- baseURL: `${config.host}/ubus`,
27
+ baseURL: `http://${config.host}/ubus`,
30
28
  timeout: 5000,
31
29
  headers: {
32
30
  "Content-Type": "application/json"
@@ -34,11 +32,11 @@ class OpenWrt extends EventEmitter {
34
32
  });
35
33
 
36
34
  this.impulseGenerator = new ImpulseGenerator()
37
- .on("connect", () => this.handleWithLock(async () => {
35
+ .on('connect', () => this.handleWithLock(async () => {
38
36
  await this.connect();
39
37
  }))
40
- .on("state", (state) => {
41
- this.emit(state ? "success" : "warn", `Impulse generator ${state ? "started" : "stopped"}`);
38
+ .on('state', (state) => {
39
+ this.emit(state ? 'success' : 'warn', `Impulse generator ${state ? 'started' : 'stopped'}`);
42
40
  });
43
41
  }
44
42
 
@@ -49,8 +47,7 @@ class OpenWrt extends EventEmitter {
49
47
  try {
50
48
  await fn();
51
49
  } catch (error) {
52
- this.emit("error", `Impulse generator error: ${error.message}`
53
- );
50
+ this.emit('error', `Impulse generator error: ${error.message}`);
54
51
  } finally {
55
52
  this.lock = false;
56
53
  }
@@ -62,83 +59,95 @@ class OpenWrt extends EventEmitter {
62
59
  return this.sessionId;
63
60
  }
64
61
 
65
- const response = await this.axiosInstance.post("", {
66
- jsonrpc: "2.0",
62
+ const response = await this.axiosInstance.post('', {
63
+ jsonrpc: '2.0',
67
64
  id: 1,
68
- method: "call",
69
- params: ["00000000000000000000000000000000", "session", "login", { username: this.user, password: this.passwd }]
65
+ method: 'call',
66
+ params: ['00000000000000000000000000000000', 'session', 'login', { username: this.user, password: this.passwd }]
70
67
  });
71
68
 
72
69
  const result = response.data?.result?.[1];
73
70
  if (!result?.ubus_rpc_session) {
74
- throw new Error("ubus login failed");
71
+ throw new Error('ubus login failed');
75
72
  }
76
73
 
77
74
  this.sessionId = result.ubus_rpc_session;
78
75
  this.sessionExpiresAt = now + 240_000;
79
76
 
80
- if (this.logDebug) this.emit("debug", `Ubus login OK`);
77
+ if (this.logDebug) this.emit('debug', `Ubus login OK`);
81
78
  return this.sessionId;
82
79
  }
83
80
 
84
81
  async ubusCall(service, method, params = {}) {
85
82
  const session = await this.login();
86
83
 
87
- const response = await this.axiosInstance.post("", {
88
- jsonrpc: "2.0",
84
+ const response = await this.axiosInstance.post('', {
85
+ jsonrpc: '2.0',
89
86
  id: 2,
90
- method: "call",
87
+ method: 'call',
91
88
  params: [session, service, method, params]
92
89
  });
93
90
 
94
91
  if (response.data?.error) {
95
- throw new Error(response.data.error.message || "ubus call error");
92
+ throw new Error(response.data.error.message || 'ubus call error');
96
93
  }
97
94
 
98
95
  return response.data.result[1];
99
96
  }
100
97
 
101
98
  async connect() {
99
+ const openWrtInfo = { state: false, systemInfo: {}, wirelessStatus: {}, wirelessRadios: [], ssids: [] }
100
+
102
101
  try {
103
- const openWrtInfo = { state: false, systemInfo: {}, wirelessStatus: {}, wirelessRadios: [], ssids: [] }
104
- const systemInfo = await this.ubusCall("system", "board");
105
- if (this.logDebug) this.emit("debug", `System info data: ${JSON.stringify(systemInfo, null, 2)}`);
106
-
107
- const wirelessStatus = await this.ubusCall("network.wireless", "status");
108
- if (this.logDebug) this.emit("debug", `Wireless status data: ${JSON.stringify(wirelessStatus, null, 2)}`);
109
-
110
- const wirelessRadios = Object.values(status.radios).map(radio => ({
111
- name: radio.name,
112
- state: radio.up === true,
113
- interfaces: Object.values(radio.interfaces).map(i => ({
114
- name: i.ssid,
115
- state: i.up === true,
116
- mode: i.mode
117
- }))
118
- }));
119
-
120
- const ssids = wirelessRadios.flatMap(radio => radio.interfaces);
121
- this.emit("systemInfo", systemInfo);
122
- this.emit("wirelessStatus", wirelessStatus);
123
- this.emit("wirelessRadios", wirelessRadios);
124
- this.emit("ssids", ssids);
102
+ const systemInfo = await this.ubusCall('system', 'board');
103
+ if (this.logDebug) this.emit('debug', `System info data: ${JSON.stringify(systemInfo, null, 2)}`);
104
+
105
+ //const wirelessStatus = await this.ubusCall('network.wireless', 'status');
106
+ const wirelessStatus = await this.ubusCall('uci', 'get', { config: 'wireless' });
107
+ if (this.logDebug) this.emit('debug', `Wireless status data: ${JSON.stringify(wirelessStatus, null, 2)}`);
108
+
109
+ //const wirelessRadios = Object.values(wirelessStatus.radios).map(radio => ({
110
+ //name: radio.name,
111
+ //state: radio.up === true,
112
+ //interfaces: Object.values(radio.interfaces).map(i => ({
113
+ //name: i.ssid,
114
+ //state: i.up === true,
115
+ //mode: i.mode
116
+ //}))
117
+ //}));
118
+
119
+ //const ssids = wirelessRadios.flatMap(radio => radio.interfaces);
120
+ const ssids = Object.entries(wirelessStatus.values || {}).flatMap(([key, data]) => {
121
+ if (!key.startsWith('wifinet')) return []; // pomijamy wszystko inne
122
+ return [{
123
+ ifname: data['.name'] || key,
124
+ name: data.ssid || null,
125
+ device: data.device || null,
126
+ mode: data.mode || null,
127
+ hidden: data.hidden === '1' || data.hidden === true,
128
+ state: true
129
+ }];
130
+ });
131
+ this.emit('systemInfo', systemInfo);
132
+ this.emit('wirelessStatus', wirelessStatus);
133
+ //this.emit('wirelessRadios', wirelessRadios);
134
+ this.emit('ssids', ssids);
125
135
 
126
136
  if (this.firstRun) {
127
- this.emit("success", `Connect success`);
137
+ this.emit('success', `Connect success`);
128
138
  this.firstRun = false;
129
139
  }
130
140
 
131
141
  openWrtInfo.state = true;
132
142
  openWrtInfo.systemInfo = systemInfo;
133
143
  openWrtInfo.wirelessStatus = wirelessStatus;
134
- openWrtInfo.wirelessRadios = wirelessRadios;
144
+ //openWrtInfo.wirelessRadios = wirelessRadios;
135
145
  openWrtInfo.ssids = ssids;
136
146
 
137
- if (this.logDebug) this.emit("debug", `OpenWrt Data: ${JSON.stringify(openWrtInfo, null, 2)}`);
138
147
  return openWrtInfo;
139
148
  } catch (error) {
140
- if (this.logError) this.emit("error", `Connect error: ${error.message}`);
141
- return null;
149
+ if (this.logError) this.emit('error', `Connect error: ${error.message}`);
150
+ return openWrtInfo;
142
151
  }
143
152
  }
144
153
 
@@ -146,29 +155,29 @@ class OpenWrt extends EventEmitter {
146
155
  switch (type) {
147
156
  case 'ssid':
148
157
  await this.handleWithLock(async () => {
149
- if (this.logDebug) this.emit("debug", `${state ? "Enabling" : "Disabling"} SSID ${ssidName}`);
158
+ if (this.logDebug) this.emit('debug', `${state ? 'Enabling' : 'Disabling'} SSID ${ssidName}`);
150
159
 
151
- const status = await this.ubusCall("network.wireless", "status");
160
+ const status = await this.ubusCall('network.wireless', 'status');
152
161
  const iface = await this.functions.findIfaceBySsid(status, ssidName);
153
162
  if (!iface) throw new Error(`SSID ${ssidName} not found`);
154
163
 
155
164
  const section = iface.section;
156
165
  if (!section) throw new Error(`No UCI section for SSID ${ssidName}`);
157
166
 
158
- await this.ubusCall("uci", "set",
167
+ await this.ubusCall('uci', 'set',
159
168
  {
160
- config: "wireless",
169
+ config: 'wireless',
161
170
  section: section,
162
171
  values: {
163
- disabled: state ? "0" : "1"
172
+ disabled: state ? '0' : '1'
164
173
  }
165
174
  }
166
175
  );
167
176
 
168
- await this.ubusCall("uci", "commit", { config: "wireless" });
169
- await this.ubusCall("network.wireless", "reload", {});
177
+ await this.ubusCall('uci', 'commit', { config: 'wireless' });
178
+ await this.ubusCall('network.wireless', 'reload', {});
170
179
 
171
- if (this.logDebug) this.emit("debug", `Send SSID ${ssidName} ${state ? "enabled" : "disabled"}`);
180
+ if (this.logDebug) this.emit('debug', `Send SSID ${ssidName} ${state ? 'enabled' : 'disabled'}`);
172
181
  });
173
182
  break;
174
183
  case 'switch':
@@ -177,5 +186,4 @@ class OpenWrt extends EventEmitter {
177
186
  }
178
187
  }
179
188
 
180
- export default OpenWrt;
181
-
189
+ export default OpenWrt;
package/src/swdevice.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import EventEmitter from 'events';
2
2
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
3
3
 
4
- class SwitchDevice extends EventEmitter {
4
+ class Switch extends EventEmitter {
5
5
  constructor(api, config, openWrt, openWrtInfo) {
6
6
  super();
7
7
 
@@ -12,8 +12,9 @@ class SwitchDevice extends EventEmitter {
12
12
  AccessoryUUID = api.hap.uuid;
13
13
 
14
14
  //config
15
- this.name = config.switch.name || openWrtInfo.systemInfo.hostname;
16
- this.switch = config.switch;
15
+ this.host = config.host;
16
+ this.name = config.accessPoint.name || openWrtInfo.systemInfo.hostname;
17
+ this.accessPoint = config.accessPoint;
17
18
  this.logInfo = config.log?.info || false;
18
19
  this.logDebug = config.log?.debug || false;
19
20
 
@@ -121,29 +122,30 @@ class SwitchDevice extends EventEmitter {
121
122
  //prepare accessory
122
123
  if (this.logDebug) this.emit('debug', `prepare accessory`);
123
124
  const accessoryName = this.name;
124
- const accessoryUUID = AccessoryUUID.generate(this.openWrtInfo.systemInfo.hostname);
125
- const accessoryCategory = Categories.ROUTER;
125
+ const accessoryUUID = AccessoryUUID.generate(`${this.host}${this.openWrtInfo.systemInfo.hostname}`);
126
+ const accessoryCategory = Categories.AIRPORT;
126
127
  const accessory = new Accessory(accessoryName, accessoryUUID, accessoryCategory);
127
128
 
128
129
  //prepare information service
129
130
  if (this.logDebug) this.emit('debug', `prepare information service`);
130
131
  accessory.getService(Service.AccessoryInformation)
131
- .setCharacteristic(Characteristic.Manufacturer, 'OpenWrt')
132
+ .setCharacteristic(Characteristic.Manufacturer, this.openWrtInfo.systemInfo.release.distribution || 'OpenWrt')
132
133
  .setCharacteristic(Characteristic.Model, this.openWrtInfo.systemInfo.model)
133
134
  .setCharacteristic(Characteristic.SerialNumber, this.openWrtInfo.systemInfo.system)
134
- .setCharacteristic(Characteristic.FirmwareRevision, this.openWrtInfo.systemInfo.release?.description)
135
+ .setCharacteristic(Characteristic.FirmwareRevision, this.openWrtInfo.systemInfo.release?.version)
135
136
  .setCharacteristic(Characteristic.ConfiguredName, accessoryName);
136
137
 
137
138
  if (this.logDebug) this.emit('debug', `prepare service`);
138
139
 
139
- //device
140
+ //services
140
141
  this.services = [];
142
+ this.sensorServices = [];
141
143
  for (const port of this.ports) {
142
144
  const name = port.name;
143
145
  if (this.logDebug) this.emit('debug', `prepare port: ${name} service`);
144
146
 
145
- const serviceName = this.accessPoint.namePrefix ? `${accessoryName} ${ssidName}` : ssidName;
146
- const service = accessory.addService(Service.Switch, serviceName, `service${ssidName}`);
147
+ const serviceName = this.accessPoint.namePrefix ? `${accessoryName} ${name}` : name;
148
+ const service = accessory.addService(Service.Switch, serviceName, `service${name}`);
147
149
  service.addOptionalCharacteristic(Characteristic.ConfiguredName);
148
150
  service.setCharacteristic(Characteristic.ConfiguredName, serviceName);
149
151
  service.getCharacteristic(Characteristic.On)
@@ -166,7 +168,6 @@ class SwitchDevice extends EventEmitter {
166
168
  if (this.accessPoint.sensor) {
167
169
  if (this.logDebug) this.emit('debug', `prepare port: ${name} sensor service`);
168
170
 
169
- this.sensorServices = [];
170
171
  const sensorService = accessory.addService(Service.ContactSensor, serviceName, `sensorService${name}`);
171
172
  sensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
172
173
  sensorService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
@@ -191,39 +192,44 @@ class SwitchDevice extends EventEmitter {
191
192
  //start external integrations
192
193
  if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
193
194
 
194
- this.emit('devInfo', `-------- Switch ${this.name} --------`);
195
- this.emit('devInfo', `Name: ${this.openWrtInfo.systemInfo.hostname}`);
196
- this.emit('devInfo', `Model: ${this.openWrtInfo.systemInfo.model}`);
195
+ this.emit('devInfo', `-------- Access Point ${this.name} --------`);
196
+ this.emit('devInfo', `Model: ${this.openWrtInfo.systemInfo.model || this.openWrtInfo.systemInfo.board_name}`);
197
197
  this.emit('devInfo', `System: ${this.openWrtInfo.systemInfo.system}`);
198
+ this.emit('devInfo', `Kernel: ${this.openWrtInfo.systemInfo.kernel}`);
198
199
  this.emit('devInfo', `Firmware: ${this.openWrtInfo.systemInfo.release?.description}`);
200
+ this.emit('devInfo', `Target: ${this.openWrtInfo.systemInfo.release?.target}`);
201
+ this.emit('devInfo', `Ports: ${this.ports.length}`);
199
202
  this.emit('devInfo', `----------------------------------`);
200
203
 
201
204
  //openwrt client
202
205
  this.openWrt.on('systemInfo', (info) => {
203
- this.informationService?.updateCharacteristic(Characteristic.FirmwareRevision, info.release?.description);
206
+ this.informationService?.updateCharacteristic(Characteristic.FirmwareRevision, info.release?.version);
204
207
  })
205
- .on('switchStatus', async (status) => {
208
+ .on('wirelessStatus', async (status) => {
206
209
  })
207
- .on('switchPorts', async (ports) => {
210
+ .on('wirelessRadios', async (radios) => {
211
+ })
212
+ .on('ports', async (ports) => {
213
+ this.ports = ports;
214
+
208
215
  // sensors
209
216
  for (let i = 0; i < ports.length; i++) {
210
217
  const port = ports[i];
211
-
212
- const name = port[i].name;
213
- const state = port[i].state;
218
+ const name = port.name;
219
+ const state = port.state;
214
220
  const serviceName = this.accessPoint.namePrefix ? `${this.name} ${name}` : name;
215
221
  this.services?.[i]
216
222
  ?.setCharacteristic(Characteristic.ConfiguredName, serviceName)
217
223
  .updateCharacteristic(Characteristic.On, state);
218
224
 
219
225
  this.sensorServices?.[i]
220
- ?.setCharacteristic(Characteristic.ConfiguredName, name)
221
- .updateCharacteristic(Characteristic.ContactSensorState, state ? 0 : 1);
226
+ ?.setCharacteristic(Characteristic.ConfiguredName, serviceName)
227
+ .updateCharacteristic(Characteristic.ContactSensorState, !state);
222
228
 
223
229
  if (this.logInfo) {
224
- this.emit('info', `Port name: ${port.name}`);
225
- this.emit('info', `Name: ${port.state}`);
226
- this.emit('info', `Mode: ${port.mode}`);
230
+ this.emit('info', `Name: ${ports.name}`);
231
+ this.emit('info', `State: ${ports.state}`);
232
+ this.emit('info', `Mode: ${ports.mode}`);
227
233
  }
228
234
  }
229
235
  })
@@ -242,4 +248,4 @@ class SwitchDevice extends EventEmitter {
242
248
  }
243
249
  }
244
250
  };
245
- export default SwitchDevice;
251
+ export default Switch;