homebridge-openwrt-control 0.0.2-beta.4 → 0.0.2-beta.40

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",
@@ -13,7 +13,7 @@
13
13
  "type": "array",
14
14
  "items": {
15
15
  "type": "object",
16
- "title": "Network",
16
+ "title": "Device",
17
17
  "properties": {
18
18
  "name": {
19
19
  "title": "Name",
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { join } from 'path';
2
2
  import { mkdirSync, existsSync, writeFileSync } from 'fs';
3
3
  import OpenWrt from './src/openwrt.js';
4
- import AccessPoint from './src/apdevice.js';
5
- import Switch from './src/swdevice.js';
4
+ import AccessPoint from './src/accesspoint.js';
5
+ import Switch from './src/switch.js';
6
6
  import ImpulseGenerator from './src/impulsegenerator.js';
7
7
  import { PluginName, PlatformName } from './src/constants.js';
8
8
 
@@ -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');
@@ -27,9 +26,9 @@ class OpenWrtPlatform {
27
26
 
28
27
  api.on('didFinishLaunching', async () => {
29
28
  for (const deviceConfig of config.devices) {
30
- const { name, host, port, displayType } =deviceConfig;
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`);
29
+ const { name, host, displayType } = deviceConfig;
30
+ if (!name || !host || !displayType) {
31
+ log.warn(`Device: ${host || 'host missing'}, ${name || 'name missing'}, ${!displayType ? ', display type disabled' : ''} in config, will not be published in the Home app`);
33
32
  continue;
34
33
  }
35
34
 
@@ -61,43 +60,45 @@ class OpenWrtPlatform {
61
60
  log.info(`Device: ${host} ${name}, Config: ${JSON.stringify(safeConfig, null, 2)}`);
62
61
  }
63
62
 
63
+ const configuredDevices = [];
64
64
  const refreshInterval = (deviceConfig.refreshInterval ?? 5) * 1000;
65
- if (deviceConfig.accessPoint?.enable) this.devices.push('accessPoint');
66
- if (deviceConfig.switch?.enable) this.devices.push('switch');
67
-
68
- if (this.devices.length === 0) return;
69
-
70
- const openWrt = new OpenWrt(deviceConfig)
71
- .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}`))
76
-
77
- const openWrtInfo = await openWrt.connect();
78
- if (!openWrtInfo.state) {
79
- if (logLevel.warn) log.warn(`Device: ${host} ${name}, no data received`);
80
- return;
81
- }
65
+ if (deviceConfig.accessPoint?.enable) configuredDevices.push('accessPoint');
66
+ if (deviceConfig.switch?.enable) configuredDevices.push('switch');
67
+ if (configuredDevices.length === 0) continue;
82
68
 
83
69
  try {
84
- for (const device of this.devices) {
85
- // create impulse generator
70
+ const openWrt = new OpenWrt(deviceConfig)
71
+ .on('success', msg => logLevel.success && log.success(`Device: ${host}, ${msg}`))
72
+ .on('info', msg => log.info(`Device: ${host} ${name}, ${msg}`))
73
+ .on('debug', msg => log.info(`Device: ${host} ${name}, debug: ${msg}`))
74
+ .on('warn', msg => log.warn(`Device: ${host} ${name}, ${msg}`))
75
+ .on('error', msg => log.error(`Device: ${host} ${name}, ${msg}`))
76
+
77
+ const openWrtInfo = await openWrt.connect();
78
+ if (!openWrtInfo.state) {
79
+ if (logLevel.warn) log.warn(`Device: ${host} ${name}, no data received`);
80
+ continue;
81
+ }
82
+
83
+ // start openwrt impulse generator
84
+ await openWrt.impulseGenerator.state(true, [{ name: 'connect', sampling: refreshInterval }], false);
85
+
86
+ // create impulse generator for every device
87
+ for (const device of configuredDevices) {
86
88
  const impulseGenerator = new ImpulseGenerator()
87
89
  .on('start', async () => {
88
90
  try {
89
91
 
90
- // create device instance
91
- let type;
92
- switch (device) {
93
- case 'accessPoint': type = new AccessPoint(api, deviceConfig, openWrt, openWrtInfo); break;
94
- case 'switch': type = new Switch(api, deviceConfig, openWrt, openWrtInfo); break;
95
- default:
96
- if (logLevel.warn) log.warn(`Device: ${host} ${name}, unknown device: ${device}`);
97
- return;
92
+ // create device clases
93
+ const DeviceClasses = { accessPoint: AccessPoint, switch: Switch };
94
+ const DeviceClass = DeviceClasses[device];
95
+
96
+ if (!DeviceClass) {
97
+ if (logLevel.warn) log.warn(`Device: ${host} ${name}, class not found for: ${device}`);
98
+ return;
98
99
  }
99
100
 
100
- type
101
+ const type = new DeviceClass(api, deviceConfig, openWrt, openWrtInfo)
101
102
  .on('devInfo', msg => logLevel.devInfo && log.info(msg))
102
103
  .on('success', msg => logLevel.success && log.success(`Device: ${host} ${name}, ${msg}`))
103
104
  .on('info', msg => log.info(`Device: ${host} ${name}, ${msg}`))
@@ -111,7 +112,7 @@ class OpenWrtPlatform {
111
112
  if (logLevel.success) log.success(`Device: ${host} ${name}, Published as external accessory.`);
112
113
  }
113
114
 
114
- // stop master impulse generator
115
+ // stop accessory impulse generator
115
116
  await impulseGenerator.state(false);
116
117
  } catch (error) {
117
118
  if (logLevel.error) log.error(`Device: ${host} ${name}, Start impulse generator error: ${error.message ?? error}, trying again.`);
@@ -121,12 +122,9 @@ class OpenWrtPlatform {
121
122
  if (logLevel.debug) log.info(`Device: ${host} ${name}, Start impulse generator ${state ? 'started' : 'stopped'}.`);
122
123
  });
123
124
 
124
- // start impulse generator
125
+ // start accessory impulse generator
125
126
  await impulseGenerator.state(true, [{ name: 'start', sampling: 120000 }]);
126
127
  }
127
-
128
- // start openwrt impulse generator
129
- await openWrt.impulseGenerator.state(true, [{ name: 'connect', sampling: refreshInterval }], false);
130
128
  } catch (error) {
131
129
  if (logLevel.error) log.error(`Device: ${host} ${name}, Did finish launching error: ${error.message ?? error}`);
132
130
  }
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.4",
4
+ "version": "0.0.2-beta.40",
5
5
  "description": "Homebridge plugin to control OpenWrt flashed devices.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
@@ -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;
@@ -65,8 +66,8 @@ class AccessPointDevice extends EventEmitter {
65
66
  this.mqtt1 = new Mqtt({
66
67
  host: this.mqtt.host,
67
68
  port: this.mqtt.port || 1883,
68
- clientId: this.mqtt.clientId ? `${this.savedInfo.manufacturer}_${this.mqtt.clientId}_${Math.random().toString(16).slice(3)}` : `${this.savedInfo.manufacturer}_${Math.random().toString(16).slice(3)}`,
69
- prefix: this.mqtt.prefix ? `${this.savedInfo.manufacturer}/${this.mqtt.prefix}/${this.name}` : `${this.savedInfo.manufacturer}/${this.name}`,
69
+ clientId: this.mqtt.clientId ? `${this.openWrtInfo.systemInfo.release.distribution || 'OpenWrt'}_${this.mqtt.clientId}_${Math.random().toString(16).slice(3)}` : `${this.openWrtInfo.systemInfo.release.distribution || 'OpenWrt'}_${Math.random().toString(16).slice(3)}`,
70
+ prefix: this.mqtt.prefix ? `${this.openWrtInfo.systemInfo.release.distribution || 'OpenWrt'}/${this.mqtt.prefix}/${this.name}` : `${this.openWrtInfo.systemInfo.release.distribution || 'OpenWrt'}/${this.name}`,
70
71
  user: this.mqtt.auth?.user,
71
72
  passwd: this.mqtt.auth?.passwd,
72
73
  logWarn: this.logWarn,
@@ -121,23 +122,23 @@ 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.system);
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
- accessory.getService(Service.AccessoryInformation)
131
- .setCharacteristic(Characteristic.Manufacturer, 'OpenWrt')
131
+ this.informationService = accessory.getService(Service.AccessoryInformation)
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.ConfiguredName, accessoryName);
135
+ .setCharacteristic(Characteristic.FirmwareRevision, this.openWrtInfo.systemInfo.release?.version);
136
136
 
137
137
  if (this.logDebug) this.emit('debug', `prepare service`);
138
138
 
139
- //device
139
+ //services
140
140
  this.services = [];
141
+ this.sensorServices = [];
141
142
  for (const ssid of this.ssids) {
142
143
  const name = ssid.name;
143
144
  if (this.logDebug) this.emit('debug', `prepare ssid: ${name} service`);
@@ -165,8 +166,6 @@ class AccessPointDevice extends EventEmitter {
165
166
 
166
167
  if (this.accessPoint.sensor) {
167
168
  if (this.logDebug) this.emit('debug', `prepare ssid: ${name} sensor service`);
168
-
169
- this.sensorServices = [];
170
169
  const sensorService = accessory.addService(Service.ContactSensor, serviceName, `sensorService${name}`);
171
170
  sensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
172
171
  sensorService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
@@ -192,39 +191,44 @@ class AccessPointDevice extends EventEmitter {
192
191
  if (this.restFul.enable || this.mqtt.enable) await this.externalIntegrations();
193
192
 
194
193
  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}`);
194
+ this.emit('devInfo', `Model: ${this.openWrtInfo.systemInfo.model || this.openWrtInfo.systemInfo.board_name}`);
197
195
  this.emit('devInfo', `System: ${this.openWrtInfo.systemInfo.system}`);
196
+ this.emit('devInfo', `Kernel: ${this.openWrtInfo.systemInfo.kernel}`);
198
197
  this.emit('devInfo', `Firmware: ${this.openWrtInfo.systemInfo.release?.description}`);
198
+ this.emit('devInfo', `Target: ${this.openWrtInfo.systemInfo.release?.target}`);
199
+ this.emit('devInfo', `SSIDs: ${this.ssids.length}`);
199
200
  this.emit('devInfo', `----------------------------------`);
200
201
 
201
202
  //openwrt client
202
203
  this.openWrt.on('systemInfo', (info) => {
203
- this.informationService?.updateCharacteristic(Characteristic.FirmwareRevision, info.release?.description);
204
+ this.informationService?.updateCharacteristic(Characteristic.FirmwareRevision, info.release?.version);
204
205
  })
206
+ .on('networkInfo', async (info) => {
207
+ })
205
208
  .on('wirelessStatus', async (status) => {
206
209
  })
207
210
  .on('wirelessRadios', async (radios) => {
208
211
  })
209
212
  .on('ssids', async (ssids) => {
213
+ this.ssids = ssids;
214
+
210
215
  // sensors
211
216
  for (let i = 0; i < ssids.length; i++) {
212
217
  const ssid = ssids[i];
213
-
214
- const name = ssid[i].name;
215
- const state = ssid[i].state;
218
+ const name = ssid.name;
219
+ const state = ssid.state;
216
220
  const serviceName = this.accessPoint.namePrefix ? `${this.name} ${name}` : name;
217
221
  this.services?.[i]
218
222
  ?.setCharacteristic(Characteristic.ConfiguredName, serviceName)
219
223
  .updateCharacteristic(Characteristic.On, state);
220
224
 
221
225
  this.sensorServices?.[i]
222
- ?.setCharacteristic(Characteristic.ConfiguredName, name)
223
- .updateCharacteristic(Characteristic.ContactSensorState, state ? 0 : 1);
226
+ ?.setCharacteristic(Characteristic.ConfiguredName, serviceName)
227
+ .updateCharacteristic(Characteristic.ContactSensorState, !state);
224
228
 
225
229
  if (this.logInfo) {
226
- this.emit('info', `SSID name: ${ssid.name}`);
227
- this.emit('info', `Name: ${ssid.state}`);
230
+ this.emit('info', `Name: ${ssid.name}`);
231
+ this.emit('info', `State: ${ssid.state}`);
228
232
  this.emit('info', `Mode: ${ssid.mode}`);
229
233
  }
230
234
  }
@@ -244,4 +248,4 @@ class AccessPointDevice extends EventEmitter {
244
248
  }
245
249
  }
246
250
  };
247
- export default AccessPointDevice;
251
+ 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,52 +59,53 @@ 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
- if (!result?.ubus_rpc_session) {
74
- throw new Error("ubus login failed");
75
- }
70
+ if (!result?.ubus_rpc_session) throw new Error('Ubus login failed');
76
71
 
77
72
  this.sessionId = result.ubus_rpc_session;
78
73
  this.sessionExpiresAt = now + 240_000;
79
74
 
80
- if (this.logDebug) this.emit("debug", `Ubus login OK`);
75
+ if (this.logDebug) this.emit('debug', `Ubus login OK`);
81
76
  return this.sessionId;
82
77
  }
83
78
 
84
79
  async ubusCall(service, method, params = {}) {
85
80
  const session = await this.login();
86
-
87
- const response = await this.axiosInstance.post("", {
88
- jsonrpc: "2.0",
81
+ const response = await this.axiosInstance.post('', {
82
+ jsonrpc: '2.0',
89
83
  id: 2,
90
- method: "call",
84
+ method: 'call',
91
85
  params: [session, service, method, params]
92
86
  });
93
87
 
94
- if (response.data?.error) {
95
- throw new Error(response.data.error.message || "ubus call error");
96
- }
88
+ if (this.logDebug) this.emit('debug', `Response: ${response}`);
89
+
90
+ if (response.data?.error) throw new Error(response.data.error.message || 'Ubus call error');
97
91
 
98
92
  return response.data.result[1];
99
93
  }
100
94
 
101
95
  async connect() {
96
+ const openWrtInfo = { state: false, systemInfo: {}, networkInfo: {}, wirelessStatus: {}, wirelessRadios: [], ssids: [] }
97
+
102
98
  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)}`);
99
+ const systemInfo = await this.ubusCall('system', 'board');
100
+ if (this.logDebug) this.emit('debug', `System info data: ${JSON.stringify(systemInfo, null, 2)}`);
106
101
 
107
- const wirelessStatus = await this.ubusCall("network.wireless", "status");
108
- if (this.logDebug) this.emit("debug", `Wireless status data: ${JSON.stringify(wirelessStatus, null, 2)}`);
102
+ const networkInfo = await this.ubusCall('network.device', 'status', { "name": "eth0" });
103
+ if (this.logDebug) this.emit('debug', `Network info data: ${JSON.stringify(networkInfo, null, 2)}`);
109
104
 
110
- const wirelessRadios = Object.values(status.radios).map(radio => ({
105
+ const wirelessStatus = await this.ubusCall('network.wireless', 'status');
106
+ if (this.logDebug) this.emit('debug', `Wireless status data: ${JSON.stringify(wirelessStatus, null, 2)}`);
107
+
108
+ const wirelessRadios = Object.values(wirelessStatus.radios).map(radio => ({
111
109
  name: radio.name,
112
110
  state: radio.up === true,
113
111
  interfaces: Object.values(radio.interfaces).map(i => ({
@@ -118,27 +116,29 @@ class OpenWrt extends EventEmitter {
118
116
  }));
119
117
 
120
118
  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);
125
-
126
- if (this.firstRun) {
127
- this.emit("success", `Connect success`);
128
- this.firstRun = false;
129
- }
130
-
131
119
  openWrtInfo.state = true;
132
120
  openWrtInfo.systemInfo = systemInfo;
121
+ openWrtInfo.networkInfo = networkInfo;
133
122
  openWrtInfo.wirelessStatus = wirelessStatus;
134
123
  openWrtInfo.wirelessRadios = wirelessRadios;
135
124
  openWrtInfo.ssids = ssids;
136
125
 
137
- if (this.logDebug) this.emit("debug", `OpenWrt Data: ${JSON.stringify(openWrtInfo, null, 2)}`);
126
+ if (this.firstRun) {
127
+ this.emit('success', `Connect success`);
128
+ this.firstRun = false;
129
+ }
130
+
131
+ // emit data
132
+ this.emit('systemInfo', systemInfo);
133
+ this.emit('networkInfo', networkInfo);
134
+ this.emit('wirelessStatus', wirelessStatus);
135
+ this.emit('wirelessRadios', wirelessRadios);
136
+ this.emit('ssids', ssids);
137
+
138
138
  return openWrtInfo;
139
139
  } catch (error) {
140
- if (this.logError) this.emit("error", `Connect error: ${error.message}`);
141
- return null;
140
+ if (this.logError) this.emit('error', `Connect error: ${error.message}`);
141
+ return openWrtInfo;
142
142
  }
143
143
  }
144
144
 
@@ -146,29 +146,29 @@ class OpenWrt extends EventEmitter {
146
146
  switch (type) {
147
147
  case 'ssid':
148
148
  await this.handleWithLock(async () => {
149
- if (this.logDebug) this.emit("debug", `${state ? "Enabling" : "Disabling"} SSID ${ssidName}`);
149
+ if (this.logDebug) this.emit('debug', `${state ? 'Enabling' : 'Disabling'} SSID ${ssidName}`);
150
150
 
151
- const status = await this.ubusCall("network.wireless", "status");
151
+ const status = await this.ubusCall('network.wireless', 'status');
152
152
  const iface = await this.functions.findIfaceBySsid(status, ssidName);
153
153
  if (!iface) throw new Error(`SSID ${ssidName} not found`);
154
154
 
155
155
  const section = iface.section;
156
156
  if (!section) throw new Error(`No UCI section for SSID ${ssidName}`);
157
157
 
158
- await this.ubusCall("uci", "set",
158
+ await this.ubusCall('uci', 'set',
159
159
  {
160
- config: "wireless",
160
+ config: 'wireless',
161
161
  section: section,
162
162
  values: {
163
- disabled: state ? "0" : "1"
163
+ disabled: state ? '0' : '1'
164
164
  }
165
165
  }
166
166
  );
167
167
 
168
- await this.ubusCall("uci", "commit", { config: "wireless" });
169
- await this.ubusCall("network.wireless", "reload", {});
168
+ await this.ubusCall('uci', 'commit', { config: 'wireless' });
169
+ await this.ubusCall('network.wireless', 'reload', {});
170
170
 
171
- if (this.logDebug) this.emit("debug", `Send SSID ${ssidName} ${state ? "enabled" : "disabled"}`);
171
+ if (this.logDebug) this.emit('debug', `Send SSID ${ssidName} ${state ? 'enabled' : 'disabled'}`);
172
172
  });
173
173
  break;
174
174
  case 'switch':
@@ -177,5 +177,4 @@ class OpenWrt extends EventEmitter {
177
177
  }
178
178
  }
179
179
 
180
- export default OpenWrt;
181
-
180
+ export default OpenWrt;
@@ -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
 
@@ -65,8 +66,8 @@ class SwitchDevice extends EventEmitter {
65
66
  this.mqtt1 = new Mqtt({
66
67
  host: this.mqtt.host,
67
68
  port: this.mqtt.port || 1883,
68
- clientId: this.mqtt.clientId ? `${this.savedInfo.manufacturer}_${this.mqtt.clientId}_${Math.random().toString(16).slice(3)}` : `${this.savedInfo.manufacturer}_${Math.random().toString(16).slice(3)}`,
69
- prefix: this.mqtt.prefix ? `${this.savedInfo.manufacturer}/${this.mqtt.prefix}/${this.name}` : `${this.savedInfo.manufacturer}/${this.name}`,
69
+ clientId: this.mqtt.clientId ? `${this.openWrtInfo.systemInfo.release.distribution || 'OpenWrt'}_${this.mqtt.clientId}_${Math.random().toString(16).slice(3)}` : `${this.openWrtInfo.systemInfo.release.distribution || 'OpenWrt'}_${Math.random().toString(16).slice(3)}`,
70
+ prefix: this.mqtt.prefix ? `${this.openWrtInfo.systemInfo.release.distribution || 'OpenWrt'}/${this.mqtt.prefix}/${this.name}` : `${this.openWrtInfo.systemInfo.release.distribution || 'OpenWrt'}/${this.name}`,
70
71
  user: this.mqtt.auth?.user,
71
72
  passwd: this.mqtt.auth?.passwd,
72
73
  logWarn: this.logWarn,
@@ -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.system);
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,46 @@ 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('networkInfo', async (info) => {
206
209
  })
207
- .on('switchPorts', async (ports) => {
210
+ .on('wirelessStatus', async (status) => {
211
+ })
212
+ .on('wirelessRadios', async (radios) => {
213
+ })
214
+ .on('ports', async (ports) => {
215
+ this.ports = ports;
216
+
208
217
  // sensors
209
218
  for (let i = 0; i < ports.length; i++) {
210
219
  const port = ports[i];
211
-
212
- const name = port[i].name;
213
- const state = port[i].state;
220
+ const name = port.name;
221
+ const state = port.state;
214
222
  const serviceName = this.accessPoint.namePrefix ? `${this.name} ${name}` : name;
215
223
  this.services?.[i]
216
224
  ?.setCharacteristic(Characteristic.ConfiguredName, serviceName)
217
225
  .updateCharacteristic(Characteristic.On, state);
218
226
 
219
227
  this.sensorServices?.[i]
220
- ?.setCharacteristic(Characteristic.ConfiguredName, name)
221
- .updateCharacteristic(Characteristic.ContactSensorState, state ? 0 : 1);
228
+ ?.setCharacteristic(Characteristic.ConfiguredName, serviceName)
229
+ .updateCharacteristic(Characteristic.ContactSensorState, !state);
222
230
 
223
231
  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}`);
232
+ this.emit('info', `Name: ${ports.name}`);
233
+ this.emit('info', `State: ${ports.state}`);
234
+ this.emit('info', `Mode: ${ports.mode}`);
227
235
  }
228
236
  }
229
237
  })
@@ -242,4 +250,4 @@ class SwitchDevice extends EventEmitter {
242
250
  }
243
251
  }
244
252
  };
245
- export default SwitchDevice;
253
+ export default Switch;