@ecobridge.xyz/devicemanager 3.0.2

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.
Files changed (137) hide show
  1. package/.gitea/workflows/default_nottags.yaml +66 -0
  2. package/.gitea/workflows/default_tags.yaml +124 -0
  3. package/.vscode/launch.json +11 -0
  4. package/.vscode/settings.json +26 -0
  5. package/changelog.md +91 -0
  6. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  7. package/dist_ts/00_commitinfo_data.js +9 -0
  8. package/dist_ts/device/device.classes.device.d.ts +205 -0
  9. package/dist_ts/device/device.classes.device.js +344 -0
  10. package/dist_ts/devicemanager.classes.devicemanager.d.ts +210 -0
  11. package/dist_ts/devicemanager.classes.devicemanager.js +835 -0
  12. package/dist_ts/discovery/discovery.classes.homeassistant.d.ts +101 -0
  13. package/dist_ts/discovery/discovery.classes.homeassistant.js +313 -0
  14. package/dist_ts/discovery/discovery.classes.mdns.d.ts +90 -0
  15. package/dist_ts/discovery/discovery.classes.mdns.js +291 -0
  16. package/dist_ts/discovery/discovery.classes.networkscanner.d.ts +64 -0
  17. package/dist_ts/discovery/discovery.classes.networkscanner.js +535 -0
  18. package/dist_ts/discovery/discovery.classes.ssdp.d.ts +112 -0
  19. package/dist_ts/discovery/discovery.classes.ssdp.js +255 -0
  20. package/dist_ts/factories/index.d.ts +190 -0
  21. package/dist_ts/factories/index.js +350 -0
  22. package/dist_ts/features/feature.abstract.d.ts +118 -0
  23. package/dist_ts/features/feature.abstract.js +172 -0
  24. package/dist_ts/features/feature.camera.d.ts +95 -0
  25. package/dist_ts/features/feature.camera.js +162 -0
  26. package/dist_ts/features/feature.climate.d.ts +174 -0
  27. package/dist_ts/features/feature.climate.js +328 -0
  28. package/dist_ts/features/feature.cover.d.ts +121 -0
  29. package/dist_ts/features/feature.cover.js +217 -0
  30. package/dist_ts/features/feature.fan.d.ts +127 -0
  31. package/dist_ts/features/feature.fan.js +235 -0
  32. package/dist_ts/features/feature.light.d.ts +156 -0
  33. package/dist_ts/features/feature.light.js +296 -0
  34. package/dist_ts/features/feature.lock.d.ts +103 -0
  35. package/dist_ts/features/feature.lock.js +170 -0
  36. package/dist_ts/features/feature.playback.d.ts +98 -0
  37. package/dist_ts/features/feature.playback.js +191 -0
  38. package/dist_ts/features/feature.power.d.ts +79 -0
  39. package/dist_ts/features/feature.power.js +173 -0
  40. package/dist_ts/features/feature.print.d.ts +78 -0
  41. package/dist_ts/features/feature.print.js +226 -0
  42. package/dist_ts/features/feature.scan.d.ts +79 -0
  43. package/dist_ts/features/feature.scan.js +315 -0
  44. package/dist_ts/features/feature.sensor.d.ts +95 -0
  45. package/dist_ts/features/feature.sensor.js +147 -0
  46. package/dist_ts/features/feature.snmp.d.ts +88 -0
  47. package/dist_ts/features/feature.snmp.js +175 -0
  48. package/dist_ts/features/feature.switch.d.ts +75 -0
  49. package/dist_ts/features/feature.switch.js +126 -0
  50. package/dist_ts/features/feature.volume.d.ts +104 -0
  51. package/dist_ts/features/feature.volume.js +186 -0
  52. package/dist_ts/features/index.d.ts +19 -0
  53. package/dist_ts/features/index.js +23 -0
  54. package/dist_ts/helpers/helpers.iprange.d.ts +35 -0
  55. package/dist_ts/helpers/helpers.iprange.js +151 -0
  56. package/dist_ts/helpers/helpers.retry.d.ts +25 -0
  57. package/dist_ts/helpers/helpers.retry.js +69 -0
  58. package/dist_ts/index.d.ts +15 -0
  59. package/dist_ts/index.js +40 -0
  60. package/dist_ts/interfaces/feature.interfaces.d.ts +255 -0
  61. package/dist_ts/interfaces/feature.interfaces.js +6 -0
  62. package/dist_ts/interfaces/homeassistant.interfaces.d.ts +550 -0
  63. package/dist_ts/interfaces/homeassistant.interfaces.js +111 -0
  64. package/dist_ts/interfaces/index.d.ts +330 -0
  65. package/dist_ts/interfaces/index.js +16 -0
  66. package/dist_ts/interfaces/smarthome.interfaces.d.ts +282 -0
  67. package/dist_ts/interfaces/smarthome.interfaces.js +7 -0
  68. package/dist_ts/paths.d.ts +1 -0
  69. package/dist_ts/paths.js +3 -0
  70. package/dist_ts/plugins.d.ts +23 -0
  71. package/dist_ts/plugins.js +30 -0
  72. package/dist_ts/protocols/index.d.ts +12 -0
  73. package/dist_ts/protocols/index.js +21 -0
  74. package/dist_ts/protocols/protocol.escl.d.ts +58 -0
  75. package/dist_ts/protocols/protocol.escl.js +364 -0
  76. package/dist_ts/protocols/protocol.homeassistant.d.ts +248 -0
  77. package/dist_ts/protocols/protocol.homeassistant.js +611 -0
  78. package/dist_ts/protocols/protocol.ipp.d.ts +45 -0
  79. package/dist_ts/protocols/protocol.ipp.js +284 -0
  80. package/dist_ts/protocols/protocol.nut.d.ts +160 -0
  81. package/dist_ts/protocols/protocol.nut.js +364 -0
  82. package/dist_ts/protocols/protocol.sane.d.ts +104 -0
  83. package/dist_ts/protocols/protocol.sane.js +597 -0
  84. package/dist_ts/protocols/protocol.snmp.d.ts +133 -0
  85. package/dist_ts/protocols/protocol.snmp.js +333 -0
  86. package/dist_ts/protocols/protocol.upnp.d.ts +207 -0
  87. package/dist_ts/protocols/protocol.upnp.js +442 -0
  88. package/dist_ts/protocols/protocol.upssnmp.d.ts +160 -0
  89. package/dist_ts/protocols/protocol.upssnmp.js +263 -0
  90. package/npmextra.json +24 -0
  91. package/package.json +39 -0
  92. package/readme.hints.md +115 -0
  93. package/readme.md +624 -0
  94. package/test/test.ts +261 -0
  95. package/ts/00_commitinfo_data.ts +8 -0
  96. package/ts/device/device.classes.device.ts +454 -0
  97. package/ts/devicemanager.classes.devicemanager.ts +1219 -0
  98. package/ts/discovery/discovery.classes.homeassistant.ts +376 -0
  99. package/ts/discovery/discovery.classes.mdns.ts +347 -0
  100. package/ts/discovery/discovery.classes.networkscanner.ts +648 -0
  101. package/ts/discovery/discovery.classes.ssdp.ts +357 -0
  102. package/ts/factories/index.ts +696 -0
  103. package/ts/features/feature.abstract.ts +251 -0
  104. package/ts/features/feature.camera.ts +214 -0
  105. package/ts/features/feature.climate.ts +407 -0
  106. package/ts/features/feature.cover.ts +278 -0
  107. package/ts/features/feature.fan.ts +296 -0
  108. package/ts/features/feature.light.ts +369 -0
  109. package/ts/features/feature.lock.ts +223 -0
  110. package/ts/features/feature.playback.ts +246 -0
  111. package/ts/features/feature.power.ts +231 -0
  112. package/ts/features/feature.print.ts +297 -0
  113. package/ts/features/feature.scan.ts +370 -0
  114. package/ts/features/feature.sensor.ts +202 -0
  115. package/ts/features/feature.snmp.ts +235 -0
  116. package/ts/features/feature.switch.ts +170 -0
  117. package/ts/features/feature.volume.ts +256 -0
  118. package/ts/features/index.ts +25 -0
  119. package/ts/helpers/helpers.iprange.ts +172 -0
  120. package/ts/helpers/helpers.retry.ts +100 -0
  121. package/ts/index.ts +165 -0
  122. package/ts/interfaces/feature.interfaces.ts +359 -0
  123. package/ts/interfaces/homeassistant.interfaces.ts +666 -0
  124. package/ts/interfaces/index.ts +421 -0
  125. package/ts/interfaces/smarthome.interfaces.ts +421 -0
  126. package/ts/paths.ts +5 -0
  127. package/ts/plugins.ts +41 -0
  128. package/ts/protocols/index.ts +59 -0
  129. package/ts/protocols/protocol.escl.ts +439 -0
  130. package/ts/protocols/protocol.homeassistant.ts +737 -0
  131. package/ts/protocols/protocol.ipp.ts +329 -0
  132. package/ts/protocols/protocol.nut.ts +471 -0
  133. package/ts/protocols/protocol.sane.ts +694 -0
  134. package/ts/protocols/protocol.snmp.ts +439 -0
  135. package/ts/protocols/protocol.upnp.ts +627 -0
  136. package/ts/protocols/protocol.upssnmp.ts +377 -0
  137. package/tsconfig.json +12 -0
