node-red-contrib-mobius-flow-base 2.5.90 → 3.0.0-beta.12

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 (39) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +16 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +16 -0
  3. package/.github/ISSUE_TEMPLATE/general.md +7 -0
  4. package/.github/workflows/build_publish.yml +80 -0
  5. package/README.md +4 -10
  6. package/dist/engine-api-calls.d.ts +18 -0
  7. package/dist/engine-api-calls.js +214 -0
  8. package/dist/engine-api-client.d.ts +7 -0
  9. package/dist/engine-api-client.js +92 -0
  10. package/dist/engine-websocket.d.ts +58 -0
  11. package/dist/engine-websocket.js +226 -0
  12. package/dist/node-red-ui-funcs.js +180 -0
  13. package/dist/nodes/common/mobsearch.js +576 -0
  14. package/dist/nodes/mobius-clear-resource.html +22 -3
  15. package/dist/nodes/mobius-clear-resource.js +17 -12
  16. package/dist/nodes/mobius-connection.html +30 -8
  17. package/dist/nodes/mobius-connection.js +194 -85
  18. package/dist/nodes/mobius-discover-object-list.html +185 -126
  19. package/dist/nodes/mobius-discover-object-list.js +27 -8
  20. package/dist/nodes/mobius-discover.js +7 -7
  21. package/dist/nodes/mobius-filter-by-rid-value.html +57 -41
  22. package/dist/nodes/mobius-filter-by-rid-value.js +38 -31
  23. package/dist/nodes/mobius-flow-inject.html +32 -2
  24. package/dist/nodes/mobius-get-multi-object.html +39 -5
  25. package/dist/nodes/mobius-get-multi-resource.html +36 -4
  26. package/dist/nodes/mobius-get-multi-resource.js +13 -12
  27. package/dist/nodes/mobius-get-object.html +25 -3
  28. package/dist/nodes/mobius-get-object.js +12 -9
  29. package/dist/nodes/mobius-get-resource.html +26 -3
  30. package/dist/nodes/mobius-get-resource.js +17 -12
  31. package/dist/nodes/mobius-object-cov.html +27 -3
  32. package/dist/nodes/mobius-object-cov.js +9 -6
  33. package/dist/nodes/mobius-resource-cov.html +23 -3
  34. package/dist/nodes/mobius-resource-cov.js +5 -5
  35. package/dist/nodes/mobius-set-multi-resource.html +24 -3
  36. package/dist/nodes/mobius-set-multi-resource.js +9 -11
  37. package/dist/nodes/mobius-set-resource.html +24 -3
  38. package/package.json +13 -7
  39. package/dist/nodes/node-red-ui-discover-devices.js +0 -103
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: 🐞 Bug report
3
+ about: Create a report to help us improve
4
+ title: '🐞 [Bug]: '
5
+ labels: 'bug'
6
+ assignees: ''
7
+ ---
8
+
9
+ **Remember to include**
10
+
11
+ - Customer
12
+ - Software version
13
+ - Where it was running (Cloud, balena, customer's own infra etc)
14
+ - A good description of the bug and how to reproduce it
15
+ - An estimate of the time to fix
16
+ - Any other repos that may be affected
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: ✨ Feature request
3
+ about: Suggest an idea for this project
4
+ title: '✨ [Feature]: '
5
+ labels: 'enhancement'
6
+ assignees: ''
7
+ ---
8
+
9
+ **Remember to include**
10
+
11
+ - Customer
12
+ - The reason for the new feature
13
+ - A good description of the new feature
14
+ - Any alternatives you have considered
15
+ - An estimate of the time to fix
16
+ - Any other repos that may be affected
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: 🔖 General issue
3
+ about: Any issue that is not a bug or feature request.
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+ ---
@@ -0,0 +1,80 @@
1
+ name: Build and Publish
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - v*.*.*
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v3
14
+
15
+ - name: Get tag
16
+ id: source_tag
17
+ run: |
18
+ echo "SOURCE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
19
+
20
+ - name: Get package version
21
+ id: source_ver
22
+ run: |
23
+ echo "SOURCE_VER=v$(grep version ./package.json | sed -n 's/^.*"\([0-9][^"]*\)".*$/\1/p')" >> $GITHUB_OUTPUT
24
+
25
+ - name: Do tag and version match?
26
+ if: steps.source_tag.outputs.SOURCE_TAG != steps.source_ver.outputs.SOURCE_VER
27
+ run: |
28
+ echo ${{ steps.source_tag.outputs.SOURCE_TAG }}
29
+ echo ${{ steps.source_ver.outputs.SOURCE_VER }}
30
+ echo "::error Tag does not match version"
31
+ exit -1
32
+
33
+ - name: Setup node
34
+ uses: actions/setup-node@v3
35
+ with:
36
+ node-version: '16.x'
37
+ registry-url: 'https://registry.npmjs.org'
38
+ always-auth: true
39
+
40
+ - name: Build
41
+ run: |
42
+ npm install -g yarn
43
+ yarn install
44
+ tsc && mkdir -p dist/nodes
45
+ cp src/nodes/*.js dist/nodes/
46
+ cp src/nodes/*.html dist/nodes/
47
+ cp -r src/nodes/icons dist/nodes/
48
+ mkdir -p dist/nodes/common
49
+ cp src/mobsearch.js dist/nodes/common/
50
+ cp src/node-red-ui-funcs.js dist/
51
+ env:
52
+ GH_PKG_READ_TOKEN: ${{ secrets.GH_PKG_READ_TOKEN }}
53
+
54
+ - name: Publish package
55
+ run: |
56
+ npm publish
57
+ env:
58
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_WRITE_TOKEN }}
59
+
60
+ - name: Create release
61
+ env:
62
+ RELEASE_TYPE: ${{ contains(steps.source_ver.outputs.SOURCE_VER, '-') }}
63
+ RELEASE_TAG: ${{ steps.source_ver.outputs.SOURCE_VER }}
64
+ uses: actions/github-script@v6
65
+ with:
66
+ github-token: ${{ secrets.MOBIUS_ACTION_TOKEN }}
67
+ script: |
68
+ try {
69
+ await github.rest.repos.createRelease({
70
+ draft: false,
71
+ generate_release_notes: true,
72
+ name: process.env.RELEASE_TAG,
73
+ owner: context.repo.owner,
74
+ prerelease: process.env.RELEASE_TYPE === 'true',
75
+ repo: context.repo.repo,
76
+ tag_name: process.env.RELEASE_TAG,
77
+ });
78
+ } catch (error) {
79
+ core.setFailed(error.message);
80
+ }
package/README.md CHANGED
@@ -1,16 +1,10 @@
1
1
  # node-red-contrib-mobius-flow-base
2
- ![Version](https://img.shields.io/badge/Version-v1.0.12-blue.svg)
3
2
 
4
- Copyright 2016 [Interior Automation](http://www.interior-automation.co.uk) under the BSD-3-Clause license.
3
+ Copyright 2016 [iaconnects](http://www.iaconnects.co.uk).
5
4
 
6
- [Node-RED](http://nodered.org) nodes to interact with Interior Automation's MOBiUS Flow.
5
+ [Node-RED](http://nodered.org) nodes to interact with MOBiUSFlow.
7
6
 
8
- ## Install
9
- Run the following command in the root directory of your Node-RED install:
10
-
11
- ```npm install node-red-contrib-mobius-flow-base```
12
-
13
- This module currently requires access to Interior Automation's private NPM repository. This will be made public in the future once MOBiUS Flow is ready for public release.
7
+ This module currently requires access to the iaconnects private NPM repository.
14
8
 
15
9
  ## Nodes
16
10
 
@@ -33,4 +27,4 @@ Clears the specified priority of resource.
33
27
  Subscribe to change of value events for an object
34
28
 
35
29
  ### Resource COV Node
36
- Subscribe to change of value events for a resource
30
+ Subscribe to change of value events for a resource
@@ -0,0 +1,18 @@
1
+ import { AxiosInstance } from 'axios';
2
+ export declare const discover: (apiClient: AxiosInstance, uri: string, callback: Function) => Promise<void>;
3
+ export declare const writeResource: (apiClient: AxiosInstance, uri: string, value: number | string | boolean, priority: number, callback: Function) => Promise<void>;
4
+ export declare const writeMultiResource: (apiClient: AxiosInstance, uri: string, updates: {
5
+ r: string;
6
+ p: number;
7
+ v: number | string | boolean;
8
+ }[], callback: Function) => Promise<void>;
9
+ export declare const clearResource: (apiClient: AxiosInstance, uri: string, priority: number, callback: Function) => Promise<void>;
10
+ export declare const readResource: (apiClient: AxiosInstance, uri: string, callback: Function) => Promise<void>;
11
+ export declare const readObject: (apiClient: AxiosInstance, uri: string, callback: Function) => Promise<void>;
12
+ export declare const sendBroadcastCommand: (apiClient: AxiosInstance, cid: string, commandData: any) => Promise<void>;
13
+ export declare const sendDirectCommand: (apiClient: AxiosInstance, uri: string, cid: string, commandData: any, timeout: number, callback: Function) => Promise<void>;
14
+ export declare const getServiceConfig: (apiClient: AxiosInstance, uri: string, callback: Function) => Promise<void>;
15
+ export declare const updateObject: (apiClient: AxiosInstance, uri: string, config: any, callback: Function) => Promise<void>;
16
+ export declare const filterObjectsByRIDValue: (apiClient: AxiosInstance, uri: string, pids: string[], rid: string, limit: number, func: (v: string | number | boolean) => boolean, callback: Function) => Promise<any>;
17
+ export declare const getHubId: (apiClient: AxiosInstance, callback: Function) => Promise<void>;
18
+ export declare const getNodeConfig: (apiClient: AxiosInstance, uri: string, callback: Function) => Promise<void>;
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNodeConfig = exports.getHubId = exports.filterObjectsByRIDValue = exports.updateObject = exports.getServiceConfig = exports.sendDirectCommand = exports.sendBroadcastCommand = exports.readObject = exports.readResource = exports.clearResource = exports.writeMultiResource = exports.writeResource = exports.discover = void 0;
4
+ const discover = async (apiClient, uri, callback) => {
5
+ try {
6
+ const response = await apiClient({
7
+ method: 'get',
8
+ url: `/mobius/discover/${uri}`,
9
+ });
10
+ callback(null, response.data);
11
+ }
12
+ catch (err) {
13
+ callback(err);
14
+ }
15
+ };
16
+ exports.discover = discover;
17
+ const writeResource = async (apiClient, uri, value, priority, callback) => {
18
+ try {
19
+ const response = await apiClient({
20
+ method: 'post',
21
+ url: `/mobius/object/resource/${uri}`,
22
+ data: {
23
+ value,
24
+ priority,
25
+ },
26
+ });
27
+ callback(null, response.data);
28
+ }
29
+ catch (err) {
30
+ callback(err);
31
+ }
32
+ };
33
+ exports.writeResource = writeResource;
34
+ const writeMultiResource = async (apiClient, uri, updates, callback) => {
35
+ try {
36
+ const response = await apiClient({
37
+ method: 'patch',
38
+ url: `/mobius/object/resource/${uri}`,
39
+ data: updates,
40
+ });
41
+ callback(null, response.data);
42
+ }
43
+ catch (err) {
44
+ callback(err);
45
+ }
46
+ };
47
+ exports.writeMultiResource = writeMultiResource;
48
+ const clearResource = async (apiClient, uri, priority, callback) => {
49
+ try {
50
+ const response = await apiClient({
51
+ method: 'patch',
52
+ url: `/mobius/object/resource/clear/${uri}`,
53
+ data: {
54
+ priority,
55
+ },
56
+ });
57
+ callback(null, response.data);
58
+ }
59
+ catch (err) {
60
+ callback(err);
61
+ }
62
+ };
63
+ exports.clearResource = clearResource;
64
+ const readResource = async (apiClient, uri, callback) => {
65
+ try {
66
+ const response = await apiClient({
67
+ method: 'get',
68
+ url: `/mobius/object/resource/${uri}`,
69
+ });
70
+ callback(null, response.data);
71
+ }
72
+ catch (err) {
73
+ callback(err);
74
+ }
75
+ };
76
+ exports.readResource = readResource;
77
+ const readObject = async (apiClient, uri, callback) => {
78
+ try {
79
+ const response = await apiClient({
80
+ method: 'get',
81
+ url: `/mobius/object/${uri}`,
82
+ });
83
+ callback(null, response.data);
84
+ }
85
+ catch (err) {
86
+ callback(err);
87
+ }
88
+ };
89
+ exports.readObject = readObject;
90
+ const sendBroadcastCommand = async (apiClient, cid, commandData) => {
91
+ try {
92
+ const response = await apiClient({
93
+ method: 'post',
94
+ url: `/mobius/command/${cid}`,
95
+ data: commandData,
96
+ });
97
+ }
98
+ catch (err) {
99
+ throw `Failed to send broadcast command: ${JSON.stringify(err)}`;
100
+ }
101
+ };
102
+ exports.sendBroadcastCommand = sendBroadcastCommand;
103
+ const sendDirectCommand = async (apiClient, uri, cid, commandData, timeout, callback) => {
104
+ try {
105
+ const response = await apiClient({
106
+ method: 'post',
107
+ url: `/mobius/directCommand/${cid}`,
108
+ data: {
109
+ uri,
110
+ commandData,
111
+ timeout,
112
+ },
113
+ });
114
+ callback(null, response.data);
115
+ }
116
+ catch (err) {
117
+ callback(err);
118
+ }
119
+ };
120
+ exports.sendDirectCommand = sendDirectCommand;
121
+ const getServiceConfig = async (apiClient, uri, callback) => {
122
+ console.log(uri);
123
+ try {
124
+ const response = await apiClient({
125
+ method: 'get',
126
+ url: `/mobius/service/config/${uri}`,
127
+ });
128
+ callback(null, response.data);
129
+ }
130
+ catch (err) {
131
+ callback(err);
132
+ }
133
+ };
134
+ exports.getServiceConfig = getServiceConfig;
135
+ const updateObject = async (apiClient, uri, config, callback) => {
136
+ try {
137
+ const response = await apiClient({
138
+ method: 'post',
139
+ url: `/mobius/object/config/${uri}`,
140
+ data: config,
141
+ });
142
+ callback(null, response.data);
143
+ }
144
+ catch (err) {
145
+ callback(err);
146
+ }
147
+ };
148
+ exports.updateObject = updateObject;
149
+ const filterObjectsByRIDValue = async (apiClient, uri, pids, rid, limit, func, callback) => {
150
+ try {
151
+ const discoveries = [];
152
+ for (let pid of pids) {
153
+ discoveries.push(apiClient({
154
+ method: 'get',
155
+ url: `/mobius/discover/${uri}/${pid}`,
156
+ }));
157
+ }
158
+ const pidGroups = (await Promise.all(discoveries)).map((response) => ({
159
+ uri: response.data.uri,
160
+ inss: response.data.data,
161
+ }));
162
+ const objectUris = [];
163
+ for (let pidGroup of pidGroups) {
164
+ for (let ins of pidGroup.inss) {
165
+ objectUris.push(`${pidGroup.uri}/${ins}`);
166
+ }
167
+ }
168
+ const objects = [];
169
+ for (let objectUri of objectUris) {
170
+ const object = await apiClient({
171
+ method: 'get',
172
+ url: `/mobius/object/${objectUri}`,
173
+ });
174
+ const resource = object.data.data.resources.find((r) => r.rid === rid);
175
+ if (func(resource?.pv)) {
176
+ objects.push(object.data.data);
177
+ }
178
+ if (objects.length >= limit) {
179
+ return callback(null, { uri, ts: new Date().toISOString(), value: objects });
180
+ }
181
+ }
182
+ return callback(null, { uri, ts: new Date().toISOString(), value: objects });
183
+ }
184
+ catch (err) {
185
+ callback(err);
186
+ }
187
+ };
188
+ exports.filterObjectsByRIDValue = filterObjectsByRIDValue;
189
+ const getHubId = async (apiClient, callback) => {
190
+ try {
191
+ const response = await apiClient({
192
+ method: 'get',
193
+ url: `/mobius/admin/settings`,
194
+ });
195
+ callback(null, response.data.data.mobiusFlow.hubID.runtime);
196
+ }
197
+ catch (err) {
198
+ callback(err);
199
+ }
200
+ };
201
+ exports.getHubId = getHubId;
202
+ const getNodeConfig = async (apiClient, uri, callback) => {
203
+ try {
204
+ const response = await apiClient({
205
+ method: 'get',
206
+ url: `/mobius/node/config/${uri}`,
207
+ });
208
+ callback(null, response.data);
209
+ }
210
+ catch (err) {
211
+ callback(err);
212
+ }
213
+ };
214
+ exports.getNodeConfig = getNodeConfig;
@@ -0,0 +1,7 @@
1
+ export declare let tokens: null | {
2
+ token: string;
3
+ refreshToken: string;
4
+ };
5
+ export declare let loggedIn: boolean;
6
+ export declare const getApiClient: (protocol: string, host: string, port: number, username: string, password: string) => import("axios").AxiosInstance;
7
+ export declare const setLoggedIn: (value: boolean) => void;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.setLoggedIn = exports.getApiClient = exports.loggedIn = exports.tokens = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const engine_websocket_1 = require("./engine-websocket");
9
+ exports.tokens = null;
10
+ exports.loggedIn = false;
11
+ const getApiClient = (protocol, host, port, username, password) => {
12
+ //const baseURL = `http://localhost:8443/api/v1`;
13
+ const baseURL = `${protocol}://${host}:${port}/api/v1`;
14
+ const client = axios_1.default.create({
15
+ baseURL: baseURL,
16
+ headers: {
17
+ 'Content-Type': 'application/json',
18
+ },
19
+ });
20
+ // Add auth headers to all axios calls
21
+ client.interceptors.request.use((config) => {
22
+ if (!config.url?.endsWith('/auth/login')) {
23
+ if (exports.tokens && config.headers) {
24
+ config.headers['Authorization'] = `Bearer ${exports.tokens.token}`;
25
+ }
26
+ }
27
+ return config;
28
+ }, (error) => {
29
+ Promise.reject(error);
30
+ });
31
+ const login = async () => {
32
+ try {
33
+ const response = await client({
34
+ method: 'post',
35
+ url: '/auth/login',
36
+ data: {
37
+ username,
38
+ password,
39
+ },
40
+ });
41
+ exports.tokens = response.data;
42
+ exports.loggedIn = true;
43
+ console.log('Logged in');
44
+ (0, engine_websocket_1.connectToWebSocket)();
45
+ }
46
+ catch (e) {
47
+ exports.loggedIn = false;
48
+ }
49
+ };
50
+ login();
51
+ const refresh = async () => {
52
+ if (!exports.tokens) {
53
+ return;
54
+ }
55
+ try {
56
+ const response = await client({
57
+ method: 'post',
58
+ url: '/auth/refresh',
59
+ data: {
60
+ refreshToken: exports.tokens.refreshToken,
61
+ },
62
+ });
63
+ exports.tokens = response.data;
64
+ exports.loggedIn = true;
65
+ }
66
+ catch {
67
+ exports.loggedIn = false;
68
+ login();
69
+ }
70
+ };
71
+ setInterval(refresh, 1000 * 60 * 5);
72
+ client.interceptors.response.use((res) => {
73
+ return res;
74
+ }, async (error) => {
75
+ if (!error.response) {
76
+ // notify
77
+ }
78
+ if (error.response.status === 401 && !error.config.url?.endsWith('/auth/login')) {
79
+ console.log(`Logged Out: ${JSON.stringify(error.response)}`);
80
+ exports.loggedIn = false;
81
+ exports.tokens = null;
82
+ login();
83
+ }
84
+ return Promise.reject(error);
85
+ });
86
+ return client;
87
+ };
88
+ exports.getApiClient = getApiClient;
89
+ const setLoggedIn = (value) => {
90
+ exports.loggedIn = value;
91
+ };
92
+ exports.setLoggedIn = setLoggedIn;
@@ -0,0 +1,58 @@
1
+ type WebSocketTopics = 'authorize' | 'subscribe' | 'unsubscribe' | 'connected' | 'authorized' | 'object-cov' | 'resource-cov' | 'service-status' | 'broadcast-command' | 'error' | 'ping' | 'pong';
2
+ type Events = 'connected' | 'disconnected';
3
+ export declare const on: (eventName: Events, callback: Function) => void;
4
+ export declare function registerCallback(topic: WebSocketTopics, callback: Function): void;
5
+ export declare function clearAllCallbacks(): void;
6
+ /**
7
+ * Connect to the Mobius WebSocket API
8
+ * This method will connect to the Mobius WebSocket API and authenticate with the API token
9
+ */
10
+ export declare const connectToWebSocket: () => void;
11
+ /**
12
+ * Disconnect from the Mobius WebSocket API
13
+ * This method will close the connection to the Mobius WebSocket API
14
+ */
15
+ export declare const disconnectFromWebSocket: () => void;
16
+ /**
17
+ * Subscribe to an object's COV
18
+ * This method will subscribe to an object's COV
19
+ * @param uri The URI of the object to subscribe to
20
+ * @param listener The listener to dispatch the event to
21
+ */
22
+ export declare const subscribeToObjectCOV: (uri: string) => void;
23
+ /**
24
+ * Unsubscribe from an object's COV
25
+ * This method will unsubscribe from an object's COV
26
+ * @param uri The URI of the object to unsubscribe from
27
+ * @param listener The listener to remove
28
+ */
29
+ export declare const unsubscribeToObjectCOV: (uri: string) => void;
30
+ /**
31
+ * Subscribe to an object's COV
32
+ * This method will subscribe to an object's COV
33
+ * @param uri The URI of the object to subscribe to
34
+ * @param listener The listener to dispatch the event to
35
+ */
36
+ export declare const subscribeToResourceCOV: (uri: string) => void;
37
+ /**
38
+ * Unsubscribe from an object's COV
39
+ * This method will unsubscribe from an object's COV
40
+ * @param uri The URI of the object to unsubscribe from
41
+ * @param listener The listener to remove
42
+ */
43
+ export declare const unsubscribeToResourceCOV: (uri: string) => void;
44
+ /**
45
+ * Subscribe to a BCMD event
46
+ * This method will subscribe to a BCMD event
47
+ * @param uri The URI of the object to subscribe to
48
+ * @param listener The listener to dispatch the event to
49
+ */
50
+ export declare const subscribeToBCMD: (uri: string) => void;
51
+ /**
52
+ * Unsubscribe from a BCMD event
53
+ * This method will unsubscribe from a BCMD event
54
+ * @param uri The URI of the object to unsubscribe from
55
+ * @param listener The listener to remove
56
+ */
57
+ export declare const unsubscribeToBCMD: (uri: string) => void;
58
+ export {};