Skip to content

Commit 034daf6

Browse files
committed
0.2.2
- Improved handling of configuration file with docker/standalone version - Warning about the use of legacy configuration options with docker/standalone version - Audio from newer Nest/Google camera/doorbell devices is still blank - npm package [ip](GHSA-2p57-rm9w-gvfp) has severity issue. This is being used in external library (werift)
1 parent a380dd4 commit 034daf6

File tree

4 files changed

+110
-23
lines changed

4 files changed

+110
-23
lines changed

CHANGELOG.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,18 @@
22

33
All notable changes to `homebridge-nest-accfactory` will be documented in this file. This project tries to adhere to [Semantic Versioning](http://semver.org/).
44

5-
## v0.2.1 (2024/10/05)
65

7-
## Changes
6+
## v0.2.2 (2024/10/05)
7+
8+
- Improved handling of configuration file with docker/standalone version
9+
- Warning about the use of legacy configuration options with docker/standalone version
10+
11+
## Known Issues
12+
13+
- Audio from newer Nest/Google camera/doorbell devices is still blank
14+
- npm package [ip](https://github.com/advisories/GHSA-2p57-rm9w-gvfp) has severity issue. This is being used in external library (werift)
15+
16+
## v0.2.1 (2024/10/05)
817

918
- HomeKit support for multiple speeds on thermostat(s)
1019
- Audio library in docker release went walkabout. Added back in

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "homebridge-nest-accfactory",
33
"displayName": "Homebridge Nest Accfactory",
44
"type": "module",
5-
"version": "0.2.1",
5+
"version": "0.2.2",
66
"description": "Homebridge support for Nest/Google devices including HomeKit Secure Video (HKSV) support for doorbells and cameras",
77
"author": "n0rt0nthec4t",
88
"license": "Apache-2.0",

src/docker-standalone/index.js

Lines changed: 97 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
//
1818
// Supports both Nest REST and Protobuf APIs for communication
1919
//
20-
// Code version 3/10/2024
20+
// Code version 5/10/2024
2121
// Mark Hulskamp
2222
'use strict';
2323

24-
// Define Homebridge module requirements
24+
// Define HAP-NodeJS module requirements
2525
import HAP from 'hap-nodejs';
2626

2727
// Define nodejs module requirements
@@ -30,6 +30,7 @@ import fs from 'node:fs';
3030
import path from 'node:path';
3131
import { fileURLToPath } from 'node:url';
3232
import { setInterval } from 'node:timers';
33+
import { createRequire } from 'node:module';
3334

3435
// Import our modules
3536
import NestAccfactory from './system.js';
@@ -44,7 +45,9 @@ HomeKitDevice.HISTORY = HomeKitHistory;
4445
import Logger from './logger.js';
4546
const log = Logger.withPrefix(HomeKitDevice.PLATFORM_NAME);
4647

47-
const __filename = fileURLToPath(import.meta.url); // Make a defined for JS __dirname
48+
// Import the package.json file to get the version number
49+
const { version } = createRequire(import.meta.url)('../package.json');
50+
4851
const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Make a defined for JS __dirname
4952
const ACCESSORYPINCODE = '031-45-154'; // Default HomeKit pairing code
5053
const CONFIGURATIONFILE = 'Nest_config.json'; // Default configuration file name
@@ -56,38 +59,35 @@ function loadConfiguration(filename) {
5659
}
5760

5861
let config = undefined;
62+
let legacyFormat = false;
5963

6064
try {
6165
let loadedConfig = JSON.parse(fs.readFileSync(filename));
6266

6367
config = {
64-
nest: {},
65-
google: {},
6668
options: {},
6769
devices: {},
6870
};
6971

7072
// Load in 'current' configuration structure if present
7173
// Most of the code below is to handle the 'legacy' structure
72-
if (typeof loadedConfig?.nest === 'object') {
73-
config.nest = loadedConfig.nest;
74-
}
7574
if (typeof loadedConfig?.Connections?.Nest === 'object') {
75+
legacyFormat = true;
7676
config.nest = loadedConfig.Connections.Nest;
7777
}
7878
if (typeof loadedConfig?.SessionToken === 'string' && loadedConfig.SessionToken !== '') {
79+
legacyFormat = true;
7980
config.nest = {
8081
access_token: loadedConfig.SessionToken,
8182
fieldTest: false,
8283
};
8384
}
84-
if (typeof loadedConfig?.google === 'object') {
85-
config.google = loadedConfig.google;
86-
}
8785
if (typeof loadedConfig?.Connections?.Google === 'object') {
86+
legacyFormat = true;
8887
config.google = loadedConfig.Connections.Google;
8988
}
9089
if (typeof loadedConfig?.Connections?.GoogleToken === 'object') {
90+
legacyFormat = true;
9191
config.google = loadedConfig.Connections.GoogleToken;
9292
}
9393
if (typeof loadedConfig?.options === 'object') {
@@ -103,23 +103,50 @@ function loadConfiguration(filename) {
103103
}
104104
if (key === 'EveApp' && typeof value === 'boolean') {
105105
// Evehome app integration
106+
legacyFormat = true;
106107
config.options.eveHistory = value;
107108
}
108109
if (key === 'Weather' && typeof value === 'boolean') {
109110
// weather device(s)
111+
legacyFormat = true;
110112
config.options.weather = value;
111113
}
112114
if (key === 'HKSV' && typeof value === 'boolean') {
113115
// HomeKit Secure Video
116+
legacyFormat = true;
114117
config.options.hksv = value;
115118
}
116119
if (key === 'HomeKitCode' && typeof value === 'string' && value !== '') {
117120
// HomeKit paring code
121+
legacyFormat = true;
118122
config.options.hkPairingCode = value;
119123
}
120124
if (key === 'Elevation' && isNaN(value) === false) {
125+
// Weather location elevation
126+
legacyFormat = true;
121127
config.options.elevation = Number(value);
122128
}
129+
if (typeof value === 'object' && value?.access_token !== undefined && value?.access_token !== '') {
130+
// Nest access_token
131+
config[key.toLocaleLowerCase()] = {
132+
access_token: value?.access_token,
133+
fieldTest: value?.fieldTest === true,
134+
};
135+
}
136+
if (
137+
typeof value === 'object' &&
138+
value?.issuetoken !== undefined &&
139+
value?.issuetoken !== '' &&
140+
value?.cookie !== undefined &&
141+
value?.cookie !== ''
142+
) {
143+
// Google issue token/cookie
144+
config[key.toLocaleLowerCase()] = {
145+
issuetoken: value?.issuetoken,
146+
cookie: value?.cookie,
147+
fieldTest: value?.fieldTest === true,
148+
};
149+
}
123150

124151
if (
125152
key !== 'Connections' &&
@@ -134,34 +161,61 @@ function loadConfiguration(filename) {
134161
// Since key value is an object, and not an object for a value we expect
135162
// Ssumme its a device configuration for matching serial number
136163
key = key.toUpperCase();
137-
config.devices[key] = {};
138164
Object.entries(value).forEach(([subKey, value]) => {
139165
if (subKey === 'Exclude' && typeof value === 'boolean') {
140166
// Per device excluding
167+
legacyFormat = true;
168+
if (config.devices?.[key] === undefined) {
169+
config.devices[key] = {};
170+
}
141171
config.devices[key]['exclude'] = value;
142172
}
143173
if (subKey === 'HumiditySensor' && typeof value === 'boolean') {
144174
// Seperate humidity sensor for this device (Only valid for thermostats)
175+
legacyFormat = true;
176+
if (config.devices?.[key] === undefined) {
177+
config.devices[key] = {};
178+
}
145179
config.devices[key]['humiditySensor'] = value;
146180
}
147181
if (subKey === 'EveApp' && typeof value === 'boolean') {
148182
// Per device Evehome app integration
183+
legacyFormat = true;
184+
if (config.devices?.[key] === undefined) {
185+
config.devices[key] = {};
186+
}
149187
config.devices[key]['eveHistory'] = value;
150188
}
151189
if (subKey === 'HKSV' && typeof value === 'boolean') {
152190
// Per device HomeKit Secure Video
191+
legacyFormat = true;
192+
if (config.devices?.[key] === undefined) {
193+
config.devices[key] = {};
194+
}
153195
config.devices[key]['hksv'] = value;
154196
}
155197
if (subKey === 'Option.indoor_chime_switch' && typeof value === 'boolean') {
156198
// Per device silence indoor chime
199+
legacyFormat = true;
200+
if (config.devices?.[key] === undefined) {
201+
config.devices[key] = {};
202+
}
157203
config.devices[key]['chimeSwitch'] = value;
158204
}
159205
if (subKey === 'Option.elevation' && isNaN(value) === false) {
160206
// Per device elevation setting (for weather)
207+
legacyFormat = true;
208+
if (config.devices?.[key] === undefined) {
209+
config.devices[key] = {};
210+
}
161211
config.devices[key]['elevation'] = Number(value);
162212
}
163213
if ((subKey === 'HomeKitCode' || subKey === 'hkPairingCode') && typeof value === 'string' && value !== '') {
164214
// Per device HomeKit paring code
215+
legacyFormat = true;
216+
if (config.devices?.[key] === undefined) {
217+
config.devices[key] = {};
218+
}
165219
config.devices[key]['hkPairingCode'] = value;
166220
}
167221
if (subKey === 'DoorbellCooldown' && isNaN(value) === false) {
@@ -170,6 +224,10 @@ function loadConfiguration(filename) {
170224
// If greather than 1000, assume milliseconds value passed in, so convert to seconds
171225
value = Math.floor(value / 1000);
172226
}
227+
legacyFormat = true;
228+
if (config.devices?.[key] === undefined) {
229+
config.devices[key] = {};
230+
}
173231
config.devices[key]['doorbellCooldown'] = value;
174232
}
175233
if (subKey === 'MotionCooldown' && isNaN(value) === false) {
@@ -178,6 +236,10 @@ function loadConfiguration(filename) {
178236
// If greather than 1000, assume milliseconds value passed in, so convert to seconds
179237
value = Math.floor(value / 1000);
180238
}
239+
legacyFormat = true;
240+
if (config.devices?.[key] === undefined) {
241+
config.devices[key] = {};
242+
}
181243
config.devices[key]['motionCooldown'] = value;
182244
}
183245
if (subKey === 'PersonCooldown' && isNaN(value) === false) {
@@ -186,9 +248,17 @@ function loadConfiguration(filename) {
186248
// If greather than 1000, assume milliseconds value passed in, so convert to seconds
187249
value = Math.floor(value / 1000);
188250
}
251+
legacyFormat = true;
252+
if (config.devices?.[key] === undefined) {
253+
config.devices[key] = {};
254+
}
189255
config.devices[key]['personCooldown'] = value;
190256
}
257+
legacyFormat = true;
191258
if (subKey.startsWith('External') === true && typeof value === 'string' && value !== '') {
259+
if (config.devices?.[key] === undefined) {
260+
config.devices[key] = {};
261+
}
192262
config.devices[key]['external' + subKey.substring(8)] = value;
193263
}
194264
});
@@ -200,6 +270,18 @@ function loadConfiguration(filename) {
200270
config.options.hkPairingCode = ACCESSORYPINCODE;
201271
}
202272

273+
// See if we flagged any legacy format options, if so, put warning to user to check and upgrade format/options
274+
if (legacyFormat === true) {
275+
log.prefix = '';
276+
log.warn('');
277+
log.warn('NOTICE');
278+
log.warn('> The loaded configuration file contains legacy options. Please review the readme at the link below');
279+
log.warn('> Consider updating these in your configuration file as the mapping from legacy to current options maybe removed');
280+
log.warn('> https://github.com/n0rt0nthec4t/homebridge-nest-accfactory/blob/main/src/docker-standalone/README.md');
281+
log.warn('');
282+
log.prefix = HomeKitDevice.PLATFORM_NAME;
283+
}
284+
203285
// eslint-disable-next-line no-unused-vars
204286
} catch (error) {
205287
// Empty
@@ -209,7 +291,7 @@ function loadConfiguration(filename) {
209291
}
210292

211293
// Startup code
212-
log.info('Starting ' + __filename + ' using HAP-NodeJS library v' + HAP.HAPLibraryVersion());
294+
log.success(HomeKitDevice.PLUGIN_NAME + ' v' + version + ' (HAP v' + HAP.HAPLibraryVersion() + ') (Node v' + process.versions.node + ')');
213295

214296
// Check to see if a configuration file was passed into use and validate if present
215297
let configurationFile = path.resolve(__dirname + '/' + CONFIGURATIONFILE);
@@ -228,18 +310,14 @@ if (fs.existsSync(configurationFile) === false) {
228310
}
229311

230312
// Have a configuration file, now load the configuration options
231-
log.info('Configuration will be read from "%s"', configurationFile);
232313
let config = loadConfiguration(configurationFile);
233314
if (config === undefined) {
234315
log.info('Configuration file contains invalid JSON options');
235316
log.info('Exiting.');
236317
process.exit(1);
237318
}
238-
if (config?.nest === undefined || config?.google === undefined) {
239-
log.info('Either a Nest and/or Google connection details were not specified in the configuration file');
240-
log.info('Exiting.');
241-
process.exit(1);
242-
}
319+
320+
log.info('Loaded configuration from "%s"', configurationFile);
243321

244322
log.info(
245323
'Devices will be advertised to HomeKit using "%s" mDNS provider',

src/docker-standalone/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"displayName": "Nest Accfactory",
33
"name": "nest-accfactory",
44
"homepage": "https://github.com/n0rt0nthec4t/homebridge-nest-accfactory/blob/main/src/docker-standalone/README.md",
5-
"version": "0.2.1",
5+
"version": "0.2.2",
66
"description": "HomeKit integration for Nest devices using HAP-NodeJS library",
77
"license": "Apache-2.0",
88
"author": "n0rt0nthec4t",

0 commit comments

Comments
 (0)