@@ -0,0 +1,291 @@
1
+ import * as plugins from '../plugins.js';
2
+ /**
3
+ * Service type definitions for mDNS discovery
4
+ */
5
+ const SERVICE_TYPES = {
6
+ // Scanners
7
+ ESCL: '_uscan._tcp', // eSCL/AirScan scanners
8
+ ESCL_SECURE: '_uscans._tcp', // eSCL over TLS
9
+ SANE: '_scanner._tcp', // SANE network scanners
10
+ // Printers
11
+ IPP: '_ipp._tcp', // IPP printers
12
+ IPPS: '_ipps._tcp', // IPP over TLS
13
+ PDL: '_pdl-datastream._tcp', // Raw/JetDirect printers
14
+ // Speakers / Audio
15
+ AIRPLAY: '_airplay._tcp', // AirPlay devices (Apple TV, HomePod, etc.)
16
+ RAOP: '_raop._tcp', // Remote Audio Output Protocol (AirPlay audio)
17
+ SONOS: '_sonos._tcp', // Sonos speakers
18
+ GOOGLECAST: '_googlecast._tcp', // Chromecast / Google Cast devices
19
+ SPOTIFY: '_spotify-connect._tcp', // Spotify Connect devices
20
+ };
21
+ /**
22
+ * Default discovery options
23
+ */
24
+ const DEFAULT_OPTIONS = {
25
+ serviceTypes: [
26
+ // Scanners
27
+ SERVICE_TYPES.ESCL,
28
+ SERVICE_TYPES.ESCL_SECURE,
29
+ SERVICE_TYPES.SANE,
30
+ // Printers
31
+ SERVICE_TYPES.IPP,
32
+ SERVICE_TYPES.IPPS,
33
+ // Speakers
34
+ SERVICE_TYPES.AIRPLAY,
35
+ SERVICE_TYPES.RAOP,
36
+ SERVICE_TYPES.SONOS,
37
+ SERVICE_TYPES.GOOGLECAST,
38
+ ],
39
+ timeout: 10000,
40
+ };
41
+ /**
42
+ * mDNS/Bonjour discovery service for network devices
43
+ */
44
+ export class MdnsDiscovery extends plugins.events.EventEmitter {
45
+ bonjour = null;
46
+ browsers = [];
47
+ discoveredDevices = new Map();
48
+ options;
49
+ isRunning = false;
50
+ constructor(options) {
51
+ super();
52
+ this.options = { ...DEFAULT_OPTIONS, ...options };
53
+ }
54
+ /**
55
+ * Check if discovery is currently running
56
+ */
57
+ get running() {
58
+ return this.isRunning;
59
+ }
60
+ /**
61
+ * Get all discovered devices
62
+ */
63
+ getDevices() {
64
+ return Array.from(this.discoveredDevices.values());
65
+ }
66
+ /**
67
+ * Get discovered scanners only
68
+ */
69
+ getScanners() {
70
+ return this.getDevices().filter((d) => d.type === 'scanner');
71
+ }
72
+ /**
73
+ * Get discovered printers only
74
+ */
75
+ getPrinters() {
76
+ return this.getDevices().filter((d) => d.type === 'printer');
77
+ }
78
+ /**
79
+ * Start mDNS discovery
80
+ */
81
+ async start() {
82
+ if (this.isRunning) {
83
+ return;
84
+ }
85
+ this.bonjour = new plugins.bonjourService.Bonjour();
86
+ this.isRunning = true;
87
+ this.emit('started');
88
+ for (const serviceType of this.options.serviceTypes) {
89
+ this.browseService(serviceType);
90
+ }
91
+ }
92
+ /**
93
+ * Stop mDNS discovery
94
+ */
95
+ async stop() {
96
+ if (!this.isRunning) {
97
+ return;
98
+ }
99
+ // Stop all browsers
100
+ for (const browser of this.browsers) {
101
+ browser.stop();
102
+ }
103
+ this.browsers = [];
104
+ // Destroy bonjour instance
105
+ if (this.bonjour) {
106
+ this.bonjour.destroy();
107
+ this.bonjour = null;
108
+ }
109
+ this.isRunning = false;
110
+ this.emit('stopped');
111
+ }
112
+ /**
113
+ * Clear discovered devices
114
+ */
115
+ clear() {
116
+ this.discoveredDevices.clear();
117
+ }
118
+ /**
119
+ * Browse for a specific service type
120
+ */
121
+ browseService(serviceType) {
122
+ if (!this.bonjour) {
123
+ return;
124
+ }
125
+ const browser = this.bonjour.find({ type: serviceType }, (service) => {
126
+ this.handleServiceFound(service, serviceType);
127
+ });
128
+ browser.on('down', (service) => {
129
+ this.handleServiceLost(service, serviceType);
130
+ });
131
+ this.browsers.push(browser);
132
+ }
133
+ /**
134
+ * Handle discovered service
135
+ */
136
+ handleServiceFound(service, serviceType) {
137
+ const device = this.parseService(service, serviceType);
138
+ if (!device) {
139
+ return;
140
+ }
141
+ const existingDevice = this.discoveredDevices.get(device.id);
142
+ if (existingDevice) {
143
+ // Update existing device
144
+ this.discoveredDevices.set(device.id, device);
145
+ this.emit('device:updated', device);
146
+ }
147
+ else {
148
+ // New device found
149
+ this.discoveredDevices.set(device.id, device);
150
+ this.emit('device:found', device);
151
+ if (device.type === 'scanner') {
152
+ this.emit('scanner:found', device);
153
+ }
154
+ else if (device.type === 'printer') {
155
+ this.emit('printer:found', device);
156
+ }
157
+ }
158
+ }
159
+ /**
160
+ * Handle lost service
161
+ */
162
+ handleServiceLost(service, serviceType) {
163
+ const deviceId = this.generateDeviceId(service, serviceType);
164
+ const device = this.discoveredDevices.get(deviceId);
165
+ if (device) {
166
+ this.discoveredDevices.delete(deviceId);
167
+ this.emit('device:lost', device);
168
+ if (device.type === 'scanner') {
169
+ this.emit('scanner:lost', deviceId);
170
+ }
171
+ else if (device.type === 'printer') {
172
+ this.emit('printer:lost', deviceId);
173
+ }
174
+ }
175
+ }
176
+ /**
177
+ * Parse Bonjour service into device info
178
+ */
179
+ parseService(service, serviceType) {
180
+ const addresses = service.addresses ?? [];
181
+ // Prefer IPv4 address
182
+ const address = addresses.find((a) => !a.includes(':')) ?? addresses[0] ?? service.host;
183
+ if (!address) {
184
+ return null;
185
+ }
186
+ const txtRecords = this.parseTxtRecords(service.txt);
187
+ const deviceType = this.getDeviceType(serviceType);
188
+ const protocol = this.getProtocol(serviceType);
189
+ const deviceId = this.generateDeviceId(service, serviceType);
190
+ return {
191
+ id: deviceId,
192
+ name: service.name || txtRecords['ty'] || txtRecords['product'] || 'Unknown Device',
193
+ type: deviceType,
194
+ protocol: protocol,
195
+ address: address,
196
+ port: service.port,
197
+ txtRecords: txtRecords,
198
+ serviceType: serviceType,
199
+ };
200
+ }
201
+ /**
202
+ * Generate unique device ID
203
+ */
204
+ generateDeviceId(service, serviceType) {
205
+ const addresses = service.addresses ?? [];
206
+ const address = addresses.find((a) => !a.includes(':')) ?? addresses[0] ?? service.host;
207
+ return `${serviceType}:${address}:${service.port}`;
208
+ }
209
+ /**
210
+ * Parse TXT records from service
211
+ */
212
+ parseTxtRecords(txt) {
213
+ const records = {};
214
+ if (!txt) {
215
+ return records;
216
+ }
217
+ for (const [key, value] of Object.entries(txt)) {
218
+ if (typeof value === 'string') {
219
+ records[key] = value;
220
+ }
221
+ else if (Buffer.isBuffer(value)) {
222
+ records[key] = value.toString('utf-8');
223
+ }
224
+ else if (value !== undefined && value !== null) {
225
+ records[key] = String(value);
226
+ }
227
+ }
228
+ return records;
229
+ }
230
+ /**
231
+ * Determine device type from service type
232
+ */
233
+ getDeviceType(serviceType) {
234
+ switch (serviceType) {
235
+ case SERVICE_TYPES.ESCL:
236
+ case SERVICE_TYPES.ESCL_SECURE:
237
+ case SERVICE_TYPES.SANE:
238
+ return 'scanner';
239
+ case SERVICE_TYPES.IPP:
240
+ case SERVICE_TYPES.IPPS:
241
+ case SERVICE_TYPES.PDL:
242
+ return 'printer';
243
+ case SERVICE_TYPES.AIRPLAY:
244
+ case SERVICE_TYPES.RAOP:
245
+ case SERVICE_TYPES.SONOS:
246
+ case SERVICE_TYPES.GOOGLECAST:
247
+ case SERVICE_TYPES.SPOTIFY:
248
+ return 'speaker';
249
+ default:
250
+ // Check if it's a scanner or printer based on service type pattern
251
+ if (serviceType.includes('scan') || serviceType.includes('scanner')) {
252
+ return 'scanner';
253
+ }
254
+ if (serviceType.includes('airplay') || serviceType.includes('raop') ||
255
+ serviceType.includes('sonos') || serviceType.includes('cast') ||
256
+ serviceType.includes('spotify')) {
257
+ return 'speaker';
258
+ }
259
+ return 'printer';
260
+ }
261
+ }
262
+ /**
263
+ * Determine protocol from service type
264
+ */
265
+ getProtocol(serviceType) {
266
+ switch (serviceType) {
267
+ case SERVICE_TYPES.ESCL:
268
+ case SERVICE_TYPES.ESCL_SECURE:
269
+ return 'escl';
270
+ case SERVICE_TYPES.SANE:
271
+ return 'sane';
272
+ case SERVICE_TYPES.IPP:
273
+ case SERVICE_TYPES.IPPS:
274
+ case SERVICE_TYPES.PDL:
275
+ return 'ipp';
276
+ case SERVICE_TYPES.AIRPLAY:
277
+ case SERVICE_TYPES.RAOP:
278
+ return 'airplay';
279
+ case SERVICE_TYPES.SONOS:
280
+ return 'sonos';
281
+ case SERVICE_TYPES.GOOGLECAST:
282
+ return 'chromecast';
283
+ case SERVICE_TYPES.SPOTIFY:
284
+ return 'spotify';
285
+ default:
286
+ return 'unknown';
287
+ }
288
+ }
289
+ }
290
+ export { SERVICE_TYPES };
291
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY292ZXJ5LmNsYXNzZXMubWRucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2Rpc2NvdmVyeS9kaXNjb3ZlcnkuY2xhc3Nlcy5tZG5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBUXpDOztHQUVHO0FBQ0gsTUFBTSxhQUFhLEdBQUc7SUFDcEIsV0FBVztJQUNYLElBQUksRUFBRSxhQUFhLEVBQVksd0JBQXdCO0lBQ3ZELFdBQVcsRUFBRSxjQUFjLEVBQUksZ0JBQWdCO0lBQy9DLElBQUksRUFBRSxlQUFlLEVBQVUsd0JBQXdCO0lBRXZELFdBQVc7SUFDWCxHQUFHLEVBQUUsV0FBVyxFQUFlLGVBQWU7SUFDOUMsSUFBSSxFQUFFLFlBQVksRUFBYSxlQUFlO0lBQzlDLEdBQUcsRUFBRSxzQkFBc0IsRUFBSSx5QkFBeUI7SUFFeEQsbUJBQW1CO0lBQ25CLE9BQU8sRUFBRSxlQUFlLEVBQU8sNENBQTRDO0lBQzNFLElBQUksRUFBRSxZQUFZLEVBQWEsK0NBQStDO0lBQzlFLEtBQUssRUFBRSxhQUFhLEVBQVcsaUJBQWlCO0lBQ2hELFVBQVUsRUFBRSxrQkFBa0IsRUFBRSxtQ0FBbUM7SUFDbkUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLDBCQUEwQjtDQUNwRCxDQUFDO0FBRVg7O0dBRUc7QUFDSCxNQUFNLGVBQWUsR0FBZ0M7SUFDbkQsWUFBWSxFQUFFO1FBQ1osV0FBVztRQUNYLGFBQWEsQ0FBQyxJQUFJO1FBQ2xCLGFBQWEsQ0FBQyxXQUFXO1FBQ3pCLGFBQWEsQ0FBQyxJQUFJO1FBQ2xCLFdBQVc7UUFDWCxhQUFhLENBQUMsR0FBRztRQUNqQixhQUFhLENBQUMsSUFBSTtRQUNsQixXQUFXO1FBQ1gsYUFBYSxDQUFDLE9BQU87UUFDckIsYUFBYSxDQUFDLElBQUk7UUFDbEIsYUFBYSxDQUFDLEtBQUs7UUFDbkIsYUFBYSxDQUFDLFVBQVU7S0FDekI7SUFDRCxP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
@@ -0,0 +1,64 @@
1
+ import * as plugins from '../plugins.js';
2
+ import type { INetworkScanOptions, INetworkScanResult } from '../interfaces/index.js';
3
+ /**
4
+ * Network Scanner - scans IP ranges for scanners and printers
5
+ */
6
+ export declare class NetworkScanner extends plugins.events.EventEmitter {
7
+ private cancelled;
8
+ private scanning;
9
+ /**
10
+ * Check if a scan is currently in progress
11
+ */
12
+ get isScanning(): boolean;
13
+ /**
14
+ * Scan a network range for devices
15
+ */
16
+ scan(options: INetworkScanOptions): Promise<INetworkScanResult[]>;
17
+ /**
18
+ * Cancel an ongoing scan
19
+ */
20
+ cancel(): Promise<void>;
21
+ /**
22
+ * Resolve IPs from options (CIDR or start/end range)
23
+ */
24
+ private resolveIps;
25
+ /**
26
+ * Probe a single IP address for devices
27
+ */
28
+ private probeIp;
29
+ /**
30
+ * Quick TCP port scan
31
+ */
32
+ private scanPorts;
33
+ /**
34
+ * Check if a TCP port is open
35
+ */
36
+ private isPortOpen;
37
+ /**
38
+ * Probe for IPP printer using a simple HTTP check
39
+ * We avoid using the full ipp library for probing since it can hang and produce noisy output
40
+ */
41
+ private probeIpp;
42
+ /**
43
+ * Probe for eSCL scanner
44
+ */
45
+ private probeEscl;
46
+ /**
47
+ * Probe for SANE scanner (quick check)
48
+ */
49
+ private probeSane;
50
+ /**
51
+ * Probe for AirPlay speaker on port 7000
52
+ * Tries HTTP endpoints to identify the device. If no HTTP response,
53
+ * but port 7000 is open, it's still likely an AirPlay device.
54
+ */
55
+ private probeAirplay;
56
+ /**
57
+ * Probe for Sonos speaker
58
+ */
59
+ private probeSonos;
60
+ /**
61
+ * Probe for Chromecast device
62
+ */
63
+ private probeChromecast;
64
+ }