homebridge-freeathome-local-api 0.1.0-pre

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 (42) hide show
  1. package/.eslintignore +6 -0
  2. package/.nycrc.json +6 -0
  3. package/.prettierignore +6 -0
  4. package/.prettierrc +5 -0
  5. package/CHANGELOG.md +15 -0
  6. package/CODEOWNERS +8 -0
  7. package/LICENSE +21 -0
  8. package/README.md +69 -0
  9. package/config.schema.json +51 -0
  10. package/dist/binarySensorAccessory.d.ts +26 -0
  11. package/dist/binarySensorAccessory.d.ts.map +1 -0
  12. package/dist/binarySensorAccessory.js +61 -0
  13. package/dist/binarySensorAccessory.js.map +1 -0
  14. package/dist/enumerations.d.ts +9 -0
  15. package/dist/enumerations.d.ts.map +1 -0
  16. package/dist/enumerations.js +13 -0
  17. package/dist/enumerations.js.map +1 -0
  18. package/dist/freeAtHomeAccessory.d.ts +23 -0
  19. package/dist/freeAtHomeAccessory.d.ts.map +1 -0
  20. package/dist/freeAtHomeAccessory.js +23 -0
  21. package/dist/freeAtHomeAccessory.js.map +1 -0
  22. package/dist/freeAtHomeContext.d.ts +17 -0
  23. package/dist/freeAtHomeContext.d.ts.map +1 -0
  24. package/dist/freeAtHomeContext.js +22 -0
  25. package/dist/freeAtHomeContext.js.map +1 -0
  26. package/dist/index.d.ts +5 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +12 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/platform.d.ts +39 -0
  31. package/dist/platform.d.ts.map +1 -0
  32. package/dist/platform.js +164 -0
  33. package/dist/platform.js.map +1 -0
  34. package/dist/settings.d.ts +9 -0
  35. package/dist/settings.d.ts.map +1 -0
  36. package/dist/settings.js +12 -0
  37. package/dist/settings.js.map +1 -0
  38. package/jasmine.json +9 -0
  39. package/package.json +65 -0
  40. package/test/example.spec.ts +13 -0
  41. package/test.ts +18 -0
  42. package/tsconfig.spec.json +8 -0
