node-red-contrib-homebridge-automation 0.2.0 → 0.2.1-beta.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/.github/npm-version-script.js +85 -0
- package/package.json +2 -2
- package/src/hbConfigNode.js +2 -18
- package/src/hbConfigNode.test.js +42 -42
- package/test/node-red/.config.nodes.json +1 -1
- package/test/node-red/.config.nodes.json.backup +1 -1
- package/test/node-red/.flows.json.backup +2 -1
- package/test/node-red/flows.json +1 -1
- package/test/node-red/settings.js +71 -71
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This scripts queries the npm registry to pull out the latest version for a given tag.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const assert = require('node:assert')
|
|
8
|
+
const child_process = require('node:child_process')
|
|
9
|
+
const fs = require('node:fs')
|
|
10
|
+
const process = require('node:process')
|
|
11
|
+
|
|
12
|
+
const semver = require('semver')
|
|
13
|
+
|
|
14
|
+
const BRANCH_VERSION_PATTERN = /^([A-Z]+)-(\d+\.\d+\.\d+)$/i
|
|
15
|
+
|
|
16
|
+
// Load the contents of the package.json file
|
|
17
|
+
const packageJSON = JSON.parse(fs.readFileSync('package.json', 'utf8'))
|
|
18
|
+
|
|
19
|
+
const refArgument = process.argv[2]
|
|
20
|
+
const tagArgument = process.argv[3] || 'latest'
|
|
21
|
+
|
|
22
|
+
if (refArgument == null) {
|
|
23
|
+
console.error('ref argument is missing')
|
|
24
|
+
console.error('Usage: npm-version-script.js <ref> [tag]')
|
|
25
|
+
process.exit(1)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Queries the NPM registry for the latest version for the provided tag.
|
|
30
|
+
* @param tag The tag to query for.
|
|
31
|
+
* @returns {string} Returns the version.
|
|
32
|
+
*/
|
|
33
|
+
function getTagVersionFromNpm(tag) {
|
|
34
|
+
try {
|
|
35
|
+
return child_process.execSync(`npm info ${packageJSON.name} version --tag="${tag}"`).toString('utf8').trim()
|
|
36
|
+
} catch (e) {
|
|
37
|
+
console.error(`Failed to query the npm registry for the latest version for tag: ${tag}`)
|
|
38
|
+
// throw e;
|
|
39
|
+
return '0.0.0'
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function desiredTargetVersion(ref) {
|
|
44
|
+
// ref is a GitHub action ref string
|
|
45
|
+
if (ref.startsWith('refs/pull/')) {
|
|
46
|
+
throw new Error('The version script was executed inside a PR!')
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
assert(ref.startsWith('refs/heads/'))
|
|
50
|
+
const branchName = ref.slice('refs/heads/'.length)
|
|
51
|
+
|
|
52
|
+
const results = branchName.match(BRANCH_VERSION_PATTERN)
|
|
53
|
+
if (results != null) {
|
|
54
|
+
if (results[1] !== tagArgument) {
|
|
55
|
+
console.warn(`The base branch name (${results[1]}) differs from the tag name ${tagArgument}`)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return results[2]
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
throw new Error(`Malformed branch name for ref: ${ref}. Can't derive the base version. Use a branch name like: beta-x.x.x or alpha-x.x.x`)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// derive the base version from the branch ref
|
|
65
|
+
const baseVersion = desiredTargetVersion(refArgument)
|
|
66
|
+
|
|
67
|
+
// query the npm registry for the latest version of the provided tag name
|
|
68
|
+
const latestReleasedVersion = getTagVersionFromNpm(tagArgument) // e.g. 0.7.0-beta.12
|
|
69
|
+
const latestReleaseBase = semver.inc(latestReleasedVersion, 'patch') // will produce 0.7.0 (removing the preid, needed for the equality check below)
|
|
70
|
+
|
|
71
|
+
let publishTag
|
|
72
|
+
if (semver.eq(baseVersion, latestReleaseBase)) { // check if we are releasing another version for the latest beta or alpha
|
|
73
|
+
publishTag = latestReleasedVersion // set the current latest beta or alpha to be incremented
|
|
74
|
+
} else {
|
|
75
|
+
publishTag = baseVersion // start of with a new beta or alpha version
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// save the package.json
|
|
79
|
+
packageJSON.version = publishTag
|
|
80
|
+
fs.writeFileSync('package.json', JSON.stringify(packageJSON, null, 2))
|
|
81
|
+
|
|
82
|
+
// perform the same change to the package-lock.json
|
|
83
|
+
const packageLockJSON = JSON.parse(fs.readFileSync('package-lock.json', 'utf8'))
|
|
84
|
+
packageLockJSON.version = publishTag
|
|
85
|
+
fs.writeFileSync('package-lock.json', JSON.stringify(packageLockJSON, null, 2))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-red-contrib-homebridge-automation",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1-beta.1",
|
|
4
4
|
"description": "NodeRED Automation for HomeBridge",
|
|
5
5
|
"main": "src/HAP-NodeRed.js",
|
|
6
6
|
"scripts": {
|
|
@@ -76,4 +76,4 @@
|
|
|
76
76
|
"!src/test-utils"
|
|
77
77
|
]
|
|
78
78
|
}
|
|
79
|
-
}
|
|
79
|
+
}
|
package/src/hbConfigNode.js
CHANGED
|
@@ -26,36 +26,20 @@ class HBConfigNode {
|
|
|
26
26
|
|
|
27
27
|
this.hapClient.on('instance-discovered', this.waitForNoMoreDiscoveries);
|
|
28
28
|
this.hapClient.on('discovery-ended', this.hapClient.refreshInstances);
|
|
29
|
-
this.waitForNoMoreDiscoveries();
|
|
30
29
|
this.on('close', this.close.bind(this));
|
|
31
30
|
this.refreshInProcess = true; // Prevents multiple refreshes, hapClient kicks of a discovery on start
|
|
32
31
|
}
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
/**
|
|
36
|
-
* Start device discovery after monitor reports issues
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
refreshDevices = () => {
|
|
40
|
-
if (!this.refreshInProcess) {
|
|
41
|
-
|
|
42
|
-
this.monitor.finish();
|
|
43
|
-
this.debug('Monitor reported homebridge stability issues, refreshing devices');
|
|
44
|
-
this.hapClient.on('instance-discovered', this.waitForNoMoreDiscoveries);
|
|
45
|
-
this.hapClient.resetInstancePool();
|
|
46
|
-
this.waitForNoMoreDiscoveries();
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
34
|
/**
|
|
51
35
|
* Wait for no more instance discoveries to be made before publishing services
|
|
52
36
|
*/
|
|
53
|
-
waitForNoMoreDiscoveries = () => {
|
|
37
|
+
waitForNoMoreDiscoveries = (instance) => {
|
|
38
|
+
debug('Instance discovered: %s - %s %s:%s', instance?.name, instance?.username, instance?.ipAddress, instance?.port);
|
|
54
39
|
if (!this.discoveryTimeout) {
|
|
55
40
|
clearTimeout(this.discoveryTimeout);
|
|
56
41
|
this.discoveryTimeout = setTimeout(() => {
|
|
57
42
|
this.debug('No more instances discovered, publishing services');
|
|
58
|
-
this.hapClient.removeListener('instance-discovered', this.waitForNoMoreDiscoveries);
|
|
59
43
|
this.handleReady();
|
|
60
44
|
this.discoveryTimeout = null;
|
|
61
45
|
this.refreshInProcess = false;
|
package/src/hbConfigNode.test.js
CHANGED
|
@@ -2094,26 +2094,35 @@ describe('HBConfigNode', () => {
|
|
|
2094
2094
|
];
|
|
2095
2095
|
});
|
|
2096
2096
|
|
|
2097
|
-
test('toList filters and maps devices correctly', () => {
|
|
2097
|
+
test('toList filters and maps camera devices correctly', () => {
|
|
2098
2098
|
const result = node.toList({ perms: 'ev' });
|
|
2099
2099
|
expect(result).toEqual([
|
|
2100
2100
|
{
|
|
2101
|
-
name: '
|
|
2102
|
-
fullName: '
|
|
2103
|
-
sortName: '
|
|
2104
|
-
uniqueId: '
|
|
2105
|
-
homebridge: '
|
|
2106
|
-
service: '
|
|
2107
|
-
manufacturer: '
|
|
2101
|
+
name: 'Backyard',
|
|
2102
|
+
fullName: 'Backyard - CameraRTPStreamManagement',
|
|
2103
|
+
sortName: 'Backyard:CameraRTPStreamManagement',
|
|
2104
|
+
uniqueId: 'homebridge0E:89:A7:DA:D3:21EufyBackyard00000110',
|
|
2105
|
+
homebridge: 'homebridge',
|
|
2106
|
+
service: 'CameraRTPStreamManagement',
|
|
2107
|
+
manufacturer: 'Eufy'
|
|
2108
2108
|
},
|
|
2109
2109
|
{
|
|
2110
|
-
name: '
|
|
2111
|
-
fullName: '
|
|
2112
|
-
sortName: '
|
|
2113
|
-
uniqueId: '
|
|
2114
|
-
homebridge: '
|
|
2115
|
-
service: '
|
|
2116
|
-
manufacturer: '
|
|
2110
|
+
name: 'Backyard',
|
|
2111
|
+
fullName: 'Backyard - MotionSensor',
|
|
2112
|
+
sortName: 'Backyard:MotionSensor',
|
|
2113
|
+
uniqueId: 'homebridge0E:89:A7:DA:D3:21EufyBackyard00000085',
|
|
2114
|
+
homebridge: 'homebridge',
|
|
2115
|
+
service: 'MotionSensor',
|
|
2116
|
+
manufacturer: 'Eufy'
|
|
2117
|
+
},
|
|
2118
|
+
{
|
|
2119
|
+
"fullName": "Canoe 5036 - CameraRTPStreamManagement",
|
|
2120
|
+
"homebridge": "ECI-T24F2",
|
|
2121
|
+
"manufacturer": "HikVision",
|
|
2122
|
+
"name": "Canoe 5036",
|
|
2123
|
+
"service": "CameraRTPStreamManagement",
|
|
2124
|
+
"sortName": "Canoe 5036:CameraRTPStreamManagement",
|
|
2125
|
+
"uniqueId": "ECI-T24F25C:EE:FE:4D:64:B4HikVisionCanoe 503600000110",
|
|
2117
2126
|
},
|
|
2118
2127
|
{
|
|
2119
2128
|
"fullName": "Canoe - MotionSensor",
|
|
@@ -2125,28 +2134,28 @@ describe('HBConfigNode', () => {
|
|
|
2125
2134
|
"uniqueId": "ECI-T24F25C:EE:FE:4D:64:B4HikVisionCanoe00000085",
|
|
2126
2135
|
},
|
|
2127
2136
|
{
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2137
|
+
name: 'Kitchen Switch',
|
|
2138
|
+
fullName: 'Kitchen Switch - Switch',
|
|
2139
|
+
sortName: 'Kitchen Switch:Switch',
|
|
2140
|
+
uniqueId: 'Bridge211:22:33:44:55:66AcmeKitchen Switch87654321',
|
|
2141
|
+
homebridge: 'Bridge2',
|
|
2142
|
+
service: 'Switch',
|
|
2143
|
+
manufacturer: 'Acme',
|
|
2135
2144
|
},
|
|
2136
2145
|
{
|
|
2137
|
-
name: '
|
|
2138
|
-
fullName: '
|
|
2139
|
-
sortName: '
|
|
2140
|
-
uniqueId: '
|
|
2141
|
-
homebridge: '
|
|
2142
|
-
service: '
|
|
2143
|
-
manufacturer: '
|
|
2146
|
+
name: 'Living Room Light',
|
|
2147
|
+
fullName: 'Living Room Light - Lightbulb',
|
|
2148
|
+
sortName: 'Living Room Light:Lightbulb',
|
|
2149
|
+
uniqueId: 'Bridge100:11:22:33:44:55AcmeLiving Room Light12345678',
|
|
2150
|
+
homebridge: 'Bridge1',
|
|
2151
|
+
service: 'Lightbulb',
|
|
2152
|
+
manufacturer: 'Acme',
|
|
2144
2153
|
},
|
|
2145
2154
|
{
|
|
2146
|
-
name: '
|
|
2147
|
-
fullName: '
|
|
2148
|
-
sortName: '
|
|
2149
|
-
uniqueId: 'homebridge0E:89:A7:DA:D3:
|
|
2155
|
+
name: 'Side door',
|
|
2156
|
+
fullName: 'Side door - CameraRTPStreamManagement',
|
|
2157
|
+
sortName: 'Side door:CameraRTPStreamManagement',
|
|
2158
|
+
uniqueId: 'homebridge0E:89:A7:DA:D3:21EufySide door00000110',
|
|
2150
2159
|
homebridge: 'homebridge',
|
|
2151
2160
|
service: 'CameraRTPStreamManagement',
|
|
2152
2161
|
manufacturer: 'Eufy'
|
|
@@ -2160,15 +2169,6 @@ describe('HBConfigNode', () => {
|
|
|
2160
2169
|
service: 'MotionSensor',
|
|
2161
2170
|
manufacturer: 'Eufy'
|
|
2162
2171
|
},
|
|
2163
|
-
{
|
|
2164
|
-
name: 'Side door',
|
|
2165
|
-
fullName: 'Side door - CameraRTPStreamManagement',
|
|
2166
|
-
sortName: 'Side door:CameraRTPStreamManagement',
|
|
2167
|
-
uniqueId: 'homebridge0E:89:A7:DA:D3:21EufySide door00000110',
|
|
2168
|
-
homebridge: 'homebridge',
|
|
2169
|
-
service: 'CameraRTPStreamManagement',
|
|
2170
|
-
manufacturer: 'Eufy'
|
|
2171
|
-
}
|
|
2172
2172
|
]);
|
|
2173
2173
|
|
|
2174
2174
|
// Ensure the unsupported type was filtered out
|
package/test/node-red/flows.json
CHANGED
|
@@ -22,14 +22,14 @@
|
|
|
22
22
|
|
|
23
23
|
module.exports = {
|
|
24
24
|
|
|
25
|
-
/*******************************************************************************
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
/*******************************************************************************
|
|
26
|
+
* Flow File and User Directory Settings
|
|
27
|
+
* - flowFile
|
|
28
|
+
* - credentialSecret
|
|
29
|
+
* - flowFilePretty
|
|
30
|
+
* - userDir
|
|
31
|
+
* - nodesDir
|
|
32
|
+
******************************************************************************/
|
|
33
33
|
|
|
34
34
|
/** The file containing the flows. If not set, defaults to flows_<hostname>.json **/
|
|
35
35
|
flowFile: 'flows.json',
|
|
@@ -60,15 +60,15 @@ module.exports = {
|
|
|
60
60
|
*/
|
|
61
61
|
//nodesDir: '/home/nol/.node-red/nodes',
|
|
62
62
|
|
|
63
|
-
/*******************************************************************************
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
/*******************************************************************************
|
|
64
|
+
* Security
|
|
65
|
+
* - adminAuth
|
|
66
|
+
* - https
|
|
67
|
+
* - httpsRefreshInterval
|
|
68
|
+
* - requireHttps
|
|
69
|
+
* - httpNodeAuth
|
|
70
|
+
* - httpStaticAuth
|
|
71
|
+
******************************************************************************/
|
|
72
72
|
|
|
73
73
|
/** To password protect the Node-RED editor and admin API, the following
|
|
74
74
|
* property can be used. See https://nodered.org/docs/security.html for details.
|
|
@@ -125,22 +125,22 @@ module.exports = {
|
|
|
125
125
|
//httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
|
|
126
126
|
//httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
|
|
127
127
|
|
|
128
|
-
/*******************************************************************************
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
128
|
+
/*******************************************************************************
|
|
129
|
+
* Server Settings
|
|
130
|
+
* - uiPort
|
|
131
|
+
* - uiHost
|
|
132
|
+
* - apiMaxLength
|
|
133
|
+
* - httpServerOptions
|
|
134
|
+
* - httpAdminRoot
|
|
135
|
+
* - httpAdminMiddleware
|
|
136
|
+
* - httpAdminCookieOptions
|
|
137
|
+
* - httpNodeRoot
|
|
138
|
+
* - httpNodeCors
|
|
139
|
+
* - httpNodeMiddleware
|
|
140
|
+
* - httpStatic
|
|
141
|
+
* - httpStaticRoot
|
|
142
|
+
* - httpStaticCors
|
|
143
|
+
******************************************************************************/
|
|
144
144
|
|
|
145
145
|
/** the tcp port that the Node-RED web server is listening on */
|
|
146
146
|
uiPort: process.env.PORT || 1880,
|
|
@@ -269,16 +269,16 @@ module.exports = {
|
|
|
269
269
|
// mode: "legacy", // legacy mode is for non-strict previous proxy determination logic (node-red < v4 compatible)
|
|
270
270
|
// },
|
|
271
271
|
|
|
272
|
-
/*******************************************************************************
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
272
|
+
/*******************************************************************************
|
|
273
|
+
* Runtime Settings
|
|
274
|
+
* - lang
|
|
275
|
+
* - runtimeState
|
|
276
|
+
* - diagnostics
|
|
277
|
+
* - logging
|
|
278
|
+
* - contextStorage
|
|
279
|
+
* - exportGlobalContextKeys
|
|
280
|
+
* - externalModules
|
|
281
|
+
******************************************************************************/
|
|
282
282
|
|
|
283
283
|
/** Uncomment the following to run node-red in your preferred language.
|
|
284
284
|
* Available languages include: en-US (default), ja, de, zh-CN, zh-TW, ru, ko
|
|
@@ -324,7 +324,7 @@ module.exports = {
|
|
|
324
324
|
* trace - record very detailed logging + debug + info + warn + error + fatal errors
|
|
325
325
|
* off - turn off all logging (doesn't affect metrics or audit)
|
|
326
326
|
*/
|
|
327
|
-
level: "
|
|
327
|
+
level: "debug",
|
|
328
328
|
/** Whether or not to include metric events in the log output */
|
|
329
329
|
metrics: false,
|
|
330
330
|
/** Whether or not to include audit events in the log output */
|
|
@@ -381,11 +381,11 @@ module.exports = {
|
|
|
381
381
|
},
|
|
382
382
|
|
|
383
383
|
|
|
384
|
-
/*******************************************************************************
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
384
|
+
/*******************************************************************************
|
|
385
|
+
* Editor Settings
|
|
386
|
+
* - disableEditor
|
|
387
|
+
* - editorTheme
|
|
388
|
+
******************************************************************************/
|
|
389
389
|
|
|
390
390
|
/** The following property can be used to disable the editor. The admin API
|
|
391
391
|
* is not affected by this option. To disable both the editor and the admin
|
|
@@ -468,28 +468,28 @@ module.exports = {
|
|
|
468
468
|
},
|
|
469
469
|
},
|
|
470
470
|
|
|
471
|
-
/*******************************************************************************
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
471
|
+
/*******************************************************************************
|
|
472
|
+
* Node Settings
|
|
473
|
+
* - fileWorkingDirectory
|
|
474
|
+
* - functionGlobalContext
|
|
475
|
+
* - functionExternalModules
|
|
476
|
+
* - functionTimeout
|
|
477
|
+
* - nodeMessageBufferMaxLength
|
|
478
|
+
* - ui (for use with Node-RED Dashboard)
|
|
479
|
+
* - debugUseColors
|
|
480
|
+
* - debugMaxLength
|
|
481
|
+
* - debugStatusLength
|
|
482
|
+
* - execMaxBufferSize
|
|
483
|
+
* - httpRequestTimeout
|
|
484
|
+
* - mqttReconnectTime
|
|
485
|
+
* - serialReconnectTime
|
|
486
|
+
* - socketReconnectTime
|
|
487
|
+
* - socketTimeout
|
|
488
|
+
* - tcpMsgQueueSize
|
|
489
|
+
* - inboundWebSocketTimeout
|
|
490
|
+
* - tlsConfigDisableLocalFiles
|
|
491
|
+
* - webSocketNodeVerifyClient
|
|
492
|
+
******************************************************************************/
|
|
493
493
|
|
|
494
494
|
/** The working directory to handle relative file paths from within the File nodes
|
|
495
495
|
* defaults to the working directory of the Node-RED process.
|