homebridge-openwrt-control 0.0.2-beta.3 → 0.0.2-beta.31
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/config.schema.json +1 -1
- package/index.js +35 -35
- package/package.json +1 -1
- package/src/apdevice.js +21 -18
- package/src/openwrt.js +68 -60
- package/src/swdevice.js +32 -26
package/config.schema.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"singular": true,
|
|
5
5
|
"fixArrays": true,
|
|
6
6
|
"strictValidation": true,
|
|
7
|
-
"headerDisplay": "This plugin works with OpenWrt
|
|
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
|
|
30
|
-
const { name, host,
|
|
31
|
-
if (!name || !host || !
|
|
32
|
-
log.warn(`Device: ${host || 'host missing'}, ${name || 'name missing'}, ${
|
|
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:
|
|
39
|
-
success:
|
|
40
|
-
info:
|
|
41
|
-
warn:
|
|
42
|
-
error:
|
|
43
|
-
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
|
-
...
|
|
48
|
+
...deviceConfig,
|
|
50
49
|
auth: {
|
|
51
|
-
...
|
|
50
|
+
...deviceConfig.auth,
|
|
52
51
|
passwd: 'removed',
|
|
53
52
|
},
|
|
54
53
|
mqtt: {
|
|
55
54
|
auth: {
|
|
56
|
-
...
|
|
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
|
|
65
|
-
|
|
66
|
-
if (
|
|
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
|
-
|
|
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) {
|
|
@@ -80,8 +79,12 @@ class OpenWrtPlatform {
|
|
|
80
79
|
return;
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
// start openwrt impulse generator
|
|
83
|
+
await openWrt.impulseGenerator.state(true, [{ name: 'connect', sampling: refreshInterval }], false);
|
|
84
|
+
|
|
85
|
+
for (const device of configuredDevices) {
|
|
86
|
+
try {
|
|
87
|
+
|
|
85
88
|
// create impulse generator
|
|
86
89
|
const impulseGenerator = new ImpulseGenerator()
|
|
87
90
|
.on('start', async () => {
|
|
@@ -90,8 +93,8 @@ class OpenWrtPlatform {
|
|
|
90
93
|
// create device instance
|
|
91
94
|
let type;
|
|
92
95
|
switch (device) {
|
|
93
|
-
case 'accessPoint': type = new AccessPoint(api,
|
|
94
|
-
case 'switch': type = new Switch(api,
|
|
96
|
+
case 'accessPoint': type = new AccessPoint(api, deviceConfig, openWrt, openWrtInfo); break;
|
|
97
|
+
case 'switch': type = new Switch(api, deviceConfig, openWrt, openWrtInfo); break;
|
|
95
98
|
default:
|
|
96
99
|
if (logLevel.warn) log.warn(`Device: ${host} ${name}, unknown device: ${device}`);
|
|
97
100
|
return;
|
|
@@ -111,7 +114,7 @@ class OpenWrtPlatform {
|
|
|
111
114
|
if (logLevel.success) log.success(`Device: ${host} ${name}, Published as external accessory.`);
|
|
112
115
|
}
|
|
113
116
|
|
|
114
|
-
// stop
|
|
117
|
+
// stop accessory impulse generator
|
|
115
118
|
await impulseGenerator.state(false);
|
|
116
119
|
} catch (error) {
|
|
117
120
|
if (logLevel.error) log.error(`Device: ${host} ${name}, Start impulse generator error: ${error.message ?? error}, trying again.`);
|
|
@@ -121,14 +124,11 @@ class OpenWrtPlatform {
|
|
|
121
124
|
if (logLevel.debug) log.info(`Device: ${host} ${name}, Start impulse generator ${state ? 'started' : 'stopped'}.`);
|
|
122
125
|
});
|
|
123
126
|
|
|
124
|
-
// start impulse generator
|
|
127
|
+
// start accessory impulse generator
|
|
125
128
|
await impulseGenerator.state(true, [{ name: 'start', sampling: 120000 }]);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (logLevel.error) log.error(`Device: ${host} ${name}, Did finish launching error: ${error.message ?? error}`);
|
|
126
131
|
}
|
|
127
|
-
|
|
128
|
-
// start openwrt impulse generator
|
|
129
|
-
await openWrt.impulseGenerator.state(true, [{ name: 'connect', sampling: refreshInterval }], false);
|
|
130
|
-
} catch (error) {
|
|
131
|
-
if (logLevel.error) log.error(`Device: ${host} ${name}, Did finish launching error: ${error.message ?? error}`);
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
});
|
package/package.json
CHANGED
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
|
|
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?.
|
|
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
|
-
//
|
|
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', `
|
|
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?.
|
|
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
|
|
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,
|
|
223
|
-
.updateCharacteristic(Characteristic.ContactSensorState, state
|
|
225
|
+
?.setCharacteristic(Characteristic.ConfiguredName, serviceName)
|
|
226
|
+
.updateCharacteristic(Characteristic.ContactSensorState, !state);
|
|
224
227
|
|
|
225
228
|
if (this.logInfo) {
|
|
226
|
-
this.emit('info', `
|
|
227
|
-
this.emit('info', `
|
|
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
|
|
250
|
+
export default AccessPoint;
|
package/src/openwrt.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import EventEmitter from
|
|
2
|
-
import axios from
|
|
1
|
+
import EventEmitter from 'events';
|
|
2
|
+
import axios from 'axios';
|
|
3
3
|
import Functions from './functions.js';
|
|
4
|
-
import ImpulseGenerator from
|
|
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.
|
|
11
|
-
this.
|
|
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:
|
|
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(
|
|
35
|
+
.on('connect', () => this.handleWithLock(async () => {
|
|
38
36
|
await this.connect();
|
|
39
37
|
}))
|
|
40
|
-
.on(
|
|
41
|
-
this.emit(state ?
|
|
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(
|
|
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:
|
|
62
|
+
const response = await this.axiosInstance.post('', {
|
|
63
|
+
jsonrpc: '2.0',
|
|
67
64
|
id: 1,
|
|
68
|
-
method:
|
|
69
|
-
params: [
|
|
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(
|
|
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(
|
|
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:
|
|
84
|
+
const response = await this.axiosInstance.post('', {
|
|
85
|
+
jsonrpc: '2.0',
|
|
89
86
|
id: 2,
|
|
90
|
-
method:
|
|
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 ||
|
|
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
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const wirelessStatus = await this.ubusCall(
|
|
108
|
-
if (this.logDebug) this.emit(
|
|
109
|
-
|
|
110
|
-
const wirelessRadios = Object.values(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}));
|
|
119
|
-
|
|
120
|
-
const ssids = wirelessRadios.flatMap(radio => radio.interfaces);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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(
|
|
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(
|
|
141
|
-
return
|
|
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(
|
|
158
|
+
if (this.logDebug) this.emit('debug', `${state ? 'Enabling' : 'Disabling'} SSID ${ssidName}`);
|
|
150
159
|
|
|
151
|
-
const status = await this.ubusCall(
|
|
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(
|
|
167
|
+
await this.ubusCall('uci', 'set',
|
|
159
168
|
{
|
|
160
|
-
config:
|
|
169
|
+
config: 'wireless',
|
|
161
170
|
section: section,
|
|
162
171
|
values: {
|
|
163
|
-
disabled: state ?
|
|
172
|
+
disabled: state ? '0' : '1'
|
|
164
173
|
}
|
|
165
174
|
}
|
|
166
175
|
);
|
|
167
176
|
|
|
168
|
-
await this.ubusCall(
|
|
169
|
-
await this.ubusCall(
|
|
177
|
+
await this.ubusCall('uci', 'commit', { config: 'wireless' });
|
|
178
|
+
await this.ubusCall('network.wireless', 'reload', {});
|
|
170
179
|
|
|
171
|
-
if (this.logDebug) this.emit(
|
|
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
|
|
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.
|
|
16
|
-
this.
|
|
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.
|
|
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?.
|
|
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
|
-
//
|
|
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} ${
|
|
146
|
-
const service = accessory.addService(Service.Switch, serviceName, `service${
|
|
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', `--------
|
|
195
|
-
this.emit('devInfo', `
|
|
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?.
|
|
206
|
+
this.informationService?.updateCharacteristic(Characteristic.FirmwareRevision, info.release?.version);
|
|
204
207
|
})
|
|
205
|
-
.on('
|
|
208
|
+
.on('wirelessStatus', async (status) => {
|
|
206
209
|
})
|
|
207
|
-
.on('
|
|
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
|
|
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,
|
|
221
|
-
.updateCharacteristic(Characteristic.ContactSensorState, state
|
|
226
|
+
?.setCharacteristic(Characteristic.ConfiguredName, serviceName)
|
|
227
|
+
.updateCharacteristic(Characteristic.ContactSensorState, !state);
|
|
222
228
|
|
|
223
229
|
if (this.logInfo) {
|
|
224
|
-
this.emit('info', `
|
|
225
|
-
this.emit('info', `
|
|
226
|
-
this.emit('info', `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
|
|
251
|
+
export default Switch;
|