lavva.exalushome 2.0.110 → 2.0.113

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 (142) hide show
  1. package/README.md +356 -0
  2. package/build/exalushome-library-bundle.js +1 -1
  3. package/build/exalushome-library-bundle.js.map +1 -1
  4. package/build/js/Api.js +112 -112
  5. package/build/js/Api.js.map +1 -1
  6. package/build/js/AsyncLock.js +15 -15
  7. package/build/js/AsyncSemaphore.js +44 -44
  8. package/build/js/AsyncSemaphore.js.map +1 -1
  9. package/build/js/CancelationTokenSource.js +18 -18
  10. package/build/js/DataFrame.js +86 -86
  11. package/build/js/DependencyContainer.js +87 -87
  12. package/build/js/DependencyContainer.js.map +1 -1
  13. package/build/js/Event.js +24 -24
  14. package/build/js/Event.js.map +1 -1
  15. package/build/js/Guid.js +8 -8
  16. package/build/js/Helpers.js +132 -132
  17. package/build/js/Helpers.js.map +1 -1
  18. package/build/js/IDIService.js +1 -1
  19. package/build/js/INetworkService.js +41 -41
  20. package/build/js/Services/AppStateService.js +217 -217
  21. package/build/js/Services/AppStateService.js.map +1 -1
  22. package/build/js/Services/Chat/ChatImplementations/ControllerChat/ControllerChat.js +224 -224
  23. package/build/js/Services/Chat/ChatImplementations/ControllerChat/ControllerChat.js.map +1 -1
  24. package/build/js/Services/Chat/ChatImplementations/ControllerChat/IControllerChat.js +33 -33
  25. package/build/js/Services/Chat/ChatImplementations/FamillyChat/FamillyChat.js +147 -147
  26. package/build/js/Services/Chat/ChatImplementations/FamillyChat/FamillyChat.js.map +1 -1
  27. package/build/js/Services/Chat/ChatImplementations/FamillyChat/IFamillyChat.js +1 -1
  28. package/build/js/Services/Chat/ChatImplementations/GptChat/GptChat.js +184 -184
  29. package/build/js/Services/Chat/ChatImplementations/GptChat/GptChat.js.map +1 -1
  30. package/build/js/Services/Chat/ChatImplementations/GptChat/IGptChat.js +26 -26
  31. package/build/js/Services/Chat/ChatService.js +43 -43
  32. package/build/js/Services/Chat/ChatService.js.map +1 -1
  33. package/build/js/Services/Chat/IChatService.js +6 -6
  34. package/build/js/Services/Controller/ConnectedAppsService.js +117 -117
  35. package/build/js/Services/Controller/ConnectedAppsService.js.map +1 -1
  36. package/build/js/Services/Controller/ControllerConfigurationService.js +319 -319
  37. package/build/js/Services/Controller/ControllerConfigurationService.js.map +1 -1
  38. package/build/js/Services/Controller/ControllerExtensionsService.js +148 -148
  39. package/build/js/Services/Controller/ControllerExtensionsService.js.map +1 -1
  40. package/build/js/Services/Controller/FindControllerService.js +155 -155
  41. package/build/js/Services/Controller/FindControllerService.js.map +1 -1
  42. package/build/js/Services/Controller/GeolocationService.js +111 -111
  43. package/build/js/Services/Controller/GeolocationService.js.map +1 -1
  44. package/build/js/Services/Controller/IConnectedAppsService.js +24 -24
  45. package/build/js/Services/Controller/IControllerConfigurationService.js +1 -1
  46. package/build/js/Services/Controller/IControllerExtensionsService.js +1 -1
  47. package/build/js/Services/Controller/IGeolocationService.js +20 -20
  48. package/build/js/Services/DataMigrationService.js +169 -169
  49. package/build/js/Services/DataMigrationService.js.map +1 -1
  50. package/build/js/Services/Devices/ChannelsGroupsService.js +696 -696
  51. package/build/js/Services/Devices/ChannelsGroupsService.js.map +1 -1
  52. package/build/js/Services/Devices/Device.js +248 -248
  53. package/build/js/Services/Devices/Device.js.map +1 -1
  54. package/build/js/Services/Devices/DeviceChannel.js +304 -304
  55. package/build/js/Services/Devices/DeviceChannel.js.map +1 -1
  56. package/build/js/Services/Devices/DevicesService.js +1184 -1184
  57. package/build/js/Services/Devices/DevicesService.js.map +1 -1
  58. package/build/js/Services/Devices/IChannelsGroupsService.js +109 -109
  59. package/build/js/Services/Devices/IChannelsGroupsService.js.map +1 -1
  60. package/build/js/Services/Devices/IDevice.js +197 -197
  61. package/build/js/Services/Devices/IDeviceChannel.js +48 -48
  62. package/build/js/Services/Devices/IDeviceConfigService.js +1 -1
  63. package/build/js/Services/Devices/IDeviceState.d.ts +7 -1
  64. package/build/js/Services/Devices/IDeviceState.js +970 -963
  65. package/build/js/Services/Devices/IDeviceState.js.map +1 -1
  66. package/build/js/Services/Devices/IDeviceTask.js +36 -36
  67. package/build/js/Services/Devices/IDevicesService.js +9 -9
  68. package/build/js/Services/Devices/IManuallyPairedDevicesProtocolService.js +1 -1
  69. package/build/js/Services/Devices/IManuallyPairedDevicesService.js +1 -1
  70. package/build/js/Services/Devices/ManuallyPairedDevicesService.js +68 -68
  71. package/build/js/Services/Devices/ManuallyPairedDevicesService.js.map +1 -1
  72. package/build/js/Services/Devices/TaskExecutionResult.js +9 -9
  73. package/build/js/Services/Devices/Tasks/DeviceTask.js +42 -42
  74. package/build/js/Services/Devices/Tasks/Tasks.js +216 -216
  75. package/build/js/Services/Devices/dist/DevicesService.d.ts +17 -17
  76. package/build/js/Services/ExalusConnectionService.js +498 -498
  77. package/build/js/Services/ExalusConnectionService.js.map +1 -1
  78. package/build/js/Services/FieldChangeResult.js +51 -51
  79. package/build/js/Services/IAppStateService.js +66 -66
  80. package/build/js/Services/IExalusConnectionService.js +31 -31
  81. package/build/js/Services/ILocalStorageService.js +1 -1
  82. package/build/js/Services/IRemoteStorageService.js +8 -8
  83. package/build/js/Services/LocalNetworkExalusConnectionService.js +289 -289
  84. package/build/js/Services/LocalNetworkExalusConnectionService.js.map +1 -1
  85. package/build/js/Services/LocalStorageService.js +38 -38
  86. package/build/js/Services/LocalStorageService.js.map +1 -1
  87. package/build/js/Services/Logging/ILoggerService.js +8 -8
  88. package/build/js/Services/Logging/LoggerService.js +132 -132
  89. package/build/js/Services/Logging/LoggerService.js.map +1 -1
  90. package/build/js/Services/PictureInPicture.js +28 -28
  91. package/build/js/Services/PictureInPicture.js.map +1 -1
  92. package/build/js/Services/Pictures/IPicture.js +6 -6
  93. package/build/js/Services/Pictures/IPicturesService.js +1 -1
  94. package/build/js/Services/Pictures/Picture.js +50 -50
  95. package/build/js/Services/Pictures/PicturesService.js +441 -441
  96. package/build/js/Services/Pictures/PicturesService.js.map +1 -1
  97. package/build/js/Services/RemoteStorageService.js +122 -122
  98. package/build/js/Services/RemoteStorageService.js.map +1 -1
  99. package/build/js/Services/Scenes/IScenesService.js +7 -7
  100. package/build/js/Services/Scenes/LeftArgumentTypes.js +166 -166
  101. package/build/js/Services/Scenes/LeftArgumentTypes.js.map +1 -1
  102. package/build/js/Services/Scenes/SceneTaskTypes.js +32 -32
  103. package/build/js/Services/Scenes/Scenes.js +134 -134
  104. package/build/js/Services/Scenes/ScenesBuilder.js +1097 -1097
  105. package/build/js/Services/Scenes/ScenesBuilder.js.map +1 -1
  106. package/build/js/Services/Scenes/ScenesService.js +1131 -1131
  107. package/build/js/Services/Scenes/ScenesService.js.map +1 -1
  108. package/build/js/Services/Scenes/dist/ScenesService.d.ts +5 -5
  109. package/build/js/Services/Session/ISessionService.js +8 -8
  110. package/build/js/Services/Session/SessionService.js +222 -222
  111. package/build/js/Services/Session/SessionService.js.map +1 -1
  112. package/build/js/Services/StatesHistory/IStatesHistoryService.js +12 -12
  113. package/build/js/Services/StatesHistory/StatesHistory.js +75 -75
  114. package/build/js/Services/StatesHistory/StatesHistoryService.js +235 -235
  115. package/build/js/Services/StatesHistory/StatesHistoryService.js.map +1 -1
  116. package/build/js/Services/SupportedDevices/ISupportedDevicesService.js +115 -115
  117. package/build/js/Services/SupportedDevices/SupportedDevicesService.js +26 -26
  118. package/build/js/Services/Updates/CustomUpdateActions/ICustomUpdateActions.js +1 -1
  119. package/build/js/Services/Updates/IUpdateInfo.js +62 -62
  120. package/build/js/Services/Updates/IUpdatesProvider.js +48 -48
  121. package/build/js/Services/Updates/IUpdatesService.js +139 -139
  122. package/build/js/Services/Updates/UpdateProviderServices/IControllerModulesUpdatesProviderService.js +1 -1
  123. package/build/js/Services/Updates/UpdateProviderServices/IDeviceUpdateProviderService.js +1 -1
  124. package/build/js/Services/Updates/UpdateProviderServices/IUpdateProviderService.js +1 -1
  125. package/build/js/Services/Updates/UpdatesProvider.js +212 -212
  126. package/build/js/Services/Updates/UpdatesProvider.js.map +1 -1
  127. package/build/js/Services/Updates/UpdatesService.js +1487 -1487
  128. package/build/js/Services/Updates/UpdatesService.js.map +1 -1
  129. package/build/js/Services/Updates/dist/UpdatesService.d.ts +9 -9
  130. package/build/js/Services/Users/IUser.js +21 -21
  131. package/build/js/Services/Users/IUsersService.js +1 -1
  132. package/build/js/Services/Users/User.js +104 -104
  133. package/build/js/Services/Users/UsersService.js +302 -302
  134. package/build/js/Services/Users/UsersService.js.map +1 -1
  135. package/build/js/Services/WebApi/IWebApiCacheService.js +1 -1
  136. package/build/js/Services/WebApi/WebApiCacheService.js +42 -42
  137. package/build/js/Services/WebApi/WebApiCacheService.js.map +1 -1
  138. package/build/js/TypedEvent.js +23 -23
  139. package/build/js/TypedEvent.js.map +1 -1
  140. package/build/js/dist/Api.d.ts +12 -12
  141. package/build/tsconfig.tsbuildinfo +1 -1
  142. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,356 @@
