iobroker.pro-bravia 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +129 -0
- package/admin/i18n/de.json +28 -0
- package/admin/i18n/en.json +28 -0
- package/admin/i18n/es.json +28 -0
- package/admin/i18n/fr.json +28 -0
- package/admin/i18n/it.json +28 -0
- package/admin/i18n/nl.json +28 -0
- package/admin/i18n/pl.json +28 -0
- package/admin/i18n/pt.json +28 -0
- package/admin/i18n/ru.json +28 -0
- package/admin/i18n/uk.json +28 -0
- package/admin/i18n/zh-cn.json +28 -0
- package/admin/jsonConfig.json +184 -0
- package/admin/pro-bravia.png +0 -0
- package/build/device.js +275 -0
- package/build/device.js.map +1 -0
- package/build/devices/appcontrol.js +122 -0
- package/build/devices/appcontrol.js.map +1 -0
- package/build/devices/audio.js +252 -0
- package/build/devices/audio.js.map +1 -0
- package/build/devices/avcontent.js +227 -0
- package/build/devices/avcontent.js.map +1 -0
- package/build/devices/remote.js +118 -0
- package/build/devices/remote.js.map +1 -0
- package/build/devices/settings-group.js +115 -0
- package/build/devices/settings-group.js.map +1 -0
- package/build/devices/system.js +408 -0
- package/build/devices/system.js.map +1 -0
- package/build/devices/types.js +3 -0
- package/build/devices/types.js.map +1 -0
- package/build/devices/video.js +136 -0
- package/build/devices/video.js.map +1 -0
- package/build/devices/videoscreen.js +67 -0
- package/build/devices/videoscreen.js.map +1 -0
- package/build/discovery/capabilities.js +99 -0
- package/build/discovery/capabilities.js.map +1 -0
- package/build/discovery/state-mapper.js +173 -0
- package/build/discovery/state-mapper.js.map +1 -0
- package/build/lib/config.js +58 -0
- package/build/lib/config.js.map +1 -0
- package/build/lib/errors.js +74 -0
- package/build/lib/errors.js.map +1 -0
- package/build/lib/iobroker-store.js +90 -0
- package/build/lib/iobroker-store.js.map +1 -0
- package/build/lib/state-store.js +134 -0
- package/build/lib/state-store.js.map +1 -0
- package/build/lib/timers.js +35 -0
- package/build/lib/timers.js.map +1 -0
- package/build/main.js +329 -0
- package/build/main.js.map +1 -0
- package/build/transport/ircc-client.js +66 -0
- package/build/transport/ircc-client.js.map +1 -0
- package/build/transport/rest-client.js +91 -0
- package/build/transport/rest-client.js.map +1 -0
- package/build/transport/ssip-client.js +220 -0
- package/build/transport/ssip-client.js.map +1 -0
- package/build/transport/ssip-protocol.js +274 -0
- package/build/transport/ssip-protocol.js.map +1 -0
- package/build/transport/wol.js +104 -0
- package/build/transport/wol.js.map +1 -0
- package/io-package.json +206 -0
- package/package.json +74 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
{
|
|
2
|
+
"i18n": true,
|
|
3
|
+
"type": "tabs",
|
|
4
|
+
"items": {
|
|
5
|
+
"connection": {
|
|
6
|
+
"type": "panel",
|
|
7
|
+
"label": "Connection",
|
|
8
|
+
"items": {
|
|
9
|
+
"_intro": {
|
|
10
|
+
"type": "staticText",
|
|
11
|
+
"text": "connection_intro",
|
|
12
|
+
"sm": 12,
|
|
13
|
+
"xs": 12,
|
|
14
|
+
"md": 12,
|
|
15
|
+
"lg": 12,
|
|
16
|
+
"xl": 12
|
|
17
|
+
},
|
|
18
|
+
"host": {
|
|
19
|
+
"type": "text",
|
|
20
|
+
"label": "Display address",
|
|
21
|
+
"help": "IP address or hostname of the display",
|
|
22
|
+
"placeholder": "192.168.0.14",
|
|
23
|
+
"validatorNoSaveOnError": true,
|
|
24
|
+
"validator": "!!data.host",
|
|
25
|
+
"validatorErrorText": "Enter the display IP address or hostname",
|
|
26
|
+
"sm": 12,
|
|
27
|
+
"md": 6,
|
|
28
|
+
"xs": 12,
|
|
29
|
+
"lg": 6,
|
|
30
|
+
"xl": 6
|
|
31
|
+
},
|
|
32
|
+
"psk": {
|
|
33
|
+
"type": "password",
|
|
34
|
+
"label": "Pre-shared key",
|
|
35
|
+
"help": "Set on the display under Network & Internet > Home network > IP control > Authentication",
|
|
36
|
+
"repeat": false,
|
|
37
|
+
"sm": 12,
|
|
38
|
+
"md": 6,
|
|
39
|
+
"xs": 12,
|
|
40
|
+
"lg": 6,
|
|
41
|
+
"xl": 6
|
|
42
|
+
},
|
|
43
|
+
"httpPort": {
|
|
44
|
+
"type": "number",
|
|
45
|
+
"label": "HTTP port",
|
|
46
|
+
"help": "Displays serve the REST and IRCC endpoints on port 80",
|
|
47
|
+
"min": 1,
|
|
48
|
+
"max": 65535,
|
|
49
|
+
"default": 80,
|
|
50
|
+
"sm": 6,
|
|
51
|
+
"md": 3,
|
|
52
|
+
"xs": 12,
|
|
53
|
+
"lg": 3,
|
|
54
|
+
"xl": 3
|
|
55
|
+
},
|
|
56
|
+
"requestTimeout": {
|
|
57
|
+
"type": "number",
|
|
58
|
+
"label": "Request timeout (s)",
|
|
59
|
+
"min": 1,
|
|
60
|
+
"max": 60,
|
|
61
|
+
"default": 5,
|
|
62
|
+
"sm": 6,
|
|
63
|
+
"md": 3,
|
|
64
|
+
"xs": 12,
|
|
65
|
+
"lg": 3,
|
|
66
|
+
"xl": 3
|
|
67
|
+
},
|
|
68
|
+
"pollInterval": {
|
|
69
|
+
"type": "number",
|
|
70
|
+
"label": "Poll interval (s)",
|
|
71
|
+
"help": "How often to re-read values the display cannot push",
|
|
72
|
+
"min": 5,
|
|
73
|
+
"max": 3600,
|
|
74
|
+
"default": 30,
|
|
75
|
+
"sm": 6,
|
|
76
|
+
"md": 3,
|
|
77
|
+
"xs": 12,
|
|
78
|
+
"lg": 3,
|
|
79
|
+
"xl": 3
|
|
80
|
+
},
|
|
81
|
+
"_test": {
|
|
82
|
+
"type": "sendTo",
|
|
83
|
+
"label": "Test connection",
|
|
84
|
+
"command": "testConnection",
|
|
85
|
+
"jsonData": "{\"host\": \"${data.host}\", \"psk\": \"${data.psk}\", \"httpPort\": ${data.httpPort}}",
|
|
86
|
+
"variant": "contained",
|
|
87
|
+
"useNative": false,
|
|
88
|
+
"sm": 6,
|
|
89
|
+
"md": 3,
|
|
90
|
+
"xs": 12,
|
|
91
|
+
"lg": 3,
|
|
92
|
+
"xl": 3
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"transports": {
|
|
97
|
+
"type": "panel",
|
|
98
|
+
"label": "Control interfaces",
|
|
99
|
+
"items": {
|
|
100
|
+
"_transports_intro": {
|
|
101
|
+
"type": "staticText",
|
|
102
|
+
"text": "transports_intro",
|
|
103
|
+
"sm": 12,
|
|
104
|
+
"xs": 12,
|
|
105
|
+
"md": 12,
|
|
106
|
+
"lg": 12,
|
|
107
|
+
"xl": 12
|
|
108
|
+
},
|
|
109
|
+
"useSsip": {
|
|
110
|
+
"type": "checkbox",
|
|
111
|
+
"label": "Use Simple IP Control",
|
|
112
|
+
"help": "Adds instant push updates for power, input, volume, mute and picture mute, and enables picture mute control",
|
|
113
|
+
"default": true,
|
|
114
|
+
"sm": 12,
|
|
115
|
+
"md": 6,
|
|
116
|
+
"xs": 12,
|
|
117
|
+
"lg": 6,
|
|
118
|
+
"xl": 6
|
|
119
|
+
},
|
|
120
|
+
"ssipPort": {
|
|
121
|
+
"type": "number",
|
|
122
|
+
"label": "Simple IP Control port",
|
|
123
|
+
"min": 1,
|
|
124
|
+
"max": 65535,
|
|
125
|
+
"default": 20060,
|
|
126
|
+
"hidden": "!data.useSsip",
|
|
127
|
+
"sm": 12,
|
|
128
|
+
"md": 6,
|
|
129
|
+
"xs": 12,
|
|
130
|
+
"lg": 6,
|
|
131
|
+
"xl": 6
|
|
132
|
+
},
|
|
133
|
+
"useIrcc": {
|
|
134
|
+
"type": "checkbox",
|
|
135
|
+
"label": "Use IRCC-IP remote emulation",
|
|
136
|
+
"help": "Exposes the display's own remote-control key set as buttons",
|
|
137
|
+
"default": true,
|
|
138
|
+
"sm": 12,
|
|
139
|
+
"md": 6,
|
|
140
|
+
"xs": 12,
|
|
141
|
+
"lg": 6,
|
|
142
|
+
"xl": 6
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"wol": {
|
|
147
|
+
"type": "panel",
|
|
148
|
+
"label": "Wake-on-LAN",
|
|
149
|
+
"items": {
|
|
150
|
+
"_wol_intro": {
|
|
151
|
+
"type": "staticText",
|
|
152
|
+
"text": "wol_intro",
|
|
153
|
+
"sm": 12,
|
|
154
|
+
"xs": 12,
|
|
155
|
+
"md": 12,
|
|
156
|
+
"lg": 12,
|
|
157
|
+
"xl": 12
|
|
158
|
+
},
|
|
159
|
+
"macAddress": {
|
|
160
|
+
"type": "text",
|
|
161
|
+
"label": "MAC address",
|
|
162
|
+
"help": "Leave blank to read it from the display automatically",
|
|
163
|
+
"placeholder": "00:11:22:33:44:55",
|
|
164
|
+
"sm": 12,
|
|
165
|
+
"md": 6,
|
|
166
|
+
"xs": 12,
|
|
167
|
+
"lg": 6,
|
|
168
|
+
"xl": 6
|
|
169
|
+
},
|
|
170
|
+
"broadcastAddress": {
|
|
171
|
+
"type": "text",
|
|
172
|
+
"label": "Broadcast address",
|
|
173
|
+
"help": "Leave blank to use the display's own subnet broadcast address",
|
|
174
|
+
"placeholder": "192.168.0.255",
|
|
175
|
+
"sm": 12,
|
|
176
|
+
"md": 6,
|
|
177
|
+
"xs": 12,
|
|
178
|
+
"lg": 6,
|
|
179
|
+
"xl": 6
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
Binary file
|
package/build/device.js
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BraviaDevice = void 0;
|
|
4
|
+
const appcontrol_1 = require("./devices/appcontrol");
|
|
5
|
+
const audio_1 = require("./devices/audio");
|
|
6
|
+
const avcontent_1 = require("./devices/avcontent");
|
|
7
|
+
const remote_1 = require("./devices/remote");
|
|
8
|
+
const system_1 = require("./devices/system");
|
|
9
|
+
const video_1 = require("./devices/video");
|
|
10
|
+
const videoscreen_1 = require("./devices/videoscreen");
|
|
11
|
+
const capabilities_1 = require("./discovery/capabilities");
|
|
12
|
+
const errors_1 = require("./lib/errors");
|
|
13
|
+
const ircc_client_1 = require("./transport/ircc-client");
|
|
14
|
+
const rest_client_1 = require("./transport/rest-client");
|
|
15
|
+
const ssip_client_1 = require("./transport/ssip-client");
|
|
16
|
+
class BraviaDevice {
|
|
17
|
+
options;
|
|
18
|
+
store;
|
|
19
|
+
rest;
|
|
20
|
+
ssip;
|
|
21
|
+
ircc;
|
|
22
|
+
capabilities = capabilities_1.Capabilities.fromServices([]);
|
|
23
|
+
modules = [];
|
|
24
|
+
/** Root channel -> the handler that owns writes beneath it. */
|
|
25
|
+
writeHandlers = new Map();
|
|
26
|
+
ready = false;
|
|
27
|
+
stopped = false;
|
|
28
|
+
/**
|
|
29
|
+
* Discovery only returns anything meaningful while the panel is on: in standby the display
|
|
30
|
+
* answers `getPowerStatus` normally but refuses audio, video, input and app queries with
|
|
31
|
+
* `40005`. When that happens the tree is a stub, and it must be rebuilt once the display wakes.
|
|
32
|
+
*/
|
|
33
|
+
discoveryPending = false;
|
|
34
|
+
sawDisplayOff = false;
|
|
35
|
+
probeFailing = false;
|
|
36
|
+
/**
|
|
37
|
+
* Contexts already reported at warn level. A display that is unplugged fails ~9 calls per
|
|
38
|
+
* poll; without this the log fills with identical lines indefinitely.
|
|
39
|
+
*/
|
|
40
|
+
reportedContexts = new Set();
|
|
41
|
+
constructor(options, store) {
|
|
42
|
+
this.options = options;
|
|
43
|
+
this.store = store;
|
|
44
|
+
this.rest = new rest_client_1.BraviaRestClient({
|
|
45
|
+
host: options.host,
|
|
46
|
+
psk: options.psk,
|
|
47
|
+
port: options.httpPort,
|
|
48
|
+
timeoutMs: options.requestTimeoutMs,
|
|
49
|
+
});
|
|
50
|
+
this.ssip = options.useSsip
|
|
51
|
+
? new ssip_client_1.SsipClient({ host: options.host, port: options.ssipPort, timers: options.timers })
|
|
52
|
+
: null;
|
|
53
|
+
this.ircc = options.useIrcc
|
|
54
|
+
? new ircc_client_1.BraviaIrccClient({
|
|
55
|
+
host: options.host,
|
|
56
|
+
psk: options.psk,
|
|
57
|
+
port: options.httpPort,
|
|
58
|
+
timeoutMs: options.requestTimeoutMs,
|
|
59
|
+
})
|
|
60
|
+
: null;
|
|
61
|
+
}
|
|
62
|
+
context() {
|
|
63
|
+
return {
|
|
64
|
+
rest: this.rest,
|
|
65
|
+
ssip: this.ssip,
|
|
66
|
+
ircc: this.ircc,
|
|
67
|
+
capabilities: this.capabilities,
|
|
68
|
+
store: this.store,
|
|
69
|
+
config: {
|
|
70
|
+
host: this.options.host,
|
|
71
|
+
macAddress: this.options.macAddress,
|
|
72
|
+
broadcastAddress: this.options.broadcastAddress,
|
|
73
|
+
},
|
|
74
|
+
timers: this.options.timers,
|
|
75
|
+
reportError: (error, context) => this.reportError(error, context),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Confirm the display is actually answering.
|
|
80
|
+
*
|
|
81
|
+
* The module loops below deliberately swallow per-feature failures so one unsupported
|
|
82
|
+
* method cannot abort discovery — which means they can never tell the caller the display
|
|
83
|
+
* is unreachable. This single unguarded call is the liveness signal `info.connection`
|
|
84
|
+
* is driven from, and it is also what surfaces a wrong pre-shared key as an auth error.
|
|
85
|
+
*/
|
|
86
|
+
async probe() {
|
|
87
|
+
let status;
|
|
88
|
+
try {
|
|
89
|
+
const result = await this.rest.callFirst('system', 'getPowerStatus');
|
|
90
|
+
status = result.status ?? '';
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
this.probeFailing = true;
|
|
94
|
+
throw e;
|
|
95
|
+
}
|
|
96
|
+
// Only a genuine unreachable -> reachable transition makes old failures newsworthy again.
|
|
97
|
+
// Clearing on every successful probe would reset the set before it was ever consulted,
|
|
98
|
+
// leaving the de-duplication inert and the warning repeating on every poll.
|
|
99
|
+
if (this.probeFailing) {
|
|
100
|
+
this.probeFailing = false;
|
|
101
|
+
this.reportedContexts.clear();
|
|
102
|
+
}
|
|
103
|
+
return status === 'active';
|
|
104
|
+
}
|
|
105
|
+
/** Stop all further work. Called from `onUnload` before the transports are torn down. */
|
|
106
|
+
stop() {
|
|
107
|
+
this.stopped = true;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Discover what the display supports and build the state tree from it.
|
|
111
|
+
*
|
|
112
|
+
* Called once the display is reachable. Safe to call again after a reconnection: object
|
|
113
|
+
* creation is idempotent.
|
|
114
|
+
*/
|
|
115
|
+
async initialise() {
|
|
116
|
+
// Must come first: Capabilities.discover() falls back to "assume everything supported"
|
|
117
|
+
// when the display does not answer, so on its own it hides an unreachable display.
|
|
118
|
+
const active = await this.probe();
|
|
119
|
+
this.capabilities = await capabilities_1.Capabilities.discover(this.rest);
|
|
120
|
+
if (this.capabilities.assumed) {
|
|
121
|
+
this.store.log.warn('The display did not report its supported API list; assuming full support and ' +
|
|
122
|
+
'relying on per-call errors instead.');
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
this.store.log.info(`Display supports services: ${this.capabilities.serviceNames.join(', ')}`);
|
|
126
|
+
}
|
|
127
|
+
const ctx = this.context();
|
|
128
|
+
const system = new system_1.SystemModule(ctx);
|
|
129
|
+
const audio = new audio_1.AudioModule(ctx);
|
|
130
|
+
const video = new video_1.VideoModule(ctx);
|
|
131
|
+
const avContent = new avcontent_1.AvContentModule(ctx);
|
|
132
|
+
const videoScreen = new videoscreen_1.VideoScreenModule(ctx);
|
|
133
|
+
const appControl = new appcontrol_1.AppControlModule(ctx);
|
|
134
|
+
const remote = new remote_1.RemoteModule(ctx);
|
|
135
|
+
this.modules = [system, audio, video, avContent, videoScreen, appControl, remote];
|
|
136
|
+
await this.runModuleInit();
|
|
137
|
+
// A display in standby yields an empty tree without failing, so mark it for a rebuild.
|
|
138
|
+
this.discoveryPending = !active || this.sawDisplayOff;
|
|
139
|
+
if (this.discoveryPending) {
|
|
140
|
+
this.store.log.info('The display is in standby, so it could not report its capabilities yet; ' +
|
|
141
|
+
'discovery will complete automatically once it is switched on.');
|
|
142
|
+
}
|
|
143
|
+
this.writeHandlers.clear();
|
|
144
|
+
this.writeHandlers.set('power', (path, value) => system.write(path, value));
|
|
145
|
+
// The system module owns two roots: power control and system-level settings.
|
|
146
|
+
this.writeHandlers.set('system', (path, value) => system.writeSystem(path, value));
|
|
147
|
+
this.writeHandlers.set('audio', (path, value) => audio.write(path, value));
|
|
148
|
+
this.writeHandlers.set('video', (path, value) => video.write(path, value));
|
|
149
|
+
this.writeHandlers.set('input', (path, value) => avContent.write(path, value));
|
|
150
|
+
this.writeHandlers.set('scene', (path, value) => videoScreen.write(path, value));
|
|
151
|
+
this.writeHandlers.set('apps', (path, value) => appControl.write(path, value));
|
|
152
|
+
this.writeHandlers.set('remote', (path, value) => remote.write(path, value));
|
|
153
|
+
this.ready = true;
|
|
154
|
+
}
|
|
155
|
+
/** Create objects for every module. Idempotent, so it can be re-run when the display wakes. */
|
|
156
|
+
async runModuleInit() {
|
|
157
|
+
this.sawDisplayOff = false;
|
|
158
|
+
for (const module of this.modules) {
|
|
159
|
+
// Re-checked every iteration: discovery can run for a long time against a slow
|
|
160
|
+
// display, and a Save in admin restarts the instance underneath it.
|
|
161
|
+
if (this.stopped) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
await module.init();
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
this.reportError(e, `${module.name}.init`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/** Re-read every value the display exposes. */
|
|
173
|
+
async refresh() {
|
|
174
|
+
if (!this.ready || this.stopped) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// Rejects when the display is unreachable, so the caller can act on it.
|
|
178
|
+
const active = await this.probe();
|
|
179
|
+
// Finish the discovery that standby prevented, before any module writes values that
|
|
180
|
+
// would otherwise land on objects that were never created.
|
|
181
|
+
if (active && this.discoveryPending) {
|
|
182
|
+
this.store.log.info('Display is on; completing the capability discovery it refused in standby');
|
|
183
|
+
await this.runModuleInit();
|
|
184
|
+
this.discoveryPending = this.sawDisplayOff;
|
|
185
|
+
}
|
|
186
|
+
for (const module of this.modules) {
|
|
187
|
+
if (this.stopped) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
await module.refresh();
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
this.reportError(e, `${module.name}.refresh`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Dispatch a command written to one of our states.
|
|
200
|
+
*
|
|
201
|
+
* @param id state id relative to the adapter namespace, e.g. `audio.volume`
|
|
202
|
+
* @returns true when a module claimed and executed the write
|
|
203
|
+
*/
|
|
204
|
+
async write(id, value) {
|
|
205
|
+
if (!this.ready) {
|
|
206
|
+
throw new errors_1.BraviaError('Display is not initialised yet', 'retryable');
|
|
207
|
+
}
|
|
208
|
+
const separator = id.indexOf('.');
|
|
209
|
+
if (separator === -1) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
const root = id.slice(0, separator);
|
|
213
|
+
const path = id.slice(separator + 1);
|
|
214
|
+
const handler = this.writeHandlers.get(root);
|
|
215
|
+
if (!handler) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
return handler(path, value);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Route an SSIP push notification to whichever module owns it.
|
|
222
|
+
*
|
|
223
|
+
*/
|
|
224
|
+
async handleNotify(message) {
|
|
225
|
+
for (const module of this.modules) {
|
|
226
|
+
if (!module.onNotify) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
if (await module.onNotify(message)) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (e) {
|
|
235
|
+
this.reportError(e, `${module.name}.onNotify`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
this.store.log.debug(`Unhandled SSIP notification ${message.command} ${message.parameter}`);
|
|
239
|
+
}
|
|
240
|
+
reportError(error, context) {
|
|
241
|
+
const braviaError = error instanceof errors_1.BraviaError ? error : null;
|
|
242
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
243
|
+
// A display in standby refuses most calls by design; log that at debug so a powered-down
|
|
244
|
+
// screen does not fill the log with warnings.
|
|
245
|
+
if (braviaError?.kind === 'displayOff') {
|
|
246
|
+
this.sawDisplayOff = true;
|
|
247
|
+
this.store.log.debug(`${context}: ${message}`);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (braviaError?.kind === 'unsupported') {
|
|
251
|
+
this.store.log.debug(`${context}: not supported by this display (${message})`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
if (this.stopped) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
// Warn once per context until the display answers again; repeats go to debug.
|
|
258
|
+
if (this.reportedContexts.has(context)) {
|
|
259
|
+
this.store.log.debug(`${context}: ${message}`);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
this.reportedContexts.add(context);
|
|
263
|
+
this.store.log.warn(`${context}: ${message}`);
|
|
264
|
+
void this.store.setAck('info.lastError', `${context}: ${message}`);
|
|
265
|
+
}
|
|
266
|
+
get isReady() {
|
|
267
|
+
return this.ready;
|
|
268
|
+
}
|
|
269
|
+
/** Every root channel this device routes writes for. Used by the coverage test. */
|
|
270
|
+
get writableRoots() {
|
|
271
|
+
return [...this.writeHandlers.keys()];
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
exports.BraviaDevice = BraviaDevice;
|
|
275
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AppControlModule = void 0;
|
|
4
|
+
const state_mapper_1 = require("../discovery/state-mapper");
|
|
5
|
+
const state_store_1 = require("../lib/state-store");
|
|
6
|
+
class AppControlModule {
|
|
7
|
+
ctx;
|
|
8
|
+
root = 'apps';
|
|
9
|
+
name = 'appControl';
|
|
10
|
+
applications = [];
|
|
11
|
+
idToUri = new Map();
|
|
12
|
+
constructor(ctx) {
|
|
13
|
+
this.ctx = ctx;
|
|
14
|
+
}
|
|
15
|
+
async init() {
|
|
16
|
+
const { store, capabilities } = this.ctx;
|
|
17
|
+
if (!capabilities.hasService('appControl')) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const canLaunch = capabilities.supports('appControl', 'setActiveApp');
|
|
21
|
+
await store.ensureChannel('apps', 'Applications');
|
|
22
|
+
await store.ensureState('apps.list', {
|
|
23
|
+
name: 'Installed applications (JSON)',
|
|
24
|
+
type: 'string',
|
|
25
|
+
role: 'json',
|
|
26
|
+
read: true,
|
|
27
|
+
write: false,
|
|
28
|
+
});
|
|
29
|
+
if (canLaunch) {
|
|
30
|
+
await store.ensureState('apps.launch', {
|
|
31
|
+
name: 'Launch application by URI',
|
|
32
|
+
type: 'string',
|
|
33
|
+
role: 'text',
|
|
34
|
+
read: true,
|
|
35
|
+
write: true,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (capabilities.supports('appControl', 'terminateApps')) {
|
|
39
|
+
await store.ensureState('apps.terminate', {
|
|
40
|
+
name: 'Terminate all applications',
|
|
41
|
+
type: 'boolean',
|
|
42
|
+
role: 'button',
|
|
43
|
+
read: false,
|
|
44
|
+
write: true,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
this.applications = await this.readApplications();
|
|
48
|
+
await store.setAck('apps.list', JSON.stringify(this.applications));
|
|
49
|
+
if (this.applications.length > 0 && canLaunch) {
|
|
50
|
+
await store.ensureChannel('apps.items', 'Installed applications');
|
|
51
|
+
for (const application of this.applications) {
|
|
52
|
+
if (!application.uri) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const id = (0, state_mapper_1.sanitiseId)(application.title || application.uri);
|
|
56
|
+
if (this.idToUri.has(id)) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
this.idToUri.set(id, application.uri);
|
|
60
|
+
await store.ensureChannel(`apps.items.${id}`, application.title ?? id);
|
|
61
|
+
await store.ensureState(`apps.items.${id}.uri`, {
|
|
62
|
+
name: 'URI',
|
|
63
|
+
type: 'string',
|
|
64
|
+
role: 'text',
|
|
65
|
+
read: true,
|
|
66
|
+
write: false,
|
|
67
|
+
});
|
|
68
|
+
await store.ensureState(`apps.items.${id}.launch`, {
|
|
69
|
+
name: `Launch ${application.title ?? id}`,
|
|
70
|
+
type: 'boolean',
|
|
71
|
+
role: 'button',
|
|
72
|
+
read: false,
|
|
73
|
+
write: true,
|
|
74
|
+
});
|
|
75
|
+
await store.setAck(`apps.items.${id}.uri`, application.uri);
|
|
76
|
+
}
|
|
77
|
+
await (0, state_store_1.pruneChildren)(store, 'apps.items', this.idToUri.keys());
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async readApplications() {
|
|
81
|
+
if (!this.ctx.capabilities.supports('appControl', 'getApplicationList')) {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const result = await this.ctx.rest.call('appControl', 'getApplicationList');
|
|
86
|
+
return Array.isArray(result[0]) ? result[0] : [];
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
this.ctx.reportError(e, 'appControl.getApplicationList');
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async refresh() {
|
|
94
|
+
// The installed application list only changes on install/uninstall, so it is read at
|
|
95
|
+
// startup rather than on every poll.
|
|
96
|
+
}
|
|
97
|
+
async write(path, value) {
|
|
98
|
+
const { rest, store } = this.ctx;
|
|
99
|
+
if (path === 'launch') {
|
|
100
|
+
await rest.call('appControl', 'setActiveApp', [{ uri: String(value) }]);
|
|
101
|
+
await store.setAck('apps.launch', value);
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
if (path === 'terminate') {
|
|
105
|
+
await rest.call('appControl', 'terminateApps');
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
const button = /^items\.([^.]+)\.launch$/.exec(path);
|
|
109
|
+
if (button) {
|
|
110
|
+
const uri = this.idToUri.get(button[1]);
|
|
111
|
+
if (!uri) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
await rest.call('appControl', 'setActiveApp', [{ uri }]);
|
|
115
|
+
await store.setAck('apps.launch', uri);
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.AppControlModule = AppControlModule;
|
|
122
|
+
//# sourceMappingURL=appcontrol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appcontrol.js","sourceRoot":"","sources":["../../src/devices/appcontrol.ts"],"names":[],"mappings":"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"}
|