@mgurreta/homebridge-molekule 1.2.4

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/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <https://unlicense.org>
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # homebridge-molekule
2
+ A Homebridge Plugin for Molekule Air Purifiers. Tested on the Air Mini. Once you install this plugin you can say:
3
+ ```
4
+ Hey Siri, what's the status of the Air Purifier Filter?
5
+ Hey Siri, set the speed of the Molekule to 60%.
6
+ ```
7
+ ## Installation
8
+
9
+ ### Via Homebridge UI (Recommended)
10
+
11
+ 1. Open the **Homebridge UI** in your web browser
12
+ 2. Navigate to the **Plugins** tab
13
+ 3. Click the **Search** button (or use the search bar)
14
+ 4. Search for **"Molekule"** or **"homebridge-molekule"**
15
+ 5. Click on the plugin in the search results
16
+ 6. Click the **Install** button
17
+ 7. Wait for the installation to complete
18
+
19
+ ### Via Command Line
20
+
21
+ Alternatively, you can install via npm:
22
+ ```bash
23
+ npm -g i @mgurreta/homebridge-molekule
24
+ ```
25
+
26
+ ## Configuration
27
+
28
+ ### Via Homebridge UI
29
+
30
+ 1. After installation, go to the **Plugins** tab in Homebridge UI
31
+ 2. Find **Homebridge Molekule** in your installed plugins list
32
+ 3. Click the **Settings** (gear icon) or **Configure** button
33
+ 4. Fill in the configuration form:
34
+ - **Name**: Platform name (default: "homebridge-molekule")
35
+ - **Email**: Your Molekule account email address
36
+ - **Password**: Your Molekule account password
37
+ - **Filter Change Warning Percentage**: Threshold for filter change warnings (default: 5%)
38
+ 5. Click **Save** to apply the configuration
39
+ 6. The plugin will restart automatically and discover your Molekule devices
40
+
41
+ ### Manual Configuration
42
+
43
+ If you prefer to configure manually, add this to your `config.json` file under Platforms:
44
+ ```json
45
+ {
46
+ "platform": "Molekule",
47
+ "name": "homebridge-molekule",
48
+ "email": "YOUR EMAIL HERE",
49
+ "password": "YOUR PASSWORD HERE",
50
+ "threshold": 10
51
+ }
52
+ ```
53
+ # Notes and Issues
54
+ Using an incorrect password can cause a need for a full password reset on your account. Pay special attention to the password you're using.
55
+ This plugin loads the names that are set for each device in the Molekule app.
@@ -0,0 +1,38 @@
1
+ {
2
+ "pluginAlias": "Molekule",
3
+ "pluginType": "platform",
4
+ "singular": false,
5
+ "schema": {
6
+ "type": "object",
7
+ "properties": {
8
+ "name": {
9
+ "title": "Name",
10
+ "type": "string",
11
+ "default": "homebridge-molekule",
12
+ "required": true
13
+ },
14
+ "email": {
15
+ "title": "Email",
16
+ "type": "string",
17
+ "format": "email",
18
+ "placeholder": "example@example.com",
19
+ "required": true
20
+ },
21
+ "password": {
22
+ "title": "Password",
23
+ "type": "string",
24
+ "placeholder": "********",
25
+ "required": true,
26
+ "description": "<b>Ensure password is correct, othersise a reset may become necessary.</b>"
27
+ },
28
+ "threshold": {
29
+ "title": "Filter Change Warning Percentage",
30
+ "type": "integer",
31
+ "default": 5,
32
+ "minimum": 0,
33
+ "maximum": 100,
34
+ "description": "Show <b>Change Filter</b> warning once Filter Life reaches this value."
35
+ }
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpAJAX = void 0;
4
+ const amazon_cognito_identity_js_1 = require("amazon-cognito-identity-js");
5
+ let token = '';
6
+ let refreshToken;
7
+ let authError;
8
+ // Molekule API settings
9
+ const ClientId = '1ec4fa3oriciupg94ugoi84kkk';
10
+ const PoolId = 'us-west-2_KqrEZKC6r';
11
+ const url = 'https://api.molekule.com/users/me/devices/';
12
+ class HttpAJAX {
13
+ log;
14
+ email;
15
+ pass;
16
+ authenticationData;
17
+ userData;
18
+ userPool;
19
+ authenticationDetails;
20
+ cognitoUser;
21
+ userPoolData;
22
+ constructor(log, config) {
23
+ this.log = log;
24
+ this.email = config.email;
25
+ this.pass = config.password;
26
+ this.authenticationData = {
27
+ Username: this.email,
28
+ Password: this.pass,
29
+ };
30
+ this.userPoolData = {
31
+ UserPoolId: PoolId,
32
+ ClientId,
33
+ };
34
+ this.userPool = new amazon_cognito_identity_js_1.CognitoUserPool(this.userPoolData);
35
+ this.userData = {
36
+ Username: this.email,
37
+ Pool: this.userPool,
38
+ };
39
+ this.authenticationDetails = new amazon_cognito_identity_js_1.AuthenticationDetails(this.authenticationData);
40
+ this.cognitoUser = new amazon_cognito_identity_js_1.CognitoUser(this.userData);
41
+ }
42
+ refreshAuthToken() {
43
+ return new Promise((resolve, reject) => this.cognitoUser.refreshSession(refreshToken, (err, session) => {
44
+ if (err) {
45
+ this.log.info('Auth token fetch using refresh token failed. Fallback to username/password');
46
+ this.log.debug(err);
47
+ reject(err);
48
+ }
49
+ else {
50
+ this.log.info('✓ Token refresh successful');
51
+ authError = false;
52
+ token = session.getAccessToken().getJwtToken();
53
+ resolve(session);
54
+ }
55
+ }));
56
+ }
57
+ initiateAuth() {
58
+ this.log.debug('email: ' + this.email);
59
+ this.log.debug('password: ' + this.pass);
60
+ return new Promise((resolve, reject) => this.cognitoUser.authenticateUser(this.authenticationDetails, {
61
+ onSuccess: (result) => {
62
+ token = result.getAccessToken().getJwtToken();
63
+ refreshToken = result.getRefreshToken();
64
+ this.log.info('✓ Valid Login Credentials');
65
+ authError = false;
66
+ resolve(result.getAccessToken().getJwtToken());
67
+ },
68
+ onFailure: (err) => {
69
+ this.log.error('API Authentication Failure, possibly a password/username error.');
70
+ reject(err);
71
+ },
72
+ }));
73
+ }
74
+ async httpCall(method, extraUrl, send, retry) {
75
+ let response;
76
+ if (authError)
77
+ await this.refreshAuthToken().catch((e) => {
78
+ this.initiateAuth().catch((e) => {
79
+ this.log.error(e);
80
+ return;
81
+ });
82
+ this.log.debug(e);
83
+ });
84
+ if (token === '' || authError)
85
+ await this.initiateAuth().catch((err) => {
86
+ this.log.error(err);
87
+ return;
88
+ });
89
+ if (method === 'GET') {
90
+ const contents = {
91
+ method,
92
+ headers: {
93
+ authorization: token,
94
+ 'x-api-version': '1.0',
95
+ 'content-type': 'application/json',
96
+ },
97
+ };
98
+ response = await fetch(url + extraUrl, contents);
99
+ this.log.debug('HTTP GET STATUS: ' + response.status);
100
+ this.log.debug('HTTP GET CONTENTS: ' + JSON.stringify(response));
101
+ if (response.status === 401 && retry > 0) {
102
+ authError = true;
103
+ return await this.httpCall(method, extraUrl, send, retry - 1);
104
+ }
105
+ else
106
+ return response;
107
+ }
108
+ else {
109
+ const contents = {
110
+ method,
111
+ body: send,
112
+ headers: {
113
+ authorization: token,
114
+ 'x-api-version': '1.0',
115
+ 'content-type': 'application/json',
116
+ },
117
+ };
118
+ response = await fetch(url + extraUrl, contents);
119
+ this.log.debug('HTTP POST STATUS: ' + response.status + ' With contents: ' + send);
120
+ if (response.status === 401 && retry > 0) {
121
+ authError = true;
122
+ return await this.httpCall(method, extraUrl, send, retry - 1);
123
+ }
124
+ }
125
+ return response;
126
+ }
127
+ }
128
+ exports.HttpAJAX = HttpAJAX;
129
+ //# sourceMappingURL=cognito.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cognito.js","sourceRoot":"","sources":["../src/cognito.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ const settings_1 = require("./settings");
3
+ const platform_1 = require("./platform");
4
+ module.exports = (api) => {
5
+ api.registerPlatform(settings_1.PLATFORM_NAME, platform_1.MolekuleHomebridgePlatform);
6
+ };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,yCAA0C;AAC1C,yCAAuD;AAKvD,iBAAS,CAAC,GAAQ,EAAE,EAAE;IACpB,GAAG,CAAC,gBAAgB,CAAC,wBAAa,EAAE,qCAA0B,CAAC,CAAA;AACjE,CAAC,CAAC"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MolekuleHomebridgePlatform = void 0;
4
+ const settings_1 = require("./settings");
5
+ const platformAccessory_1 = require("./platformAccessory");
6
+ const cognito_1 = require("./cognito");
7
+ let intervalID;
8
+ const refreshInterval = 60; //token refresh interval in minutes
9
+ /**
10
+ * HomebridgePlatform
11
+ * This class is the main constructor for your plugin, this is where you should
12
+ * parse the user config and discover/register accessories with Homebridge.
13
+ */
14
+ class MolekuleHomebridgePlatform {
15
+ log;
16
+ config;
17
+ api;
18
+ caller;
19
+ Service;
20
+ Characteristic;
21
+ // this is used to track restored cached accessories
22
+ accessories = [];
23
+ constructor(log, config, api, caller = new cognito_1.HttpAJAX(log, config)) {
24
+ this.log = log;
25
+ this.config = config;
26
+ this.api = api;
27
+ this.caller = caller;
28
+ this.Service = this.api.hap.Service;
29
+ this.Characteristic = this.api.hap.Characteristic;
30
+ // When this event is fired it means Homebridge has restored all cached accessories from disk.
31
+ // Dynamic Platform plugins should only register new accessories after this event was fired,
32
+ // in order to ensure they weren't added to homebridge already. This event can also be used
33
+ // to start discovery of new accessories.
34
+ this.api.on('didFinishLaunching', () => {
35
+ log.debug('Executed didFinishLaunching callback');
36
+ // run the method to discover / register your devices as accessories
37
+ this.discoverDevices();
38
+ if (!intervalID)
39
+ intervalID = setInterval(() => this.caller.refreshAuthToken(), refreshInterval * 60 * 1000);
40
+ });
41
+ this.log.debug('Finished initializing platform ', settings_1.PLATFORM_NAME);
42
+ }
43
+ /**
44
+ * This function is invoked when homebridge restores cached accessories from disk at startup.
45
+ * It should be used to setup event handlers for characteristics and update respective values.
46
+ */
47
+ configureAccessory(accessory) {
48
+ this.log.info('Loading accessory from cache:', accessory.displayName);
49
+ // add the restored accessory to the accessories cache so we can track if it has already been registered
50
+ this.accessories.push(accessory);
51
+ }
52
+ /**
53
+ * This is an example method showing how to register discovered accessories.
54
+ * Accessories must only be registered once, previously created accessories
55
+ * must not be registered again to prevent "duplicate UUID" errors.
56
+ */
57
+ async discoverDevices() {
58
+ this.log.debug('Discover Devices Called');
59
+ const response = this.caller.httpCall('GET', '', '', 1);
60
+ const devices = await (await response).json();
61
+ // loop over the discovered devices and register each one if it has not already been registered
62
+ if ((await response).status !== 200) {
63
+ this.log.error('Fatal error, discover devices failed. Try running homebridge in debug mode to see HTTP status code.');
64
+ return; //prevent crashes
65
+ }
66
+ devices.content.forEach((device) => {
67
+ // generate a unique id for the accessory this should be generated from
68
+ // something globally unique, but constant, for example, the device serial
69
+ // number or MAC address
70
+ this.log.debug('found device from API: ' + JSON.stringify(device));
71
+ const uuid = this.api.hap.uuid.generate(device.serialNumber);
72
+ // see if an accessory with the same uuid has already been registered and restored from
73
+ // the cached devices we stored in the `configureAccessory` method above
74
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
75
+ if (existingAccessory) {
76
+ // the accessory already exists
77
+ this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName);
78
+ // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
79
+ // existingAccessory.context.device = device;
80
+ // this.api.updatePlatformAccessories([existingAccessory]);
81
+ // create the accessory handler for the restored accessory
82
+ // this is imported from `platformAccessory.ts`
83
+ new platformAccessory_1.MolekulePlatformAccessory(this, existingAccessory, this.config, this.log);
84
+ // it is possible to remove platform accessories at any time using `api.unregisterPlatformAccessories`, eg.:
85
+ // remove platform accessories when no longer present
86
+ // this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [existingAccessory]);
87
+ // this.log.info('Removing existing accessory from cache:', existingAccessory.displayName);
88
+ }
89
+ else {
90
+ // the accessory does not yet exist, so we need to create it
91
+ this.log.info('Adding new accessory:', device.name);
92
+ // create a new accessory
93
+ const accessory = new this.api.platformAccessory(device.name, uuid);
94
+ // store a copy of the device object in the `accessory.context`
95
+ // the `context` property can be used to store any data about the accessory you may need
96
+ accessory.context.device = device;
97
+ // create the accessory handler for the newly create accessory
98
+ // this is imported from `platformAccessory.ts`
99
+ new platformAccessory_1.MolekulePlatformAccessory(this, accessory, this.config, this.log);
100
+ // link the accessory to your platform
101
+ this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
102
+ }
103
+ });
104
+ }
105
+ }
106
+ exports.MolekuleHomebridgePlatform = MolekuleHomebridgePlatform;
107
+ //# 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,216 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MolekulePlatformAccessory = void 0;
4
+ const cognito_1 = require("./cognito");
5
+ /**
6
+ * Platform Accessory
7
+ * An instance of this class is created for each accessory your platform registers
8
+ * Each accessory may expose multiple services of different service types.
9
+ */
10
+ class MolekulePlatformAccessory {
11
+ platform;
12
+ accessory;
13
+ config;
14
+ log;
15
+ service;
16
+ /**
17
+ * These are just used to create a working example
18
+ * You should implement your own code to track the state of your accessory
19
+ */
20
+ state = {
21
+ state: 0,
22
+ Speed: 0,
23
+ Filter: 100,
24
+ On: 0,
25
+ Auto: 0,
26
+ };
27
+ constructor(platform, accessory, config, log) {
28
+ this.platform = platform;
29
+ this.accessory = accessory;
30
+ this.config = config;
31
+ this.log = log;
32
+ this.caller = new cognito_1.HttpAJAX(this.log, this.config);
33
+ // set accessory information
34
+ this.accessory
35
+ .getService(this.platform.Service.AccessoryInformation)
36
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Molekule')
37
+ .setCharacteristic(this.platform.Characteristic.Model, accessory.context.device.model)
38
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, accessory.context.device.serialNumber)
39
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, accessory.context.device.firmwareVersion);
40
+ // get the AirPurifier service if it exists, otherwise create a new AirPurifier service
41
+ // you can create multiple services for each accessory
42
+ this.service =
43
+ this.accessory.getService(this.platform.Service.AirPurifier) ||
44
+ this.accessory.addService(this.platform.Service.AirPurifier);
45
+ // set the service name, this is what is displayed as the default name on the Home app
46
+ // in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
47
+ this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.name);
48
+ // each service must implement at-minimum the "required characteristics" for the given service type
49
+ // see https://developers.homebridge.io/#/service/AirPurifier
50
+ // register handlers for the On/Off Characteristic
51
+ this.service
52
+ .getCharacteristic(this.platform.Characteristic.Active)
53
+ .onSet(this.handleActiveSet.bind(this)) // SET - bind to the `handleActiveSet` method below
54
+ .onGet(this.handleActiveGet.bind(this)); // GET - bind to the `handleActiveGet` method below
55
+ // register handlers for the CurrentAirPurifierState Characteristic
56
+ this.service
57
+ .getCharacteristic(this.platform.Characteristic.CurrentAirPurifierState)
58
+ .onGet(this.getState.bind(this)); // GET - bind to the `getState` method below
59
+ // register handlers for the TargetAirPurifierState Characteristic
60
+ this.service
61
+ .getCharacteristic(this.platform.Characteristic.TargetAirPurifierState)
62
+ .onSet(this.handleAutoSet.bind(this))
63
+ .onGet(this.handleAutoGet.bind(this));
64
+ this.service
65
+ .getCharacteristic(this.platform.Characteristic.RotationSpeed)
66
+ .onSet(this.setSpeed.bind(this))
67
+ .onGet(this.getSpeed.bind(this));
68
+ this.service
69
+ .getCharacteristic(this.platform.Characteristic.FilterChangeIndication)
70
+ .onGet(this.getFilterChange.bind(this));
71
+ this.service
72
+ .getCharacteristic(this.platform.Characteristic.FilterLifeLevel)
73
+ .onGet(this.getFilterStatus.bind(this));
74
+ /**
75
+ * Creating multiple services of the same type.
76
+ *
77
+ * To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
78
+ * when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
79
+ * this.accessory.getService('NAME') || this.accessory.addService(this.platform.Service.Lightbulb, 'NAME', 'USER_DEFINED_SUBTYPE_ID');
80
+ *
81
+ * The USER_DEFINED_SUBTYPE must be unique to the platform accessory (if you platform exposes multiple accessories, each accessory
82
+ * can use the same sub type id.)
83
+ */
84
+ }
85
+ caller;
86
+ /**
87
+ * Handle "SET" requests from HomeKit
88
+ * These are sent when the user changes the state of an accessory, for example, turning on a Light bulb.
89
+ */
90
+ async handleActiveSet(value) {
91
+ // implement your own code to turn your device on/off
92
+ let data = '"on"}';
93
+ if (!value)
94
+ data = '"off"}';
95
+ const response = await this.caller.httpCall('POST', this.accessory.context.device.serialNumber + '/actions/set-power-status', '{"status":' + data, 1);
96
+ if (response.status === 204) {
97
+ this.service.updateCharacteristic(this.platform.Characteristic.Active, value);
98
+ if (value) {
99
+ this.service.updateCharacteristic(this.platform.Characteristic.CurrentAirPurifierState, 2);
100
+ this.state.state = 2;
101
+ this.state.On = 1;
102
+ }
103
+ else {
104
+ this.service.updateCharacteristic(this.platform.Characteristic.CurrentAirPurifierState, 0);
105
+ this.state.On = 0;
106
+ }
107
+ }
108
+ this.platform.log.info('Attempted to set: ' +
109
+ value +
110
+ ' state on device: ' +
111
+ this.accessory.context.device.name +
112
+ ' Server Reply: ' +
113
+ JSON.stringify(response));
114
+ }
115
+ /**
116
+ * Handle the "GET" requests from HomeKit
117
+ * These are sent when HomeKit wants to know the current state of the accessory, for example, checking if a Light bulb is on.
118
+ *
119
+ * GET requests should return as fast as possbile. A long delay here will result in
120
+ * HomeKit being unresponsive and a bad user experience() in general.
121
+ *
122
+ * If your device takes time to respond you should update the status of your device
123
+ * asynchronously instead using the `updateCharacteristic` method instead.
124
+ * @example
125
+ * this.service.updateCharacteristic(this.platform.Characteristic.On, true)
126
+ */
127
+ async handleActiveGet() {
128
+ if ((await this.updateStates()) === 1)
129
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
130
+ this.log.info(this.accessory.context.device.name + ' state is: ' + this.state.On);
131
+ return this.state.On;
132
+ // if you need to return an error to show the device as "Not Responding" in the Home app:
133
+ // throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
134
+ }
135
+ async getState() {
136
+ return this.state.state;
137
+ }
138
+ async handleAutoSet(value) {
139
+ try {
140
+ if (value === 1) {
141
+ await this.setSpeed((100 / 3) * 2);
142
+ }
143
+ }
144
+ catch {
145
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
146
+ }
147
+ this.service.updateCharacteristic(this.platform.Characteristic.TargetAirPurifierState, value);
148
+ }
149
+ async handleAutoGet() {
150
+ if ((await this.updateStates()) === 1)
151
+ throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
152
+ return this.state.Auto;
153
+ }
154
+ /**
155
+ * Handle "SET" requests from HomeKit
156
+ * These are sent when the user changes the state of an accessory, for example, changing the speed
157
+ */
158
+ async setSpeed(value) {
159
+ const clamp = Math.round(Math.min(Math.max(value / 33.33333333, 1), 3));
160
+ const setFanSpeedRequest = await this.caller.httpCall('POST', this.accessory.context.device.serialNumber + '/actions/set-fan-speed', '{"fanSpeed": ' + clamp + '}', 1);
161
+ if (setFanSpeedRequest.status === 204) {
162
+ this.state.Speed = clamp * 33.33333333;
163
+ this.state.Auto = clamp === 2 ? 1 : 0;
164
+ }
165
+ this.platform.log.info(this.accessory.context.device.name + ' set speed -> ', '{"fanSpeed":' + clamp + '}');
166
+ this.service.updateCharacteristic(this.platform.Characteristic.RotationSpeed, this.state.Speed);
167
+ this.service.updateCharacteristic(this.platform.Characteristic.TargetAirPurifierState, this.state.Auto);
168
+ }
169
+ async getSpeed() {
170
+ return this.state.Speed;
171
+ }
172
+ async getFilterChange() {
173
+ if (this.state.Filter > this.config.threshold)
174
+ return 0;
175
+ else
176
+ return 1;
177
+ }
178
+ async getFilterStatus() {
179
+ this.log.debug('Check Filter State: ' + this.state.Filter);
180
+ return this.state.Filter;
181
+ }
182
+ async updateStates() {
183
+ const re = await this.caller.httpCall('GET', '', '', 1);
184
+ const response = await re.json();
185
+ if (!response)
186
+ return 1;
187
+ for (let i = 0; i < Object.keys(response.content).length; i++) {
188
+ if (response.content[i].serialNumber ===
189
+ this.accessory.context.device.serialNumber) {
190
+ this.platform.log.info('Get Speed ->', response.content[i].fanspeed);
191
+ this.state.Speed = Number(response.content[i].fanspeed) * 33.33333333;
192
+ this.state.Filter = response.content[i].pecoFilter;
193
+ this.state.Auto = response.content[i].fanspeed === '2' ? 1 : 0;
194
+ if (response.content[i].online === 'false') {
195
+ this.log.error(this.accessory.context.device.name +
196
+ ' was reported to be offline by the Molekule API.');
197
+ return 1;
198
+ }
199
+ if (response.content[i].mode !== 'off') {
200
+ this.state.On = 1;
201
+ this.state.state = 2;
202
+ }
203
+ else {
204
+ this.state.On = 0;
205
+ this.state.state = 0;
206
+ }
207
+ }
208
+ }
209
+ this.service.updateCharacteristic(this.platform.Characteristic.RotationSpeed, this.state.Speed);
210
+ this.service.updateCharacteristic(this.platform.Characteristic.CurrentAirPurifierState, this.state.state);
211
+ this.service.updateCharacteristic(this.platform.Characteristic.Active, this.state.On);
212
+ return 0;
213
+ }
214
+ }
215
+ exports.MolekulePlatformAccessory = MolekulePlatformAccessory;
216
+ //# sourceMappingURL=platformAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platformAccessory.js","sourceRoot":"","sources":["../src/platformAccessory.ts"],"names":[],"mappings":"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"}
@@ -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 = 'Molekule';
8
+ /**
9
+ * This must match the name of your plugin as defined the package.json
10
+ */
11
+ exports.PLUGIN_NAME = '@mgurreta/homebridge-molekule';
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,UAAU,CAAA;AAEvC;;IAEI;AACS,QAAA,WAAW,GAAG,+BAA+B,CAAA"}