1
+ # ExalusHome library for Lavva
2
+
3
+ ## Library installation:
4
+ If you want to use this library in any JavaScript or TypeScript project you can use npm to install it as package from npm repository.
5
+ For that you will have to use command:
6
+ ```
7
+ npm install lavva.exalushome
8
+ ```
9
+ or
10
+ ```
11
+ yarn add lavva.exalushome
12
+ ```
13
+
14
+ ## Initialization:
15
+ If you have installed this package then you have to initialize this library first before usage. To do this, you have to call:
16
+ ```typescript
17
+ import { Api } from 'lavva.exalushome';
18
+ const api = Api.Init();
19
+ ```
20
+
21
+ ## Getting services:
22
+ This library implements controller APIs as a group of services that implement different functionalities.
23
+ Currently we have services as:
24
+ ```ts
25
+ IExalusConnectionService
26
+ IDevicesService
27
+ ILocalStorageService
28
+ IWebApiCacheService
29
+ IUsersService
30
+ ISessionService
31
+ ILoggerService
32
+ IControllerConfigurationService
33
+ IChannelsGroupsService
34
+ IRemoteStorageService
35
+ ...
36
+ ```
37
+
38
+ To get any service that is registered in dependency container you can use:
39
+ ```typescript
40
+ const api = Api.Get<TInterface>(ServiceClassName);
41
+
42
+ //ex:
43
+ import { LoggerService } from 'lavva.exalushome/build/js/Services/Logging/LoggerService';
44
+ import { ILoggerService } from 'lavva.exalushome/build/js/Services/Logging/ILoggerService';
45
+ const logger = Api.Get<ILoggerService>(LoggerService.ServiceName);
46
+ ```
47
+ Where as generic T parameter you have to put the iterface that is used by given service and as the (ServiceClassName) parameter you have to put the reference (name) of service that you want to use.
48
+
49
+ ## IExalusConnectionService
50
+ This service allows us to connect to any controller using cloud connection (in future it will implement local communication too) and call controller APIs.
51
+ All calls to APIs are asynchronous and can be done concurently.
52
+ They can be executed out of order depending on the time when given API was called and how fast it can be handled by controller and devices.
53
+ It is a good practice to wait asynchronously for api call execution.
54
+
55
+ If you want to connect to controller you have to take service from dependency container and call method with controller serial number and PIN.
56
+ ```typescript
57
+ import { Api } from 'lavva.exalushome';
58
+ import { ExalusConnectionService } from 'lavva.exalushome/build/js/ExalusConnectionService';
59
+ import { AuthorizationInfo, IExalusConnectionService } from 'lavva.exalushome/build/js/IExalusConnectionService';
60
+ import { ILoggerService } from 'lavva.exalushome/build/js/Services/Logging/ILoggerService';
61
+ import { LoggerService } from 'lavva.exalushome/build/js/Services/Logging/LoggerService';
62
+
63
+ /// get logger service
64
+ const log = Api.Get<ILoggerService>(LoggerService.ServiceName);
65
+
66
+ /// get exalus connection service
67
+ const connection = Api.Get<IExalusConnectionService>(ExalusConnectionService.ServiceName);
68
+
69
+ /// subscribe to connection state changed event
70
+ connection.OnConnectionStateChangedEvent().Subscribe(state => log.Info(`Connection state has changed to: ${state}`));
71
+
72
+ /// connnect to controller and authorize
73
+ const result = await connection.ConnectAndAuthorizeAsync(new AuthorizationInfo(serial, pin));
74
+ log.Info(`Connection and authorization result: ${result}`);
75
+
76
+ /// check connection and authorization result
77
+ if (result != ConnectionResult.Connected) {
78
+ log.Error("Failed to connect to controller!");
79
+ return;
80
+ }
81
+
82
+ log.Info("Connected to controller!");
83
+ ```
84
+
85
+ ## ISessionService
86
+ This service represents the current app session and has reference to currently logged in user (if any is currently logged in) and can login or logout user.
87
+ There are two events that you can subsribe to if you want to know when user is logged in or logged out. User can be logged out by controller so it should be handled.
88
+
89
+ ```typescript
90
+ import { ISessionService, LoginError } from 'lavva.exalushome/build/js/Services/Session/ISessionService';
91
+ import { SessionService } from 'lavva.exalushome/build/js/Services/Session/SessionService';
92
+
93
+ /// get session service
94
+ const session = Api.Get<ISessionService>(SessionService.ServiceName);
95
+ session.OnUserLoggedOutEvent().Subscribe(user => log.Info(`User logged out from controller!`));
96
+ session.OnUserLoggedInEvent().Subscribe(user => log.Info(`User logged in to controller`));
97
+
98
+ /// login user
99
+ const loginResult = await session.UserLogInAsync("installator@installator", "QT54K96X3P9299");
100
+
101
+ /// check login result
102
+ if (loginResult instanceof User) {
103
+ log.Info(SessionService, `logged in as ${loginResult.Name} ${loginResult.Surname} email: ${loginResult.Email}`);
104
+ }
105
+ else
106
+ log.Error(SessionService, `Failed to login, error code: ${loginResult}`);
107
+ ```
108
+
109
+ ### IUsersService
110
+ This service allows us to manage users registered in controller. You can take users list, delete them, create or update.
111
+
112
+ ```typescript
113
+ /// get users
114
+ const usersApi = Api.Get<IUsersService>(UsersService.ServiceName);
115
+ const users = await usersApi.GetUsersAsync();
116
+ users.forEach(user => log.Info(`User: ${user.Email}`));
117
+ ```
118
+
119
+ ## IDevicesService
120
+ This service allows us to manage and control devices.
121
+
122
+ Getting DevicesService:
123
+ ```typescript
124
+ const devicesApi = Api.Get<IDevicesService>(DevicesService.ServiceName);
125
+ await devicesApi.WaitForSynchronizationAsync();
126
+ ```
127
+
128
+ Getting devices list:
129
+ ```typescript
130
+ const devices = await devicesApi.GetDevicesAsync();
131
+ devices.forEach(device => {
132
+ log.Info(`[DEVICE] Name: ${device.Name} Guid: ${device.Guid}`);
133
+ device.AvailableTaskTypes.forEach(task => log.Info(` Task type: ${task.InterfaceType} enum type: ${task.Type}`));
134
+ device.AvailableResponseTypes.forEach(resp => log.Info(` Response type: ${resp.InterfaceType} enum type: ${resp.Type}`));
135
+ device.Channels.forEach(ch => {
136
+ log.Info(` Channel: ${ch.Name} num: ${ch.Number}`);
137
+ ch.AvailableTaskTypes.forEach(task => log.Info(` Task type: ${task.InterfaceType} enum type: ${task.Type}`));
138
+ ch.AvailableResponseTypes.forEach(resp => log.Info(` Response type: ${resp.InterfaceType} enum type: ${resp.Type}`));
139
+ });
140
+ });
141
+ ```
142
+
143
+ Subscribing to device state changes:
144
+ ```typescript
145
+ let onStateChange = (stateChange: IDeviceState<any>) => log.Info(`[DEVICE][STATE CHANGED] changed DeviceGuid: ${device.Guid} Name: ${device.Name} \nstate: ${stateChange.TypeAsEnum}"`);
146
+ device.OnDeviceStateChangedEvent().Subscribe(onStateChange);
147
+ ```
148
+
149
+ Canceling subscription to device state changes:
150
+ ```typescript
151
+ device.OnDeviceStateChangedEvent().Unsubscribe(onStateChange);
152
+ ```
153
+
154
+ Monitoring tasks execution on devices:
155
+ ```typescript
156
+ devicesApi.OnDevicesTasksExecutionChangeEvent().Subscribe(tasks => {
157
+ tasks.forEach(task => log.Info(`Executing tasks on device: ${task.DeviceGuid} channel: ${task.Channel} status: ${task.Status}`));
158
+ });
159
+ ```
160
+
161
+ Searching for devices:
162
+ ```typescript
163
+ devicesApi.OnDeviceFoundEvent().Subscribe(device => log.Info(`Found new device ${device.Name}`));
164
+ await devicesApi.FindDevicesAsync();
165
+ const foundDevices = await devicesApi.GetFoundDevicesAsync();
166
+ ```
167
+
168
+ Registering found devices:
169
+ ```typescript
170
+ foundDevices.forEach(async device => {
171
+ log.Warning(`Found device: ${device.Name}`);
172
+ switch (await devicesApi.RegisterDeviceAsync(device)) {
173
+ case DeviceTaskExecutionResult.Executed:
174
+ log.Warning(`Device ${device.Name} has been successfully registered!`);
175
+ break;
176
+
177
+ case DeviceTaskExecutionResult.Failed:
178
+ log.Error(`Failed to register device: ${device.Name}`);
179
+ break;
180
+
181
+ case DeviceTaskExecutionResult.ControllerResponseTimeout:
182
+ log.Error(`Controller response timeout, unknown status of device: ${device.Name}`);
183
+ break;
184
+
185
+ case DeviceTaskExecutionResult.DeviceResponseTimeout:
186
+ log.Error(`Device response timeout, unknown status of device: ${device.Name}`);
187
+ break;
188
+ }
189
+ });
190
+ ```
191
+
192
+ Turning on light on first channel on first device that can be turned on:
193
+ ```typescript
194
+ (await devicesApi.GetDevicesAsync()).first(device => device.Channels.any(channel => channel.AvailableTaskTypes.any(a => a.Type === DeviceTaskType.TurnOn && channel.Number === 1)))
195
+ .Channels.first(channel => channel.Number === 1)
196
+ .ExecuteTaskAsync(new TurnOn());
197
+
198
+ /// alternatively you can use
199
+ let task = new TurnOn();
200
+ task.Channel = 1;
201
+ devicesApi.ExecuteDeviceTaskAsync(device, task);
202
+ ```
203
+ Turning off light on first channel on first device that can be turned on:
204
+ ```typescript
205
+ (await devicesApi.GetDevicesAsync()).first(device => device.Channels.any(channel => channel.AvailableTaskTypes.any(a => a.Type === DeviceTaskType.TurnOff && channel.Number === 1)))
206
+ .Channels.first(channel => channel.Number === 1)
207
+ .ExecuteTaskAsync(new TurnOff());
208
+ ```
209
+
210
+ Turning on all channels on devices that can be turned on:
211
+ ```typescript
212
+ (await devicesApi.GetDevicesAsync()).forEach(device => {
213
+ device.Channels.forEach(async channel => {
214
+ if (channel.AvailableTaskTypes.any(a => a.Type === DeviceTaskType.TurnOn)) {
215
+ let task = new TurnOn();
216
+ task.Channel = channel.Number;
217
+ tasks.push([device, task]);
218
+ }
219
+ });
220
+ });
221
+
222
+ let result = await devicesApi.ExecuteDevicesTasksAsync(tasks);
223
+ result.forEach(response => {
224
+ switch (response.Result) {
225
+ case DeviceTaskExecutionResult.Executed:
226
+ log.Info(`Turned on device: ${response.Device?.Name} on channel: ${response.Task?.Channel}`);
227
+ break;
228
+
229
+ case DeviceTaskExecutionResult.DeviceResponseTimeout:
230
+ log.Warning(`Failed to turn on device: ${response.Device?.Name} on channel: ${response.Task?.Channel}, device response timeout occurred`);
231
+ break;
232
+
233
+ case DeviceTaskExecutionResult.ControllerResponseTimeout:
234
+ log.Warning(`Unknown device state: ${response.Device?.Name} on channel: ${response.Task?.Channel}, controller response timeout occurred`);
235
+ break;
236
+
237
+ case DeviceTaskExecutionResult.Failed:
238
+ log.Error(`Error uccured when tried to turn on device: ${response.Device?.Name} on channel: ${response.Task?.Channel}`);
239
+ break;
240
+ }
241
+ });
242
+ ```
243
+
244
+ Enabling fast devices states synchronization:
245
+ ```typescript
246
+ await devices.EnableFastStatesSyncAsync();
247
+ ```
248
+
249
+ Disabling fast devices states synchronization:
250
+ ```typescript
251
+ await devices.DisableFastStatesSyncAsync();
252
+ ```
253
+
254
+ Checking if fast states synchronization is enabled:
255
+ ```await devices.IsFastStatesSyncEnabledAsync();```
256
+
257
+ ## IControllerConfigurationService
258
+ This service allows us to manage, control and monitor controller configuration.
259
+
260
+ Getting IControllerConfigurationService:
261
+ ```typescript
262
+ const controllerConfigurationApi = Api.Get<IControllerConfigurationService>(ControllerConfigurationService.ServiceName);
263
+ ```
264
+
265
+ Monitoring controller configuration changes:
266
+ ```typescript
267
+ controllerConfigurationApi.OnConfigurationTimeCheckedEvent().Subscribe(date => log.Warning(`Controller configuration time changed: ${date}`));
268
+ controllerConfigurationApi.OnEnteredConfigurationEvent().Subscribe(() => log.Warning(`Controller entered configuration mode`));
269
+ controllerConfigurationApi.OnExitedConfigurationEvent().Subscribe(() => log.Warning(`Controller exited configuration mode`));
270
+ ```
271
+
272
+ Entering configuration mode:
273
+ ```typescript
274
+ await controllerConfigurationApi.EnterConfigurationModeAsync();
275
+ ```
276
+ Exiting configuration mode:
277
+ ```typescript
278
+ await controllerConfigurationApi.ExitConfigurationModeAsync();
279
+ ```
280
+
281
+ Check if configuration has changed in comparison to the last known konfiguration by this app instance:
282
+ ```typescript
283
+ if (await controllerConfigurationApi.DidCofigurationChangeAsync())
284
+ log.Warning(`Controller configuration has changed! ${await controllerConfigurationApi.GetLastConfigurationChangeTimeAsync()}`);\
285
+ else
286
+ log.Debug("Controller configuration did not change!");
287
+ ```
288
+
289
+ ## IChannelsGroupsService
290
+ This service allows us to control devices channels groups.
291
+
292
+ Getting IChannelsGroupsService:
293
+ ```typescript
294
+ const groupsApi = Api.Get<IChannelsGroupsService>(ChannelsGroupsService.ServiceName);
295
+ await groupsApi.WaitForSynchronizationAsync(); // good to use one time after user logs in.
296
+ ```
297
+
298
+ Getting groups:
299
+ ```typescript
300
+ let groups = await groupsApi.GetGroupsAsync();
301
+ groups.forEach(group => log.Info(`Group: ${group.Name} guid: ${group.Guid}`));
302
+ ```
303
+
304
+ Removing group:
305
+ ```typescript
306
+ await groupsApi.RemoveGroupAsync(groups.first(a => a.Name === "TEST"));
307
+ ```
308
+
309
+ Creating new group:
310
+ ```typescript
311
+ let gr = new ChannelsGroup();
312
+ gr.Name = "TEST";
313
+ await groupsApi.AddNewGroupAsync(gr);
314
+ ```
315
+
316
+ Adding device channel to group:
317
+ ```typescript
318
+ await groupsApi.AddDeviceChannelToGroupAsync((await devicesApi.GetDevicesAsync()).first().Channels.first(), gr);
319
+ ```
320
+ ## IRemoteStorageService
321
+ This service allows application to store data (whatever it want's to store) in similar way like Local Storage in JavaScript but this data is not stored locally in browser but it is stored on Exalus Home controller. It can be then synchronized between app instances and retrieved or updated by app. It allows to store data in context of given logged in user or as global database that can be retrieved and modified by anyone. If it is stored in context of user then only the user that created given database can access it. You can have similar databases with same name for each user in the system and given user will be able to modify only it's own database.
322
+
323
+ Getting service instance:
324
+ ```typescript
325
+ const remoteStorage = Api.Get<IRemoteStorageService>(RemoteStorageService.ServiceName);
326
+ ```
327
+
328
+ Saving data globally accessible by every user:
329
+ ```typescript
330
+ await remoteStorage.SaveAsync("data_unique_id", true, "some data that can be an object or array too");
331
+ ```
332
+
333
+ Saving data for user that is logged in:
334
+ ```typescript
335
+ await remoteStorage.SaveAsync("data_unique_id", false, "some data that can be an object or array too; in context of user");
336
+ ```
337
+
338
+ Retrieving data that has global access:
339
+ ```typescript
340
+ await remoteStorage.ReadAsync<boolean>("data_unique_id", true, false)
341
+ ```
342
+
343
+ Retrieving data for user that is logged in:
344
+ ```typescript
345
+ await remoteStorage.ReadAsync<boolean>("data_unique_id", false, false)
346
+ ```
347
+
348
+ Removing global data (it only works on the newest controller software, older version don't have that capability but all will have it after update):
349
+ ```typescript
350
+ await remoteStorage.RemoveAsync("data_unique_id", true)
351
+ ```
352
+
353
+ Removing user data (it only works on the newest controller software, older version don't have that capability but all will have it after update):
354
+ ```typescript
355
+ await remoteStorage.RemoveAsync("data_unique_id", false)
356
+ ```