Skip to content

Commit

Permalink
Merge pull request #512 from johannrichard/beta
Browse files Browse the repository at this point in the history
Release v3.2.0 with some bugfixes for current and upcoming FW changes, as well as some long-standing bugs.
  • Loading branch information
johannrichard authored Oct 24, 2022
2 parents 50919a0 + 0ecd52c commit b8a1434
Show file tree
Hide file tree
Showing 12 changed files with 261 additions and 135 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
uses: actions/setup-node@main
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'

# - name: Upgrade yarn
# run: yarn set version berry
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/semantic-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
push:
branches: [master, beta, alpha]

# fine-grained permissions
# fine-grained permissions
# see https://github.com/semantic-release/github and https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
permissions:
contents: write
Expand All @@ -22,6 +22,7 @@ jobs:
- uses: actions/setup-node@main
with:
node-version: '16'
cache: 'yarn'

- name: Install dependencies
run: yarn set version berry
Expand Down
8 changes: 7 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,19 @@ web_modules/

# yarn v2

.yarn/build-state.yml
.yarn/cache
.yarn/install-state.gz
.yarn/plugins
.yarn/sdks
.yarn/unplugged
.yarn/build-state.yml
.yarn/releases
.yarnrc.yml
.pnp.*

# Github templates and actions, own stuff
.github
api
.prettierrc
.prettierignore
commitlint.config.js
17 changes: 17 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Homebridge Debug",
"skipFiles": ["<node_internals>/**"],
"program": "/usr/local/bin/homebridge",
"args": "-I",
"outFiles": ["${workspaceFolder}/**/*.js"]
}
]
}
21 changes: 21 additions & 0 deletions config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,27 @@
"type": "string",
"description": "Set a global authentication token. This will be used for auto-discovery on the local network and as default token for manually specified devices."
},
"ignore": {
"title": "Ignored Devices",
"description": "Devices in this list will be excluded when found via auto-discovery. Add an entry (MAC-Address without the colon) for each devices that shall be ignored. The MAC-Address of your myStrom and Dingz devices can be found in the respective app, or via the device's own webpage.",
"type": "array",
"items": {
"title": "Device",
"type": "object",
"properties": {
"mac": {
"title": "MAC-Address",
"type": "string",
"pattern": "^([A-Fa-f0-9]{2}){5}[A-Fa-f0-9]{2}$",
"required": true
},
"comment": {
"title": "Comment",
"type": "string"
}
}
}
},
"callbackHostname": {
"title": "Hostname / IP to use for button callbacks ",
"type": "string",
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"prepublishOnly": "yarn pinst --disable",
"prepare": "yarn run lint && yarn run build && yarn run depcheck",
"changelog": "changelog --exclude ci,chore",
"debug": "yarn dlx homebridge -I"
"debug": "yarn run lint && yarn run build && yarn dlx homebridge -I"
},
"keywords": [
"homebridge-plugin",
Expand All @@ -48,7 +48,7 @@
"is-valid-host": "^1.0.1",
"limit-number": "^3.0.0",
"qs": "^6.10.3",
"semver": "^7.3.5",
"semver": "^7.3.8",
"simple-color-converter": "^2.1.13"
},
"devDependencies": {
Expand Down
82 changes: 51 additions & 31 deletions src/dingzAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,37 +223,47 @@ export class DingzAccessory extends DingzDaBaseAccessory {

this.getButtonCallbackUrl()
.then((callBackUrl) => {
// Set the callback URL
const endpoints = ['generic'];
const platformCallbackUrl = this.platform.getCallbackUrl();

// Add PIR callbacks, depending on dingz Firmware version
if (this.hw.has_pir) {
if (semver.lt(this.hw.fw_version, '1.2.0')) {
endpoints.push('pir/single');
} else if (semver.lt(this.hw.fw_version, '1.4.0')) {
endpoints.push('pir/generic', 'pir/rise', 'pir/fall');
} else {
// FIXES #511: Newer FW have (yet!) other endpoint for PIR callbacks
endpoints.push('pir1/rise', 'pir1/fall');
}
}

if (this.platform.config.callbackOverride) {
this.log.warn('Override callback URL ->', callBackUrl);
// Set the callback URL (Override!)
const endpoints = // Only set `pir/single` for older FW
this.hw.has_pir && semver.lt(this.hw.fw_version, '1.2.0')
? ['generic', 'pir/single']
: this.hw.has_pir
? ['generic', 'pir/generic', 'pir/rise', 'pir/fall']
: ['generic'];

this.platform.setButtonCallbackUrl({
baseUrl: this.baseUrl,
token: this.device.token,
endpoints: endpoints,
});
} else if (!callBackUrl?.url.includes(this.platform.getCallbackUrl())) {
} else if (
// FIXME: because of #511
(semver.lt(this.hw.fw_version, '1.4.0') &&
!callBackUrl?.url?.includes(platformCallbackUrl)) ||
(semver.gte(this.hw.fw_version, '1.4.0') &&
!callBackUrl?.generic?.includes(platformCallbackUrl))
) {
this.log.warn('Update existing callback URL ->', callBackUrl);
// Set the callback URL (Override!)
const endpoints =
this.hw.has_pir && semver.lt(this.hw.fw_version, '1.2.0')
? ['generic', 'pir/single']
: this.hw.has_pir
? ['generic', 'pir/generic', 'pir/rise', 'pir/fall']
: ['generic'];

this.platform.setButtonCallbackUrl({
baseUrl: this.baseUrl,
token: this.device.token,
oldUrl: callBackUrl.url,
endpoints: endpoints,
});
} else {
this.log.debug('Callback URL already set ->', callBackUrl?.url);
this.log.debug('Callback URL already set ->', callBackUrl);
}
})
.catch(this.handleRequestErrors.bind(this));
Expand Down Expand Up @@ -835,12 +845,11 @@ export class DingzAccessory extends DingzDaBaseAccessory {

// Set min/max Values
// FIXME: Implement different lamella/blind modes #24
const maxTiltValue = semver.lt(this.hw.fw_version, '1.2.0') ? 90 : 100;
service
.getCharacteristic(this.platform.Characteristic.TargetHorizontalTiltAngle)
.setProps({
minValue: 0,
maxValue: maxTiltValue,
maxValue: 90,
minStep: this.platform.config.minStepTiltAngle,
}) // dingz Maximum values
.on(CharacteristicEventTypes.SET, this.setTiltAngle.bind(this, index));
Expand Down Expand Up @@ -881,17 +890,14 @@ export class DingzAccessory extends DingzDaBaseAccessory {
* - We're moving by setting new positions in the UI [x]
* - We're moving by pressing the "up/down" buttons in the UI or Hardware [x]
*/

const maxTiltValue = semver.lt(this.hw.fw_version, '1.2.0') ? 90 : 100;

service
.getCharacteristic(this.platform.Characteristic.TargetPosition)
.updateValue(state.position);
service
.getCharacteristic(
this.platform.Characteristic.TargetHorizontalTiltAngle,
)
.updateValue((state.lamella / 100) * maxTiltValue); // Old FW: Set in °, Get in % (...)
.updateValue((state.lamella / 100) * 90); // Lamella position set in ° in HomeKit

let positionState: number;
switch (state.moving) {
Expand All @@ -910,7 +916,7 @@ export class DingzAccessory extends DingzDaBaseAccessory {
.getCharacteristic(
this.platform.Characteristic.CurrentHorizontalTiltAngle,
)
.updateValue((state.lamella / 100) * maxTiltValue); // Set in °, Get in % (...)
.updateValue((state.lamella / 100) * 90); // Lamella position set in ° in HomeKit
break;
}
service
Expand Down Expand Up @@ -941,7 +947,7 @@ export class DingzAccessory extends DingzDaBaseAccessory {
await this.setWindowCovering({
id: id,
blind: position as number,
lamella: windowCovering.lamella,
lamella: (windowCovering.lamella / 90) * 100, // FIXES #419, we must convert ° to %
callback: callback,
});
}
Expand Down Expand Up @@ -977,14 +983,14 @@ export class DingzAccessory extends DingzDaBaseAccessory {
'Set Characteristic TargetHorizontalTiltAngle on ',
index,
'->',
angle,
`${angle}°`,
);
const id = this.getWindowCoveringId(index);
if (this.dingzStates.WindowCovers[id]) {
await this.setWindowCovering({
id: id,
blind: this.dingzStates.WindowCovers[id].position,
lamella: angle as number,
lamella: ((angle as number) / 90) * 100, // FIXES #419, we must convert ° to %
callback: callback,
});
}
Expand Down Expand Up @@ -1012,7 +1018,9 @@ export class DingzAccessory extends DingzDaBaseAccessory {
tiltAngle,
);

callback(this.reachabilityState, (tiltAngle / 100) * 90); // FIXES #371: internally, it's %, HomeKit expects °
// FIXES #371, #419: internally, it's % (but only in newer firmware, v1.2.0 and lower has ° as well), HomeKit expects °
const maxTiltValue = semver.lt(this.hw.fw_version, '1.2.0') ? 90 : 100;
callback(this.reachabilityState, (tiltAngle / maxTiltValue) * 90);
}

private getPositionState(
Expand Down Expand Up @@ -1329,9 +1337,9 @@ export class DingzAccessory extends DingzDaBaseAccessory {
color: `hex #${state.rgb}`,
to: 'hsv',
});
this.dingzStates.LED.hue = hsv.c;
this.dingzStates.LED.saturation = hsv.s;
this.dingzStates.LED.value = hsv.i;
this.dingzStates.LED.hue = hsv.color.h;
this.dingzStates.LED.saturation = hsv.color.s;
this.dingzStates.LED.value = hsv.color.v;
}

ledService
Expand Down Expand Up @@ -1490,6 +1498,15 @@ export class DingzAccessory extends DingzDaBaseAccessory {
lamella: number;
callback: CharacteristicSetCallback;
}) {
// The API only accepts integer numbers.
// As we juggle with ° vs %, we must round
// the values for blind and lamella to the nearest integer
blind = Math.round(blind);
lamella = Math.round(lamella);

this.log.debug(
`Setting WindowCovering ${id} to position ${blind} and angle ${lamella}°`,
);
// The API says the parameters can be omitted. This is not true
// {{ip}}/api/v1/shade/0?blind=<value>&lamella=<value>
const setWindowCoveringEndpoint = `${this.baseUrl}/api/v1/shade/${id}`;
Expand Down Expand Up @@ -1552,7 +1569,10 @@ export class DingzAccessory extends DingzDaBaseAccessory {
* Returns the callback URL for the device
*/
public async getButtonCallbackUrl(): Promise<AccessoryActionUrl> {
const getCallbackEndpoint = '/api/v1/action/generic/generic';
// FIXES #511: different endpoint URLs for Callback from FW v1.4.x forward
const getCallbackEndpoint = semver.gte(this.hw.fw_version, '1.4.0')
? '/api/v1/action/generic'
: '/api/v1/action/generic/generic';
this.log.debug('Getting the callback URL -> ', getCallbackEndpoint);
return await this.request.get(getCallbackEndpoint).then((response) => {
return response.data;
Expand Down
4 changes: 3 additions & 1 deletion src/lib/commonTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ export interface AccessoryTypes {
[key: string]: AccessoryType;
}

// FIXME: Needed because of #511
export interface AccessoryActionUrl {
url: string;
url?: string;
generic?: string;
}
1 change: 0 additions & 1 deletion src/lib/libs.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
declare module 'simple-color-converter';
declare module 'is-valid-host';
declare module 'semver';
declare module 'limit-number';
5 changes: 4 additions & 1 deletion src/myStromPIRAccessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,10 @@ export class MyStromPIRAccessory extends DingzDaBaseAccessory {
token: this.device.token,
endpoints: ['pir/generic'],
});
} else if (!callBackUrl?.url.includes(this.platform.getCallbackUrl())) {
} else if (
// FIXME: Needed because of #511
!callBackUrl?.url?.includes(this.platform.getCallbackUrl())
) {
this.log.warn('Update existing callback URL ->', callBackUrl);
// Set the callback URL (Override!)
this.platform.setButtonCallbackUrl({
Expand Down
Loading

0 comments on commit b8a1434

Please sign in to comment.