Skip to content

Commit 5acedb4

Browse files
committed
Add 1.3.0 release
1 parent 1a51d9f commit 5acedb4

File tree

443 files changed

+161743
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

443 files changed

+161743
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"label": "Architecture",
3+
"position": 6,
4+
"link": {
5+
"type": "generated-index"
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
---
2+
sidebar_position: 3
3+
---
4+
5+
# Apps and consoles
6+
7+
## Terminology
8+
### App (Client)
9+
A frontend application that optionally consumes the OR APIs; same meaning as OAuth client (The OR Manager web application is a client; for custom projects there could be zero or more apps where each app may be used across one or more realms, the apps generally provide very specific functionality as required by the project). These are generally responsive web applications.
10+
11+
### Console
12+
This is the application used to load the client and can be thought of as a wrapper around a client e.g. Web Browser, Android/iOS App. Generally this is an application capable of loading a web view that renders the client. A console could be hardcoded to a specific realm and client or it could be more configurable depending on requirements. A web browser requires no installation where as Android/iOS consoles are pre-compiled and distributed.
13+
14+
## Console/app interaction
15+
Apps and consoles exchange information using the API described below which consists of `providers`, a `provider` is a piece of functionality that the console provides to the app, messages can be sent bidirectionally between the console and app. The Android and iOS consoles implement a standard mechanism for this communication and when running an app in the Web Browser the `@openremote/core` component handles communication and also implements a limited subset of `providers` (e.g. `push`). The console is accessed via the `console` property on the `@openremote/core` component but it is also exported globally as `OpenRemoteConsole`:
16+
```typescript
17+
import openremote from "@openremote/core";
18+
openremote.init(...).then(()=> {
19+
let console1 = openremote.console;
20+
let console2 = window.OpenRemoteConsole;
21+
console.log("Consoles are the same: " + console1 == console2);
22+
});
23+
```
24+
25+
## Build and deployment
26+
Apps should be built and deployed within the OR manager web server using the standard tooling e.g. `gradle clean installDist` (refer to the developer guide).
27+
Console build and deployment will depend on the specific tools and platform used but where possible the standard tooling and deployment process should be used.
28+
29+
## Runtime behaviour
30+
1. Console is 'launched' (e.g. typing URL in browser or opening the app)
31+
1. Console then displays a splash screen indicating that the client is loading
32+
1. App is loaded and the URL should include query parameters to instruct the `@openremote/core` component what functionality they wish to provide to the client (see the Console/app API below)
33+
1. The app will initialise the console and the console must reply to the app as required by the API (see the Console/app API below)
34+
1. If the app has set `consoleAutoEnable: false` when initialising the `@openremote/core` component then the console must listen for the `OREvent.CONSOLE_INIT` event and then it can enable each `provider` that it is providing to the app; once all `providers` are enabled (excluding those that have been explicitly `disabled` by the user or some other mechanism) then the `OREvent.CONSOLE_READY` event is raised
35+
36+
Once the console is ready it is automatically registered with the manager backend by sending a `ConsoleRegistration` object, for example:
37+
```json
38+
{
39+
name: "ExampleConsole",
40+
version: "1.0.0",
41+
platform: "Android 7.1.2",
42+
providers: {
43+
push: {
44+
version: "ORConsole",
45+
requiresPermission: true,
46+
hasPermission: true,
47+
enabled: true,
48+
disabled: false,
49+
data: {
50+
token: "323daf3434098fabcbc",
51+
topics: ["update", "maintenance"]
52+
}
53+
},
54+
geofence: {
55+
version: "ORConsole",
56+
requiresPermission: true,
57+
hasPermission: true,
58+
enabled: true
59+
disabled: false
60+
}
61+
}
62+
}
63+
```
64+
If registration is successful then the server will return the saved console registration (including the id); which should be stored for future registration requests.
65+
66+
**N.B. the console registration is converted into an asset which is stored on the server inside the appropriate realm under an asset called 'Consoles' and if the client is authenticated then the console asset is linked with the authenticated user**
67+
68+
When the app specifies `consoleAutoEnable: false` then it is responsible for enabling each `provider` which allows the app to do things like wait until a user requests functionality provided by a provider before enabling it. When a providers status changes the `@openremote/core` component will automatically update the console registration on the server.
69+
70+
## App/console API
71+
### Client URL
72+
Console loads app with the following query parameters in the URL to override desired functionality and to inform the client about itself (ones in bold are required):
73+
74+
* **consoleName[string]** - Name of the console
75+
* **consoleVersion [string]** - Version of the console
76+
* **consolePlatform [string]** - Name of the platform
77+
* consoleProviders [string] - Space delimited list of providers that this console supports (see below for currently supported/standard providers)
78+
* consoleAutoEnable [boolean] - Whether `@openremote/core` should try and auto enable each provider (note that auto enabling cannot send any custom data to each provider during enabling and it also cannot do any processing on the responses received), for this reason it only really works on providers that don't require data during enabling.
79+
80+
#### Initialise
81+
For each provider the `@openremote/core` component sends a message asking the console to initialise the provider:
82+
```json
83+
{
84+
action: "PROVIDER_INIT",
85+
provider: "PROVIDER_NAME"
86+
}
87+
```
88+
The console then does any required initialisation and sends a message back to the app:
89+
```json
90+
{
91+
action: "PROVIDER_INIT",
92+
provider: "PROVIDER_NAME",
93+
version: "PROVIDER_VERSION",
94+
enabled: true|false [tells the app whether the provider is already enabled and therefore doesn't require enabling]
95+
disabled: true|false [tells the app whether the provider was previously disabled and therefore shouldn't be enabled]
96+
requiresPermission: true|false [tells the app whether user permission is required for this provider]
97+
hasPermission: true|false|null [tells the app whether permission has already been granted true=permission granted; false=permission denied; null=permission not yet requested]
98+
success: true|false [true=init success; false=init failure]
99+
}
100+
```
101+
If a provider initialisation call returns `success: false` then it is automatically marked as `disabled`, once all `providers` are initialised the `OREvent.CONSOLE_INIT` event is raised. The app can retrieve the `console` instance as described above and it can check the status of each `provider` and take appropriate action if desired.
102+
103+
#### Enable
104+
Once all providers are initialised then the app is free to decide when to enable each provider (if `consoleAutoEnable: false` otherwise they will be auto enabled); where a provider returned `requiresPermission=true && hasPermission=false` then the client is best placed to decide when and how to ask for permissions and should use good UX principles to avoid users denying such permission requests (see [permission-ux](https://developers.google.com/web/fundamentals/push-notifications/permission-ux)). Providers that don't require permissions or already have permissions could be enabled immediately. The enable message structure is:
105+
```json
106+
{
107+
action: "PROVIDER_ENABLE",
108+
provider: "PROVIDER_NAME",
109+
consoleId: "hhjfksdhf786382yrusd6f782",
110+
data: JSON [any data that the app wishes to pass to this provider that may be required for enabling it]
111+
}
112+
```
113+
The console then asks the user for the necessary permission(s) (if not done already) and enables the functionality of this provider then posts a message back to the app:
114+
```json
115+
{
116+
action: "PROVIDER_ENABLE",
117+
provider: "PROVIDER_NAME",
118+
hasPermission: true|false [true=user granted permission; false=user denied permission]
119+
success: true|false [true=enabled success; false=enabled failure]
120+
data: JSON [any data that the provider wishes to return to the app for use by the app and/or for sending to the server]
121+
}
122+
```
123+
#### Disable
124+
The app can disable a provider by sending the following message to the console:
125+
```json
126+
{
127+
action: "PROVIDER_DISABLE",
128+
provider: "PROVIDER_NAME"
129+
}
130+
```
131+
The console then does any required disabling of the provider and posts a message back to the app:
132+
```json
133+
{
134+
action: "PROVIDER_DISABLE",
135+
provider: "PROVIDER_NAME"
136+
}
137+
```
138+
#### Provider independence
139+
Some providers 'run' independently of the app in the background (e.g. push, geofence), providers can also communicate with each other where supported (e.g. push provider telling the geofence provider to refresh the geofences) how they do this is of no concern to the app.
140+
141+
As well as the standard messages above; the app can interact with individual providers using the provider's specific messages as described below.
142+
143+
144+
## Standard Providers
145+
### Push Provider (provider: "push")
146+
Allows data/notifications to be remotely pushed to the console. There are two types of standard push provider depending on the platform and the data sent and returned from the enable message depends on the type used:
147+
148+
### FCM Push (Android & iOS)
149+
* Supports silent (data only) push notifications
150+
* Supports topics
151+
152+
#### Enabled message request data (App -> Console)
153+
Array of topics to subscribe to (optional):
154+
```json
155+
{
156+
topics: ["update", "custom"]
157+
}
158+
```
159+
160+
#### Enabled message response data (Console -> App)
161+
```json
162+
{
163+
token: "23123213ad2313b0897efd",
164+
}
165+
```
166+
167+
### Web Push (Web Browsers)
168+
* No topic support (yet)
169+
* No silent (data only) push notifications
170+
171+
#### Enabled message request data (App -> Console)
172+
```
173+
NONE
174+
```
175+
176+
#### Enabled message response data (Console -> App)
177+
The data structure returned from the enabled message request is:
178+
```json
179+
{
180+
"endpoint": "https://some.pushservice.com/something-unique",
181+
"keys": {
182+
"p256dh": "BIPUL12DLfytvTajnryr2PRdAgXS3HGKiLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WAkAPIxr4gK0_dQds4yiI=",
183+
"auth":"FPssNDTKnInHVndSTdbKFw=="
184+
}
185+
}
186+
```
187+
188+
#### Received message (Console -> App)
189+
Called for both types when a push notification is received:
190+
```json
191+
{
192+
provider: "PROVIDER_NAME",
193+
action: "PUSH_RECEIVED",
194+
title: "Hello",
195+
text: "This is a push notification",
196+
data: JSON (data payload supplied with the push message),
197+
foreground: true|false (was notification received whilst console/client was in the foreground)
198+
coldStart: true|false (was the console/client started by clicking the notification)
199+
}
200+
```
201+
202+
### Geofence Provider (provider: "geofence")
203+
Use platform geofence APIs (Android and iOS); the provider expects a public endpoint on the OR manager at `rules/geofences/{consoleId}` which it can call to get the geofences for this console. The geofence definitions returned by this endpoint and the behaviour of this provider should match the definitions in the asset location tracking documentation.
204+
205+
#### Enabled message request data (App-> Console)
206+
```
207+
NONE
208+
```
209+
210+
#### Enabled message response data (Console -> App)
211+
```
212+
NONE
213+
```
214+
215+
#### Refresh message (App -> Console)
216+
Tell the provider to fetch the latest geofence definitions and to update its local geofences.
217+
```json
218+
{
219+
action: "GEOFENCE_REFRESH"
220+
}
221+
```
222+
223+
224+
### Storage Provider (provider: `storage`)
225+
Allows for storing data locally on the console, well known keys are:
226+
- `REFRESH_TOKEN` - Used to store offline refresh token for `keycloak` authentication (should only be stored in secure environment - not in the browser).
227+
228+
#### Enabled message request data (App-> Console)
229+
```
230+
NONE
231+
```
232+
233+
#### Enabled message response data (Console -> App)
234+
```
235+
NONE
236+
```
237+
238+
#### Store data message (App -> Console)
239+
Tell the provider to store the specified data.
240+
```json
241+
{
242+
action: "STORE",
243+
key: "DATA_KEY",
244+
value: JSON (set to null to remove the key from the store)
245+
}
246+
```
247+
248+
#### Retrieve data message request (App -> Console)
249+
Get data from the provider.
250+
```json
251+
{
252+
action: "RETRIEVE",
253+
key: "DATA_KEY"
254+
}
255+
```
256+
257+
#### Retrieve data message response (Console -> App)
258+
Returns the requested data from the provider.
259+
```json
260+
{
261+
action: "RETRIEVE",
262+
key: "DATA_KEY",
263+
value: JSON
264+
}
265+
```
266+
267+
268+
### TODO Notification Provider (provider: "notification")
269+
Show a notification immediately using the platforms standard mechanism (without using Push API)
270+
271+
#### Enabled message request data (App -> Console)
272+
No data
273+
274+
#### Enabled message response data (Console -> App)
275+
No data
276+
277+
#### Show message (App -> Console)
278+
The client can show a notification by sending the following message to the console:
279+
```json
280+
{
281+
action: "NOTIFICATION_SHOW",
282+
data: {
283+
id: 1,
284+
title: "Hello",
285+
text: "This is a notification message!",
286+
data: JSON (any data to pass to notification click handler)
287+
}
288+
```
289+
290+
#### Clicked message (Console -> App)
291+
The client can listen for notification click events by listening for the following messages:
292+
```json
293+
{
294+
action: "NOTIFICATION_CLICKED",
295+
title: "Hello",
296+
text: "This is a push notification",
297+
data: JSON (data payload supplied with the notification),
298+
}
299+
```
300+
301+
### QR Scanner Provider (provider: "qr")
302+
Open up a native view which enables the camera of the device to scan a QR code and send the content back to the app.
303+
304+
#### Enabled message request data (App -> Console)
305+
No data
306+
307+
#### Enabled message response data (Console -> App)
308+
No data
309+
310+
#### Scan QR Code (App -> Console)
311+
Start the camera and scan a QR code.
312+
```json
313+
{
314+
action: "SCAN_QR"
315+
}
316+
```
317+
#### Scan QR Code (Console -> App)
318+
```json
319+
{
320+
action: "SCAN_QR",
321+
provider: "qr",
322+
data: {
323+
result: <qr_content>
324+
}
325+
}
326+
```

0 commit comments

Comments
 (0)