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.
- package/.eslintignore +6 -0
- package/.nycrc.json +6 -0
- package/.prettierignore +6 -0
- package/.prettierrc +5 -0
- package/CHANGELOG.md +15 -0
- package/CODEOWNERS +8 -0
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/config.schema.json +51 -0
- package/dist/binarySensorAccessory.d.ts +26 -0
- package/dist/binarySensorAccessory.d.ts.map +1 -0
- package/dist/binarySensorAccessory.js +61 -0
- package/dist/binarySensorAccessory.js.map +1 -0
- package/dist/enumerations.d.ts +9 -0
- package/dist/enumerations.d.ts.map +1 -0
- package/dist/enumerations.js +13 -0
- package/dist/enumerations.js.map +1 -0
- package/dist/freeAtHomeAccessory.d.ts +23 -0
- package/dist/freeAtHomeAccessory.d.ts.map +1 -0
- package/dist/freeAtHomeAccessory.js +23 -0
- package/dist/freeAtHomeAccessory.js.map +1 -0
- package/dist/freeAtHomeContext.d.ts +17 -0
- package/dist/freeAtHomeContext.d.ts.map +1 -0
- package/dist/freeAtHomeContext.js +22 -0
- package/dist/freeAtHomeContext.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +39 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +164 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.d.ts +9 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +12 -0
- package/dist/settings.js.map +1 -0
- package/jasmine.json +9 -0
- package/package.json +65 -0
- package/test/example.spec.ts +13 -0
- package/test.ts +18 -0
- package/tsconfig.spec.json +8 -0
package/.eslintignore
ADDED
package/.nycrc.json
ADDED
package/.prettierignore
ADDED
package/.prettierrc
ADDED
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
|
+

|
|
6
|
+
[](https://codecov.io/gh/pgerke/homebridge-freeathome-local-api)
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
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@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@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@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@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@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@home device serial and the channel ID. */
|
|
9
|
+
protected readonly serialNumber: string;
|
|
10
|
+
/**
|
|
11
|
+
* Constructs a new free@home accessory instance.
|
|
12
|
+
* @param platform The free@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@home accessories.*/
|
|
5
|
+
class FreeAtHomeAccessory {
|
|
6
|
+
/**
|
|
7
|
+
* Constructs a new free@home accessory instance.
|
|
8
|
+
* @param platform The free@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@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@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@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@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@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@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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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@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@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@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"}
|
package/dist/platform.js
ADDED
|
@@ -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@home Homebridge platform. */
|
|
12
|
+
class FreeAtHomeHomebridgePlatform {
|
|
13
|
+
/**
|
|
14
|
+
* Constructs a new free@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@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@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@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"}
|
package/dist/settings.js
ADDED
|
@@ -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
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
|
+
);
|