@apocaliss92/scrypted-advanced-notifier 4.8.37 → 4.8.38
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/dist/plugin.zip +0 -0
- package/docs/INTERFACE_DESCRIPTORS_MIGRATION.md +184 -0
- package/package.json +26 -4
package/dist/plugin.zip
CHANGED
|
Binary file
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Migrazione da Webhook HTTP a Socket SDK con interfaceDescriptors
|
|
2
|
+
|
|
3
|
+
Piano per esporre i metodi Events App via **interfaceDescriptors** (come [@scrypted/llm](https://github.com/scryptedapp/llm)), eliminando le chiamate REST e usando solo la socket SDK.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Come funziona interfaceDescriptors (LLM plugin)
|
|
8
|
+
|
|
9
|
+
Dal [package.json dell'LLM](https://github.com/scryptedapp/llm/blob/main/package.json):
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"scrypted": {
|
|
14
|
+
"interfaces": ["DeviceProvider", "UserDatabase", ...],
|
|
15
|
+
"interfaceDescriptors": {
|
|
16
|
+
"UserDatabase": {
|
|
17
|
+
"name": "UserDatabase",
|
|
18
|
+
"methods": ["openDatabase"],
|
|
19
|
+
"properties": []
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- **interfaceDescriptors** dichiara interfacce custom con metodi e proprietà
|
|
27
|
+
- Il server Scrypted usa questi descrittori per esporre i metodi via RPC sulla socket
|
|
28
|
+
- Il client può chiamare `device.openDatabase()` invece di fare HTTP
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 2. Metodi Events App da esporre (handleEventsAppRequest)
|
|
33
|
+
|
|
34
|
+
| apimethod | payload | Note |
|
|
35
|
+
|-----------|---------|------|
|
|
36
|
+
| GetConfigs | — | |
|
|
37
|
+
| GetCamerasStatus | — | |
|
|
38
|
+
| GetEvents | fromDate, tillDate, limit, offset, sources, cameras, detectionClasses, eventSource, filter, groupingRange | |
|
|
39
|
+
| GetVideoclips | fromDate, tillDate, limit, offset, cameras, detectionClasses | |
|
|
40
|
+
| GetCameraDayData | deviceId, day | |
|
|
41
|
+
| GetClusteredDayData | deviceId, days, bucketMs, enabledClasses, classFilter | |
|
|
42
|
+
| GetClusterEvents | clusterId, deviceId, startMs, endMs | |
|
|
43
|
+
| GetArtifacts | deviceId, day | |
|
|
44
|
+
| GetLatestRuleArtifacts | deviceId, limit | |
|
|
45
|
+
| RemoteLog | level, message | |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 3. Modifiche al plugin advanced-notifier
|
|
50
|
+
|
|
51
|
+
### 3.1 package.json — aggiungere interfaceDescriptors
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"scrypted": {
|
|
56
|
+
"interfaces": ["Settings", "DeviceProvider", "MixinProvider", "HttpRequestHandler", "Videoclips", "LauncherApplication", "PushHandler"],
|
|
57
|
+
"interfaceDescriptors": {
|
|
58
|
+
"EventsAppApi": {
|
|
59
|
+
"name": "EventsAppApi",
|
|
60
|
+
"methods": [
|
|
61
|
+
"getConfigs",
|
|
62
|
+
"getCamerasStatus",
|
|
63
|
+
"getEvents",
|
|
64
|
+
"getVideoclips",
|
|
65
|
+
"getCameraDayData",
|
|
66
|
+
"getClusteredDayData",
|
|
67
|
+
"getClusterEvents",
|
|
68
|
+
"getArtifacts",
|
|
69
|
+
"getLatestRuleArtifacts",
|
|
70
|
+
"remoteLog"
|
|
71
|
+
],
|
|
72
|
+
"properties": []
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 3.2 utils.ts — costante interfaccia
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
export const EVENTS_APP_API_INTERFACE = "EventsAppApi";
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 3.3 main.ts — aggiungere interfaccia al data fetcher
|
|
86
|
+
|
|
87
|
+
In `onDeviceDiscovered` per DATA_FETCHER_NATIVE_ID:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
interfaces: [
|
|
91
|
+
ScryptedInterface.VideoClips,
|
|
92
|
+
ScryptedInterface.EventRecorder,
|
|
93
|
+
ScryptedInterface.Settings,
|
|
94
|
+
EVENTS_APP_API_INTERFACE, // <-- aggiungere
|
|
95
|
+
],
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 3.4 dataFetcher.ts — implementare EventsAppApi
|
|
99
|
+
|
|
100
|
+
La classe `AdvancedNotifierDataFetcher` deve implementare i metodi pubblici che mappano 1:1 con gli apimethod. Esempio:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
// EventsAppApi interface
|
|
104
|
+
async getConfigs(): Promise<{ cameras: ...; enabledDetectionSources: string[] }> {
|
|
105
|
+
const { statusCode, body } = await this.handleEventsAppRequest('GetConfigs', {});
|
|
106
|
+
if (statusCode !== 200) throw new Error(JSON.stringify(body));
|
|
107
|
+
return body as any;
|
|
108
|
+
}
|
|
109
|
+
async getCamerasStatus(): Promise<CamerasStatusResponse> { ... }
|
|
110
|
+
async getEvents(payload: GetEventsPayload): Promise<GetEventsResponse> { ... }
|
|
111
|
+
// ... etc
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Oppure, più pulito: estrarre la logica da `handleEventsAppRequest` in metodi dedicati e far sì che `handleEventsAppRequest` li chiami, così si evita duplicazione.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 4. Come il server Scrypted gestisce interfaceDescriptors
|
|
119
|
+
|
|
120
|
+
Il server Scrypted (koush/scrypted) legge `interfaceDescriptors` dal `package.json` del plugin. Quando un device dichiara un'interfaccia in `interfaces`, il server:
|
|
121
|
+
|
|
122
|
+
1. Verifica che l'interfaccia sia in `interfaceDescriptors` (per interfacce custom)
|
|
123
|
+
2. Espone i metodi via RPC sulla socket Engine.IO
|
|
124
|
+
3. Il client `@scrypted/client` può chiamare `device.getConfigs()` e la chiamata viene serializzata e inviata via socket
|
|
125
|
+
|
|
126
|
+
Non serve modificare il server: il supporto è già presente. Il client deve solo usare `client.systemManager.getDeviceById(deviceId)` e chiamare i metodi sull'oggetto restituito.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 5. Modifiche al client (camstack / scrypted-an-frontend)
|
|
131
|
+
|
|
132
|
+
### 5.1 Trovare il device Events App
|
|
133
|
+
|
|
134
|
+
Il device "Advanced notifier data fetcher" ha tipo `API` e implementa `EventsAppApi`. Per ottenere il suo ID:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
const state = client.systemManager.getSystemState();
|
|
138
|
+
const eventsAppDeviceId = Object.entries(state).find(
|
|
139
|
+
([_, d]) => (d as any)?.interfaces?.includes?.('EventsAppApi')
|
|
140
|
+
)?.[0];
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Oppure cercare per nome/tipo se lo stato lo espone.
|
|
144
|
+
|
|
145
|
+
### 5.2 Sostituire fetch con chiamate SDK
|
|
146
|
+
|
|
147
|
+
**Prima (HTTP):**
|
|
148
|
+
```ts
|
|
149
|
+
const res = await fetch(`${baseUrl}/eventsApp`, {
|
|
150
|
+
method: 'POST',
|
|
151
|
+
body: JSON.stringify({ apimethod: 'GetClusteredDayData', payload: { deviceId, days, bucketMs } }),
|
|
152
|
+
headers: { 'Content-Type': 'application/json', Authorization: getAuthHeader(auth) },
|
|
153
|
+
});
|
|
154
|
+
const data = await res.json();
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Dopo (Socket):**
|
|
158
|
+
```ts
|
|
159
|
+
const client = await getScryptedClient(auth);
|
|
160
|
+
const device = client.systemManager.getDeviceById(eventsAppDeviceId) as EventsAppApi;
|
|
161
|
+
const data = await device.getClusteredDayData({ deviceId, days, bucketMs });
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 5.3 Cosa resta su HTTP
|
|
165
|
+
|
|
166
|
+
- **URL di immagini/thumbnail/video**: usati in `<Image src={url} />` e `<Video source={{ uri }} />` — devono restare URL HTTP. Il plugin continua a servire `/eventThumbnail/...`, `/eventImage/...`, `/eventVideoclip/...` via HttpRequestHandler.
|
|
167
|
+
- **Autenticazione**: la socket SDK usa già le credenziali del client (login con username/password). Non serve più Basic auth per le chiamate dati.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 6. Ordine di implementazione
|
|
172
|
+
|
|
173
|
+
1. **Plugin**: aggiungere `interfaceDescriptors` e `EVENTS_APP_API_INTERFACE`, implementare i metodi su `AdvancedNotifierDataFetcher`
|
|
174
|
+
2. **Mantenere HttpRequestHandler**: per `apimethod` POST a `/eventsApp` — opzionale durante la transizione (fallback)
|
|
175
|
+
3. **Client**: creare `eventsAppSdk.ts` che usa la socket; `eventsAppApi.ts` può passare a usare l'SDK quando il client è connesso
|
|
176
|
+
4. **Rimuovere** le chiamate fetch a `/eventsApp` dal client una volta validato l'SDK
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 7. Riferimenti
|
|
181
|
+
|
|
182
|
+
- [LLM plugin package.json](https://github.com/scryptedapp/llm/blob/main/package.json) — esempio interfaceDescriptors
|
|
183
|
+
- [Scrypted Developer Docs](https://developer.scrypted.app/) — interfacce e plugin
|
|
184
|
+
- [@scrypted/client](https://www.npmjs.com/package/@scrypted/client) — SDK client con socket
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/apocaliss92/scrypted-advanced-notifier"
|
|
7
7
|
},
|
|
8
|
-
"version": "4.8.
|
|
8
|
+
"version": "4.8.38",
|
|
9
9
|
"scripts": {
|
|
10
10
|
"scrypted-setup-project": "scrypted-setup-project",
|
|
11
11
|
"prescrypted-setup-project": "scrypted-package-json",
|
|
@@ -49,9 +49,31 @@
|
|
|
49
49
|
"HttpRequestHandler",
|
|
50
50
|
"Videoclips",
|
|
51
51
|
"LauncherApplication",
|
|
52
|
-
"PushHandler"
|
|
52
|
+
"PushHandler",
|
|
53
|
+
"EventsAppApi"
|
|
53
54
|
],
|
|
54
|
-
"pluginDependencies": []
|
|
55
|
+
"pluginDependencies": [],
|
|
56
|
+
"interfaceDescriptors": {
|
|
57
|
+
"EventsAppApi": {
|
|
58
|
+
"name": "EventsAppApi",
|
|
59
|
+
"methods": [
|
|
60
|
+
"getConfigs",
|
|
61
|
+
"getCamerasStatus",
|
|
62
|
+
"getEvents",
|
|
63
|
+
"getVideoclips",
|
|
64
|
+
"getCameraDayData",
|
|
65
|
+
"getClusteredDayData",
|
|
66
|
+
"getClusterEvents",
|
|
67
|
+
"getArtifacts",
|
|
68
|
+
"getLatestRuleArtifacts",
|
|
69
|
+
"remoteLog",
|
|
70
|
+
"getAsset",
|
|
71
|
+
"getVideoClipThumbnailData",
|
|
72
|
+
"getVideoClipData"
|
|
73
|
+
],
|
|
74
|
+
"properties": []
|
|
75
|
+
}
|
|
76
|
+
}
|
|
55
77
|
},
|
|
56
78
|
"dependencies": {
|
|
57
79
|
"@scrypted/common": "file:../scrypted/common",
|
|
@@ -69,4 +91,4 @@
|
|
|
69
91
|
"@types/lodash": "^4.17.12",
|
|
70
92
|
"@types/node": "^20.11.0"
|
|
71
93
|
}
|
|
72
|
-
}
|
|
94
|
+
}
|