package/.eslintignore ADDED
@@ -0,0 +1,6 @@
1
+ .github
2
+ .vscode
3
+ coverage
4
+ dist
5
+ node_modules
6
+ package-lock.json
package/.nycrc.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "@istanbuljs/nyc-config-typescript",
3
+ "all": true,
4
+ "reporter": ["text", "lcov"],
5
+ "include": ["src"]
6
+ }
@@ -0,0 +1,6 @@
1
+ .github
2
+ .vscode
3
+ coverage
4
+ dist
5
+ node_modules
6
+ package-lock.json
package/.prettierrc ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "trailingComma": "es5",
3
+ "semi": true,
4
+ "tabWidth": 2
5
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## 0.1.0-pre - 14.06.2022
9
+
10
+ ### Added
11
+
12
+ - [PG-144](https://pgerke.atlassian.net/browse/PG-144):
13
+ Initial vertical increment, not published to npmjs.org yet.
14
+ - [PG-146](https://pgerke.atlassian.net/browse/PG-146):
15
+ Support binary switch
package/CODEOWNERS ADDED
@@ -0,0 +1,8 @@
1
+ # This is a comment.
2
+ # Each line is a file pattern followed by one or more owners.
3
+
4
+ # These owners will be the default owners for everything in
5
+ # the repo. Unless a later match takes precedence,
6
+ # @global-owner1 and @global-owner2 will be requested for
7
+ # review when someone opens a pull request.
8
+ * @pgerke
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Philip Gerke
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # homebridge-freeathome-local-api
2
+
3
+ A Homebridge plugin that allows the user to control BUSCH-JAEGER free@home devices using the System Access Point local API.
4
+
5
+ ![CI](https://img.shields.io/github/workflow/status/pgerke/homebridge-freeathome-local-api/Continuous%20Integration?style=flat-square)
6
+ [![codecov](https://codecov.io/gh/pgerke/homebridge-freeathome-local-api/branch/main/graph/badge.svg?token=V5ICB2MGH0)](https://codecov.io/gh/pgerke/homebridge-freeathome-local-api)
7
+ ![Dependencies](https://img.shields.io/librariesio/release/npm/homebridge-freeathome-local-api?style=flat-square)
8
+ ![npm](https://img.shields.io/npm/v/homebridge-freeathome-local-api?style=flat-square)
9
+ ![License](https://img.shields.io/github/license/pgerke/homebridge-freeathome-local-api?style=flat-square)
10
+
11
+ ## Features
12
+
13
+ - Control your BUSCH-JAEGER free@home lights, outlets, heating regulartors and more with your Apple devices
14
+ - Ask Siri to control your devices and set automations with Apple Home
15
+ - Based on the local API provided by the System Access Point running firmware version >2.6.0
16
+ - 100% covered by automated unit tests
17
+
18
+ # Supported accessories
19
+
20
+ - Binary Sensors
21
+ - Outlets
22
+ - Lights
23
+
24
+ That's not that much yet, but keep your eyes peeled, new accessories are coming up soon:
25
+
26
+ - Dimmable Lights
27
+ - Thermostats
28
+
29
+ I'll add further accessories over time, but feel free to request your favorite accessory type in a [GitHub issue](https://github.com/pgerke/homebridge-freeathome-local-api/issues).
30
+
31
+ ## Requirements
32
+
33
+ - free@home Access Point running firmware version >2.6.0
34
+ - Access to an user account that has access to the local API
35
+
36
+ ## Changelog
37
+
38
+ The changelog can be viewed [here](CHANGELOG.md).
39
+
40
+ ## I found a bug, what do I do?
41
+
42
+ I'm happy to hear any feedback regarding the plugin or it's implementation, be it critizism, praise or rants. Please create a [GitHub issue](https://github.com/pgerke/homebridge-freeathome-local-api/issues) or drop me an [email](mailto:info@philipgerke.com) if you would like to contact me.
43
+
44
+ I would especially appreciate, if you could report any issues you encounter while using the library. Issues I know about, I can probably fix.
45
+
46
+ If you want to submit a bug report, please check if the issue you have has already been reported. If you want to contribute additional information to the issue, please add it to the existing issue instead of creating another one. Duplicate issues will take time from bugfixing and thus delay a fix.
47
+
48
+ While creating a bug report, please make it easy for me to fix it by giving us all the details you have about the issue. Always include the version of the library and a short concise description of the issue. Besides that, there are a few other pieces of information that help tracking down bugs:
49
+
50
+ - The system environment in which the issue occurred (e.g. node version)
51
+ - Some steps to reproduce the issue, e.g. a code snippet
52
+ - The expected behaviour and how the failed failed to meet that expectation
53
+ - Anything else you think I might need
54
+
55
+ ## I have a feature request, what do I do?
56
+
57
+ Please create a [GitHub issue](https://github.com/pgerke/homebridge-freeathome-local-apihomebridge-freeathome-local-api/issues) or drop me an [email](mailto:info@philipgerke.com)!
58
+
59
+ ## Non-Affiliation Disclaimer
60
+
61
+ This plugin is not endorsed by, directly affiliated with, maintained, authorized, or sponsored by Busch-Jaeger Elektro GmbH or ABB Asea Brown Boveri Ltd or . All product and company names are the registered trademarks of their original owners. The use of any trade name or trademark is for identification and reference purposes only and does not imply any association with the trademark holder of their product brand.
62
+
63
+ ## License
64
+
65
+ The project is subject to the MIT license unless otherwise noted. A copy can be found in the root directory of the project [LICENSE](./LICENSE).
66
+
67
+ <hr>
68
+
69
+ Made with ❤️ by [Philip Gerke](https://github.com/pgerke)
@@ -0,0 +1,51 @@
1
+ {
2
+ "pluginAlias": "FreeAtHomeLocalApi",
3
+ "pluginType": "platform",
4
+ "singular": true,
5
+ "headerDisplay": "A Homebridge plugin for interfacing with a BUSCH-JAEGER free@home setup.",
6
+ "footerDisplay": "Control you free@home system with Apple Home using the System Access Point local API.",
7
+ "schema": {
8
+ "type": "object",
9
+ "properties": {
10
+ "title": "Name",
11
+ "type": "string",
12
+ "required": true,
13
+ "default": "My free@home Setup"
14
+ },
15
+ "host": {
16
+ "title": "System Access Point Hostname",
17
+ "description": "The system access point host name",
18
+ "placeholder": "SysAP Host Name",
19
+ "type": "string",
20
+ "required": true
21
+ },
22
+ "user": {
23
+ "title": "User ID",
24
+ "description": "The user name that shall be used to authenticate with the system access point.",
25
+ "placeholder": "SysAP User",
26
+ "type": "string",
27
+ "required": true
28
+ },
29
+ "password": {
30
+ "title": "Password",
31
+ "description": "The password that shall be used to authenticate with the system access point",
32
+ "placeholder": "SysAP Password",
33
+ "type": "string",
34
+ "required": true
35
+ },
36
+ "tlsEnabled ": {
37
+ "title": "TLS Enabled",
38
+ "description": "Determines whether the communication with the system access point shall be protected by TLS. Disabling TLS poses a security risk!",
39
+ "type": "boolean",
40
+ "required": false,
41
+ "default": true
42
+ },
43
+ "verboseErrors ": {
44
+ "title": "Verbose Errors",
45
+ "description": "Determines whether verbose error messages shall be used, for example for message validation. This is a debug option that should only be enabled if needed.",
46
+ "type": "boolean",
47
+ "required": false,
48
+ "default": false
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,26 @@
1
+ import { PlatformAccessory } from "homebridge";
2
+ import { FreeAtHomeAccessory } from "./freeAtHomeAccessory";
3
+ import { FreeAtHomeContext } from "./freeAtHomeContext";
4
+ import { FreeAtHomeHomebridgePlatform } from "./platform";
5
+ /**
6
+ * A binary sensor accessory.
7
+ * @description
8
+ * A binary sensor can be used to control more or less any that free&#64;home device
9
+ * that has a binary on/off power state exposed on data point 0000 like, for example,
10
+ * binary switches or dimmers.
11
+ */
12
+ export declare class BinarySensorAccessory extends FreeAtHomeAccessory {
13
+ readonly platform: FreeAtHomeHomebridgePlatform;
14
+ readonly accessory: PlatformAccessory<FreeAtHomeContext>;
15
+ private readonly service;
16
+ /**
17
+ * Constructs a new binary sensor accessory instance.
18
+ * @param platform The free&#64;home Homebridge platform controlling the accessory
19
+ * @param accessory The platform accessory.
20
+ */
21
+ constructor(platform: FreeAtHomeHomebridgePlatform, accessory: PlatformAccessory<FreeAtHomeContext>);
22
+ private setOn;
23
+ private getOn;
24
+ updateDatapoint(datapoint: string, value: string): void;
25
+ }
26
+ //# sourceMappingURL=binarySensorAccessory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binarySensorAccessory.d.ts","sourceRoot":"","sources":["../src/binarySensorAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,iBAAiB,EAAW,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAa,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;GAMG;AACH,qBAAa,qBAAsB,SAAQ,mBAAmB;IAS1D,QAAQ,CAAC,QAAQ,EAAE,4BAA4B;IAC/C,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,iBAAiB,CAAC;IAT1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC;;;;OAIG;gBAEQ,QAAQ,EAAE,4BAA4B,EACtC,SAAS,EAAE,iBAAiB,CAAC,iBAAiB,CAAC;YAgB5C,KAAK;YAkBL,KAAK;IAsBH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CAoBxE"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BinarySensorAccessory = void 0;
4
+ const freeAtHomeAccessory_1 = require("./freeAtHomeAccessory");
5
+ const platform_1 = require("./platform");
6
+ /**
7
+ * A binary sensor accessory.
8
+ * @description
9
+ * A binary sensor can be used to control more or less any that free&#64;home device
10
+ * that has a binary on/off power state exposed on data point 0000 like, for example,
11
+ * binary switches or dimmers.
12
+ */
13
+ class BinarySensorAccessory extends freeAtHomeAccessory_1.FreeAtHomeAccessory {
14
+ /**
15
+ * Constructs a new binary sensor accessory instance.
16
+ * @param platform The free&#64;home Homebridge platform controlling the accessory
17
+ * @param accessory The platform accessory.
18
+ */
19
+ constructor(platform, accessory) {
20
+ super(platform, accessory);
21
+ this.platform = platform;
22
+ this.accessory = accessory;
23
+ // get the Switch service if it exists, otherwise create a new service instance
24
+ this.service =
25
+ this.accessory.getService(this.platform.Service.Switch) ||
26
+ this.accessory.addService(this.platform.Service.Switch);
27
+ // register handlers for the On/Off Characteristic
28
+ this.service
29
+ .getCharacteristic(this.platform.Characteristic.On)
30
+ .onSet(this.setOn.bind(this))
31
+ .onGet(this.getOn.bind(this));
32
+ }
33
+ async setOn(value) {
34
+ // log event
35
+ this.platform.log.info(`${this.accessory.displayName} (Binary Sensor ${this.serialNumber}) set characteristic On -> ${value.toString()}`);
36
+ // set data point at SysAP
37
+ await this.platform.sysap.setDatapoint(platform_1.emptyGuid, this.accessory.context.deviceSerial, this.accessory.context.channelId, "idp0000", value ? "1" : "0");
38
+ }
39
+ async getOn() {
40
+ // get data point from SysAP
41
+ const response = await this.platform.sysap.getDatapoint(platform_1.emptyGuid, this.accessory.context.deviceSerial, this.accessory.context.channelId, "odp0000");
42
+ // parse value
43
+ const value = !!parseInt(response[platform_1.emptyGuid].values[0]);
44
+ // log event
45
+ this.platform.log.info(`${this.accessory.displayName} (Binary Sensor ${this.serialNumber}) get characteristic On -> ${value.toString()}`);
46
+ return value;
47
+ }
48
+ updateDatapoint(datapoint, value) {
49
+ // ignore unknown data points
50
+ if (datapoint !== "odp0000")
51
+ return;
52
+ // parse value
53
+ const characteristicValue = !!parseInt(value);
54
+ // log event
55
+ this.platform.log.info(`${this.accessory.displayName} (Binary Sensor ${this.serialNumber}) updated characteristic On -> ${characteristicValue.toString()}`);
56
+ // asynchoronously update the characteristic
57
+ this.service.updateCharacteristic(this.platform.Characteristic.On, characteristicValue);
58
+ }
59
+ }
60
+ exports.BinarySensorAccessory = BinarySensorAccessory;
61
+ //# sourceMappingURL=binarySensorAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binarySensorAccessory.js","sourceRoot":"","sources":["../src/binarySensorAccessory.ts"],"names":[],"mappings":";;;AACA,+DAA4D;AAE5D,yCAAqE;AAErE;;;;;;GAMG;AACH,MAAa,qBAAsB,SAAQ,yCAAmB;IAG5D;;;;OAIG;IACH,YACW,QAAsC,EACtC,SAA+C;QAExD,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAHlB,aAAQ,GAAR,QAAQ,CAA8B;QACtC,cAAS,GAAT,SAAS,CAAsC;QAIxD,+EAA+E;QAC/E,IAAI,CAAC,OAAO;YACV,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;gBACvD,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAE1D,kDAAkD;QAClD,IAAI,CAAC,OAAO;aACT,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;aAClD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAC5B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAClC,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,KAA0B;QAC5C,YAAY;QACZ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CACpB,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,mBAC3B,IAAI,CAAC,YACP,8BAA8B,KAAK,CAAC,QAAQ,EAAE,EAAE,CACjD,CAAC;QAEF,0BAA0B;QAC1B,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CACpC,oBAAS,EACT,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,EACnC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAChC,SAAS,EACT,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAClB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,KAAK;QACjB,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CACrD,oBAAS,EACT,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,EACnC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAChC,SAAS,CACV,CAAC;QAEF,cAAc;QACd,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,oBAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAExD,YAAY;QACZ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CACpB,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,mBAC3B,IAAI,CAAC,YACP,8BAA8B,KAAK,CAAC,QAAQ,EAAE,EAAE,CACjD,CAAC;QAEF,OAAO,KAAK,CAAC;IACf,CAAC;IAEe,eAAe,CAAC,SAAiB,EAAE,KAAa;QAC9D,6BAA6B;QAC7B,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO;QAEpC,cAAc;QACd,MAAM,mBAAmB,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE9C,YAAY;QACZ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CACpB,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,mBAC3B,IAAI,CAAC,YACP,kCAAkC,mBAAmB,CAAC,QAAQ,EAAE,EAAE,CACnE,CAAC;QAEF,4CAA4C;QAC5C,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAC/B,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,EAC/B,mBAAmB,CACpB,CAAC;IACJ,CAAC;CACF;AAtFD,sDAsFC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The enumeration containing the supported function IDs as defined at
3
+ * https://developer.eu.mybuildings.abb.com/fah_local/reference/functionids/
4
+ */
5
+ export declare enum FunctionID {
6
+ /** A (binary) switch actuator */
7
+ FID_SWITCH_ACTUATOR = "7"
8
+ }
9
+ //# sourceMappingURL=enumerations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enumerations.d.ts","sourceRoot":"","sources":["../src/enumerations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,oBAAY,UAAU;IACpB,kCAAkC;IAClC,mBAAmB,MAAM;CAC1B"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FunctionID = void 0;
4
+ /**
5
+ * The enumeration containing the supported function IDs as defined at
6
+ * https://developer.eu.mybuildings.abb.com/fah_local/reference/functionids/
7
+ */
8
+ var FunctionID;
9
+ (function (FunctionID) {
10
+ /** A (binary) switch actuator */
11
+ FunctionID["FID_SWITCH_ACTUATOR"] = "7";
12
+ })(FunctionID = exports.FunctionID || (exports.FunctionID = {}));
13
+ //# sourceMappingURL=enumerations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enumerations.js","sourceRoot":"","sources":["../src/enumerations.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,kCAAkC;IAClC,uCAAyB,CAAA;AAC3B,CAAC,EAHW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAGrB"}
@@ -0,0 +1,23 @@
1
+ import { PlatformAccessory } from "homebridge";
2
+ import { FreeAtHomeContext } from "./freeAtHomeContext";
3
+ import { FreeAtHomeHomebridgePlatform } from "./platform";
4
+ /** The abstract base class for all free&#64;home accessories.*/
5
+ export declare abstract class FreeAtHomeAccessory {
6
+ protected readonly platform: FreeAtHomeHomebridgePlatform;
7
+ protected readonly accessory: PlatformAccessory<FreeAtHomeContext>;
8
+ /** The serial number consisting of the free&#64;home device serial and the channel ID. */
9
+ protected readonly serialNumber: string;
10
+ /**
11
+ * Constructs a new free&#64;home accessory instance.
12
+ * @param platform The free&#64;home Homebridge platform controlling the accessory
13
+ * @param accessory The platform accessory.
14
+ */
15
+ constructor(platform: FreeAtHomeHomebridgePlatform, accessory: PlatformAccessory<FreeAtHomeContext>);
16
+ /**
17
+ * Asynchonously updates accessory characteristics from a datapoint.
18
+ * @param datapoint The updated data point.
19
+ * @param value A string representing the new value.
20
+ */
21
+ abstract updateDatapoint(datapoint: string, value: string): void;
22
+ }
23
+ //# sourceMappingURL=freeAtHomeAccessory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freeAtHomeAccessory.d.ts","sourceRoot":"","sources":["../src/freeAtHomeAccessory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE1D,gEAAgE;AAChE,8BAAsB,mBAAmB;IAUrC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,4BAA4B;IACzD,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,iBAAiB,CAAC;IAVpE,0FAA0F;IAC1F,SAAS,CAAC,QAAQ,CAAC,YAAY,SAAkF;IAEjH;;;;OAIG;gBAEkB,QAAQ,EAAE,4BAA4B,EACtC,SAAS,EAAE,iBAAiB,CAAC,iBAAiB,CAAC;IAmBpE;;;;OAIG;aACa,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CACxE"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FreeAtHomeAccessory = void 0;
4
+ /** The abstract base class for all free&#64;home accessories.*/
5
+ class FreeAtHomeAccessory {
6
+ /**
7
+ * Constructs a new free&#64;home accessory instance.
8
+ * @param platform The free&#64;home Homebridge platform controlling the accessory
9
+ * @param accessory The platform accessory.
10
+ */
11
+ constructor(platform, accessory) {
12
+ var _a, _b;
13
+ this.platform = platform;
14
+ this.accessory = accessory;
15
+ /** The serial number consisting of the free&#64;home device serial and the channel ID. */
16
+ this.serialNumber = `${this.accessory.context.deviceSerial} (${this.accessory.context.channelId})`;
17
+ // set accessory information
18
+ (_a = this.accessory
19
+ .getService(this.platform.Service.AccessoryInformation)) === null || _a === void 0 ? void 0 : _a.setCharacteristic(this.platform.Characteristic.Manufacturer, "BUSCH-JAEGER").setCharacteristic(this.platform.Characteristic.Model, (_b = accessory.context.device.displayName) !== null && _b !== void 0 ? _b : "Unknown Model").setCharacteristic(this.platform.Characteristic.SerialNumber, this.serialNumber);
20
+ }
21
+ }
22
+ exports.FreeAtHomeAccessory = FreeAtHomeAccessory;
23
+ //# sourceMappingURL=freeAtHomeAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freeAtHomeAccessory.js","sourceRoot":"","sources":["../src/freeAtHomeAccessory.ts"],"names":[],"mappings":";;;AAIA,gEAAgE;AAChE,MAAsB,mBAAmB;IAIvC;;;;OAIG;IACH,YACqB,QAAsC,EACtC,SAA+C;;QAD/C,aAAQ,GAAR,QAAQ,CAA8B;QACtC,cAAS,GAAT,SAAS,CAAsC;QAVpE,0FAA0F;QACvE,iBAAY,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC;QAW/G,4BAA4B;QAC5B,MAAA,IAAI,CAAC,SAAS;aACX,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,0CACrD,iBAAiB,CACjB,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,YAAY,EACzC,cAAc,EAEf,iBAAiB,CAChB,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,EAClC,MAAA,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,mCAAI,eAAe,EAExD,iBAAiB,CAChB,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,YAAY,EACzC,IAAI,CAAC,YAAY,CAClB,CAAC;IACN,CAAC;CAQF;AApCD,kDAoCC"}
@@ -0,0 +1,17 @@
1
+ import { Channel, Device, Logger } from "freeathome-local-api-client";
2
+ import { PlatformAccessory, UnknownContext } from "homebridge/lib/platformAccessory";
3
+ /** Describes the context of a free&#64;home accessory. */
4
+ export interface FreeAtHomeContext {
5
+ channel: Channel;
6
+ channelId: string;
7
+ deviceSerial: string;
8
+ device: Device;
9
+ }
10
+ /**
11
+ * Determines whether the specified accessory is a free&#64;home accessory.
12
+ * @param accessory The accessory to be tested
13
+ * @param logger {Logger} The logger instance to be used.
14
+ * @returns {boolean} A value indicating whether the specified object is a free&#64;home accessory.
15
+ */
16
+ export declare function isFreeAtHomeAccessory(accessory: PlatformAccessory<UnknownContext>, logger: Logger): accessory is PlatformAccessory<FreeAtHomeContext>;
17
+ //# sourceMappingURL=freeAtHomeContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freeAtHomeContext.d.ts","sourceRoot":"","sources":["../src/freeAtHomeContext.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,MAAM,EAGN,MAAM,EACP,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,iBAAiB,EACjB,cAAc,EACf,MAAM,kCAAkC,CAAC;AAE1C,0DAA0D;AAC1D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,iBAAiB,CAAC,cAAc,CAAC,EAC5C,MAAM,EAAE,MAAM,GACb,SAAS,IAAI,iBAAiB,CAAC,iBAAiB,CAAC,CAanD"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isFreeAtHomeAccessory = void 0;
4
+ const freeathome_local_api_client_1 = require("freeathome-local-api-client");
5
+ /**
6
+ * Determines whether the specified accessory is a free&#64;home accessory.
7
+ * @param accessory The accessory to be tested
8
+ * @param logger {Logger} The logger instance to be used.
9
+ * @returns {boolean} A value indicating whether the specified object is a free&#64;home accessory.
10
+ */
11
+ function isFreeAtHomeAccessory(accessory, logger) {
12
+ const keys = Object.keys(accessory.context);
13
+ const hasKeys = keys.includes("device") &&
14
+ keys.includes("deviceSerial") &&
15
+ keys.includes("channel") &&
16
+ keys.includes("channelId");
17
+ return (hasKeys &&
18
+ (0, freeathome_local_api_client_1.isChannel)(accessory.context.channel, logger) &&
19
+ (0, freeathome_local_api_client_1.isDevice)(accessory.context.device, logger));
20
+ }
21
+ exports.isFreeAtHomeAccessory = isFreeAtHomeAccessory;
22
+ //# sourceMappingURL=freeAtHomeContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freeAtHomeContext.js","sourceRoot":"","sources":["../src/freeAtHomeContext.ts"],"names":[],"mappings":";;;AAAA,6EAMqC;AAcrC;;;;;GAKG;AACH,SAAgB,qBAAqB,CACnC,SAA4C,EAC5C,MAAc;IAEd,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,OAAO,GACX,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACvB,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAE7B,OAAO,CACL,OAAO;QACP,IAAA,uCAAS,EAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC;QAC5C,IAAA,sCAAQ,EAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAC3C,CAAC;AACJ,CAAC;AAhBD,sDAgBC"}
@@ -0,0 +1,5 @@
1
+ import { API } from "homebridge";
2
+ /** This method registers the platform with Homebridge */
3
+ declare const _default: (api: API) => void;
4
+ export = _default;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAMjC,yDAAyD;8BAC1C,GAAG;AAAlB,kBAEE"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const settings_1 = require("./settings");
6
+ const platform_1 = require("./platform");
7
+ const node_fetch_1 = __importDefault(require("node-fetch"));
8
+ globalThis.fetch = node_fetch_1.default;
9
+ module.exports = (api) => {
10
+ api.registerPlatform(settings_1.PLATFORM_NAME, platform_1.FreeAtHomeHomebridgePlatform);
11
+ };
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AACA,yCAA2C;AAC3C,yCAA0D;AAC1D,4DAA+B;AAC/B,UAAU,CAAC,KAAK,GAAG,oBAAK,CAAC;AAGzB,iBAAS,CAAC,GAAQ,EAAE,EAAE;IACpB,GAAG,CAAC,gBAAgB,CAAC,wBAAa,EAAE,uCAA4B,CAAC,CAAC;AACpE,CAAC,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig, Service, Characteristic } from "homebridge";
2
+ import { SystemAccessPoint } from "freeathome-local-api-client";
3
+ import { FreeAtHomeContext } from "./freeAtHomeContext";
4
+ export declare const emptyGuid = "00000000-0000-0000-0000-000000000000";
5
+ /** The free&#64;home Homebridge platform. */
6
+ export declare class FreeAtHomeHomebridgePlatform implements DynamicPlatformPlugin {
7
+ readonly log: Logger;
8
+ readonly config: PlatformConfig;
9
+ readonly api: API;
10
+ /** The service reference */
11
+ readonly Service: typeof Service;
12
+ /** The characteristic reference */
13
+ readonly Characteristic: typeof Characteristic;
14
+ /** The list of restored cached accessories */
15
+ readonly accessories: Array<PlatformAccessory<FreeAtHomeContext>>;
16
+ /** The system access point */
17
+ readonly sysap: SystemAccessPoint;
18
+ private fahAccessories;
19
+ private fahLogger;
20
+ /**
21
+ * Constructs a new free&#64;home Homebridge platform instance.
22
+ * @param log {Logger} The logger instance.
23
+ * @param config {PlatformConfig} The platform configuration.
24
+ * @param api {API} The API instance.
25
+ */
26
+ constructor(log: Logger, config: PlatformConfig, api: API);
27
+ /**
28
+ * Configures the specified accessory.
29
+ * @param accessory The accessory to be configured.
30
+ * @description
31
+ * This function is invoked when homebridge restores cached accessories from disk at startup.
32
+ * It should be used to setup event handlers for characteristics and update respective values.
33
+ */
34
+ configureAccessory(accessory: PlatformAccessory): void;
35
+ /** Discovers the supported free&#64;home devices from the System Access Point. */
36
+ private discoverDevices;
37
+ private processWebSocketMesage;
38
+ }
39
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EACH,qBAAqB,EACrB,MAAM,EACN,iBAAiB,EACjB,cAAc,EACd,OAAO,EACP,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,iBAAiB,EAIlB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,iBAAiB,EAAyB,MAAM,qBAAqB,CAAC;AAK/E,eAAO,MAAM,SAAS,yCAAyC,CAAC;AAEhE,6CAA6C;AAC7C,qBAAa,4BAA6B,YAAW,qBAAqB;aAoBtD,GAAG,EAAE,MAAM;aACX,MAAM,EAAE,cAAc;aACtB,GAAG,EAAE,GAAG;IArB1B,4BAA4B;IAC5B,SAAgB,OAAO,EAAE,OAAO,OAAO,CAAwB;IAC/D,mCAAmC;IACnC,SAAgB,cAAc,EAAE,OAAO,cAAc,CACvB;IAC9B,8CAA8C;IAC9C,SAAgB,WAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC,CAAM;IAC9E,8BAA8B;IAC9B,SAAgB,KAAK,EAAE,iBAAiB,CAAC;IACzC,OAAO,CAAC,cAAc,CAA0C;IAChE,OAAO,CAAC,SAAS,CAAmB;IAEpC;;;;;OAKG;gBAEe,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,GAAG;IAkD1B;;;;;;OAMG;IACI,kBAAkB,CAAC,SAAS,EAAE,iBAAiB;IAQtD,kFAAkF;YACpE,eAAe;IAsG7B,OAAO,CAAC,sBAAsB;CAwB/B"}
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FreeAtHomeHomebridgePlatform = exports.emptyGuid = void 0;
4
+ const settings_1 = require("./settings");
5
+ const freeathome_local_api_client_1 = require("freeathome-local-api-client");
6
+ const binarySensorAccessory_1 = require("./binarySensorAccessory");
7
+ const freeAtHomeContext_1 = require("./freeAtHomeContext");
8
+ const enumerations_1 = require("./enumerations");
9
+ // In the local API the system access point UUID is always an empty UUID. Could be extended later to also support the cloud API.
10
+ exports.emptyGuid = "00000000-0000-0000-0000-000000000000";
11
+ /** The free&#64;home Homebridge platform. */
12
+ class FreeAtHomeHomebridgePlatform {
13
+ /**
14
+ * Constructs a new free&#64;home Homebridge platform instance.
15
+ * @param log {Logger} The logger instance.
16
+ * @param config {PlatformConfig} The platform configuration.
17
+ * @param api {API} The API instance.
18
+ */
19
+ constructor(log, config, api) {
20
+ this.log = log;
21
+ this.config = config;
22
+ this.api = api;
23
+ /** The service reference */
24
+ this.Service = this.api.hap.Service;
25
+ /** The characteristic reference */
26
+ this.Characteristic = this.api.hap.Characteristic;
27
+ /** The list of restored cached accessories */
28
+ this.accessories = [];
29
+ this.fahAccessories = new Map();
30
+ // Create a logger for the free&#64;home Local API Client
31
+ this.fahLogger = {
32
+ debug: (message, ...optionalParams) => { var _a; return log.debug((_a = message) !== null && _a !== void 0 ? _a : "", ...optionalParams); },
33
+ error: (message, ...optionalParams) => { var _a; return log.error((_a = message) !== null && _a !== void 0 ? _a : "", ...optionalParams); },
34
+ log: (message, ...optionalParams) => { var _a; return log.info((_a = message) !== null && _a !== void 0 ? _a : "", ...optionalParams); },
35
+ warn: (message, ...optionalParams) => { var _a; return log.warn((_a = message) !== null && _a !== void 0 ? _a : "", ...optionalParams); },
36
+ };
37
+ // Create a system access point instance
38
+ this.sysap = new freeathome_local_api_client_1.SystemAccessPoint(this.config.host, this.config.user, this.config.password, this.config.tlsEnabled, this.config.verboseErrors, this.fahLogger);
39
+ // Subscribe to web socket messages
40
+ this.sysap
41
+ .getWebSocketMessages()
42
+ .subscribe((message) => this.processWebSocketMesage(message));
43
+ this.log.debug("Finished initializing platform:", this.config.name);
44
+ // When Homebridge has restored all cached accessories from disk we can start discovery of new accessories.
45
+ this.api.on("didFinishLaunching", () => {
46
+ log.debug("Executed didFinishLaunching callback");
47
+ // run discovery
48
+ this.discoverDevices()
49
+ .then(() => this.log.info(`Discovery completed: ${this.fahAccessories.size} accessories detected`))
50
+ .catch((error) => this.log.error("Device discovery failed", error));
51
+ // Connect to system access point web socket
52
+ this.sysap.connectWebSocket(this.config.tlsEnabled);
53
+ });
54
+ }
55
+ /**
56
+ * Configures the specified accessory.
57
+ * @param accessory The accessory to be configured.
58
+ * @description
59
+ * This function is invoked when homebridge restores cached accessories from disk at startup.
60
+ * It should be used to setup event handlers for characteristics and update respective values.
61
+ */
62
+ configureAccessory(accessory) {
63
+ this.log.info("Loading accessory from cache:", accessory.displayName);
64
+ // add the restored accessory to the accessories cache so we can track if it has already been registered
65
+ if ((0, freeAtHomeContext_1.isFreeAtHomeAccessory)(accessory, this.fahLogger))
66
+ this.accessories.push(accessory);
67
+ }
68
+ /** Discovers the supported free&#64;home devices from the System Access Point. */
69
+ async discoverDevices() {
70
+ // Get the SysAP configuration
71
+ const config = await this.sysap.getConfiguration();
72
+ // Enmumerate the devices
73
+ Object.keys(config[exports.emptyGuid].devices).forEach((serial) => {
74
+ // Filter unsupported (pseudo) devices like scenes or third party devices
75
+ if (!serial.startsWith("ABB"))
76
+ return;
77
+ const device = config[exports.emptyGuid].devices[serial];
78
+ if (!device.channels)
79
+ return;
80
+ // Enumerate the channels
81
+ Object.keys(device.channels).forEach((channelId) => {
82
+ var _a, _b, _c, _d;
83
+ const channel = (_a = device.channels) === null || _a === void 0 ? void 0 : _a[channelId];
84
+ if (!channel)
85
+ return;
86
+ // Filter unsupported channels
87
+ if (!(channel.functionID &&
88
+ Object.values(enumerations_1.FunctionID).includes(channel.functionID))) {
89
+ this.log.debug(`Ignored ${serial} (${channelId}): FunctionID '${(_b = channel.functionID) !== null && _b !== void 0 ? _b : "<UNDEFINED>"}' is not supported.`);
90
+ return;
91
+ }
92
+ // Filter unconfigured devices
93
+ if (!(channel.floor && channel.room)) {
94
+ this.log.debug(`Ignored ${serial} (${channelId}): Floor and room are not configured.`);
95
+ return;
96
+ }
97
+ // Create or restore the accessory
98
+ const uuid = this.api.hap.uuid.generate(`${serial}_${channelId}`);
99
+ let accessory = this.accessories.find((accessory) => accessory.UUID === uuid);
100
+ if (accessory) {
101
+ // the accessory already exists
102
+ this.log.info("Restoring existing accessory from cache:", accessory.displayName);
103
+ // Update context
104
+ accessory.context.deviceSerial = serial;
105
+ accessory.context.device = device;
106
+ accessory.context.channel = channel;
107
+ accessory.context.channelId = channelId;
108
+ this.api.updatePlatformAccessories([accessory]);
109
+ // it is possible to remove platform accessories at any time using `api.unregisterPlatformAccessories`, eg.:
110
+ // remove platform accessories when no longer present
111
+ // this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [existingAccessory]);
112
+ // this.log.info('Removing existing accessory from cache:', existingAccessory.displayName);
113
+ }
114
+ else {
115
+ // the accessory does not yet exist, so we need to create it
116
+ this.log.info("Adding new accessory:", channel.displayName);
117
+ // create a new accessory
118
+ accessory = new this.api.platformAccessory((_c = channel.displayName) !== null && _c !== void 0 ? _c : uuid, uuid);
119
+ accessory.context.deviceSerial = serial;
120
+ accessory.context.device = device;
121
+ accessory.context.channel = channel;
122
+ accessory.context.channelId = channelId;
123
+ // link the accessory to your platform
124
+ this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [
125
+ accessory,
126
+ ]);
127
+ }
128
+ // Ignore non free&#64;home accessories
129
+ if (!(0, freeAtHomeContext_1.isFreeAtHomeAccessory)(accessory, this.fahLogger))
130
+ return;
131
+ // create accessory
132
+ switch (channel.functionID) {
133
+ case enumerations_1.FunctionID.FID_SWITCH_ACTUATOR:
134
+ this.fahAccessories.set(`${serial}_${channelId}`, new binarySensorAccessory_1.BinarySensorAccessory(this, accessory));
135
+ return;
136
+ default:
137
+ this.log.error(`${serial} (${channelId}): Cannot configure accessory for FunctionID '${(_d = channel.functionID) !== null && _d !== void 0 ? _d : "<UNDEFINED>"}'!`);
138
+ }
139
+ });
140
+ });
141
+ }
142
+ processWebSocketMesage(message) {
143
+ // Get data point identifiers
144
+ const datapoints = Object.keys(message[exports.emptyGuid].datapoints);
145
+ datapoints.forEach((datapoint) => {
146
+ var _a;
147
+ // Ignore data points that have an unexpected format
148
+ const match = datapoint.match(/^(ABB[a-zA-Z0-9]{9})\/(ch\d{4})\/(odp\d{4})$/i);
149
+ if (!match) {
150
+ this.log.debug(`Ignored datapoint ${datapoint}: Unexpected format`);
151
+ return;
152
+ }
153
+ // Ignore data points we don't have an accessory for
154
+ const identifier = `${match[1]}_${match[2]}`;
155
+ if (!this.fahAccessories.has(identifier))
156
+ return;
157
+ // Update the accessory data point
158
+ (_a = this.fahAccessories
159
+ .get(identifier)) === null || _a === void 0 ? void 0 : _a.updateDatapoint(match[3], message[exports.emptyGuid].datapoints[datapoint]);
160
+ });
161
+ }
162
+ }
163
+ exports.FreeAtHomeHomebridgePlatform = FreeAtHomeHomebridgePlatform;
164
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * This is the name of the platform that users will use to register the plugin in the Homebridge config.json
3
+ */
4
+ export declare const PLATFORM_NAME = "FreeAtHomeLocalApi";
5
+ /**
6
+ * This must match the name of your plugin as defined the package.json
7
+ */
8
+ export declare const PLUGIN_NAME = "homebridge-freeathome-local-api";
9
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,aAAa,uBAAuB,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,WAAW,oCAAoC,CAAC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PLUGIN_NAME = exports.PLATFORM_NAME = void 0;
4
+ /**
5
+ * This is the name of the platform that users will use to register the plugin in the Homebridge config.json
6
+ */
7
+ exports.PLATFORM_NAME = "FreeAtHomeLocalApi";
8
+ /**
9
+ * This must match the name of your plugin as defined the package.json
10
+ */
11
+ exports.PLUGIN_NAME = "homebridge-freeathome-local-api";
12
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACU,QAAA,aAAa,GAAG,oBAAoB,CAAC;AAElD;;GAEG;AACU,QAAA,WAAW,GAAG,iCAAiC,CAAC"}
package/jasmine.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "spec_dir": "test",
3
+ "spec_files": ["**/*[sS]pec.ts"],
4
+ "helpers": ["test.ts"],
5
+ "env": {
6
+ "stopSpecOnExpectationFailure": false,
7
+ "random": true
8
+ }
9
+ }
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "displayName": "free@home Local API",
3
+ "name": "homebridge-freeathome-local-api",
4
+ "version": "0.1.0-pre",
5
+ "preview": true,
6
+ "description": "Control your free@home setup using the local API provided by your System Access Point",
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/pgerke/homebridge-freeathome-local-api.git"
11
+ },
12
+ "author": {
13
+ "email": "info@philipgerke.com",
14
+ "name": "Philip Gerke",
15
+ "url": "https://www.philipgerke.com"
16
+ },
17
+ "bugs": {
18
+ "url": "https://github.com/pgerke/homebridge-freeathome-local-api/issues"
19
+ },
20
+ "engines": {
21
+ "node": ">=14.18.1",
22
+ "homebridge": ">=1.3.5"
23
+ },
24
+ "main": "dist/index.js",
25
+ "scripts": {
26
+ "clean": "rimraf dist",
27
+ "lint": "eslint . --fix --max-warnings=0",
28
+ "watch": "npm run build && npm link && nodemon",
29
+ "test": "ts-node --project ./tsconfig.spec.json node_modules/jasmine/bin/jasmine --config=jasmine.json",
30
+ "test:coverage": "nyc npm run test",
31
+ "build": "npm run clean && tsc",
32
+ "prepublishOnly": "npm run lint && npm run build"
33
+ },
34
+ "keywords": [
35
+ "homebridge-plugin",
36
+ "freeathome"
37
+ ],
38
+ "dependencies": {
39
+ "freeathome-local-api-client": "1.2.0-pre.5",
40
+ "node-fetch": "^2.6.7"
41
+ },
42
+ "devDependencies": {
43
+ "@istanbuljs/nyc-config-typescript": "^1.0.2",
44
+ "@types/jasmine": "^4.0.3",
45
+ "@types/node": "^17.0.32",
46
+ "@types/node-fetch": "^2.6.1",
47
+ "@typescript-eslint/eslint-plugin": "^5.0.0",
48
+ "@typescript-eslint/parser": "^5.0.0",
49
+ "eslint": "^8.15.0",
50
+ "eslint-config-prettier": "^8.5.0",
51
+ "eslint-plugin-import": "^2.26.0",
52
+ "eslint-plugin-n": "^15.2.0",
53
+ "eslint-plugin-prettier": "^4.0.0",
54
+ "eslint-plugin-promise": "^6.0.0",
55
+ "homebridge": "^1.3.9",
56
+ "jasmine": "^4.1.0",
57
+ "jasmine-spec-reporter": "^7.0.0",
58
+ "nodemon": "^2.0.13",
59
+ "nyc": "^15.1.0",
60
+ "prettier": "^2.6.2",
61
+ "rimraf": "^3.0.2",
62
+ "ts-node": "^10.7.0",
63
+ "typescript": "^4.6.4"
64
+ }
65
+ }
@@ -0,0 +1,13 @@
1
+ import { originalTimeout } from "./../test";
2
+ import { PLUGIN_NAME } from "./../src/settings";
3
+
4
+ describe("Example Test Suite", () => {
5
+ afterAll(() => {
6
+ // Restore the default Jasmine timeout after the test suite.
7
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
8
+ });
9
+
10
+ it("should be executed", () => {
11
+ expect(PLUGIN_NAME).toBe("homebridge-freeathome-local-api");
12
+ });
13
+ });
package/test.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { SpecReporter } from "jasmine-spec-reporter";
2
+
3
+ // Preserve original timeout
4
+ export const originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
5
+
6
+ // Configure reporters
7
+ jasmine.getEnv().clearReporters();
8
+ jasmine.getEnv().addReporter(
9
+ new SpecReporter({
10
+ spec: {
11
+ displayDuration: true,
12
+ displayErrorMessages: true,
13
+ displayFailed: true,
14
+ displayPending: true,
15
+ displaySuccessful: true,
16
+ },
17
+ })
18
+ );
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["jasmine", "node"]
5
+ },
6
+ "include": ["src", "test/**/*.ts", "test.ts"],
7
+ "exclude": ["node_modules", "dist"]
8
+ }