Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 26 additions & 21 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
{
"extends": "eslint:recommended",
"env": {
"node": true,
"es6": true,
"mocha": true,
"browser": true
},
"linebreak-style": 0,
"extends": "athom",
"rules": {
"no-mixed-spaces-and-tabs": 0, // disable rule
"callback-return": "warn",
"handle-callback-err": "error",
"no-new-require": "error",
"no-empty-function": "error",
"global-require": "error",
"no-return-await": "error",
"no-catch-shadow": "error",
"no-await-in-loop": "error",
"array-callback-return" : "error",
"no-invalid-this" : "error"
"brace-style": "off",
"camelcase": "off",
"consistent-return": "off",
"eqeqeq": "off",
"func-names": "off",
"global-require": "off",
"guard-for-in": "off",
"import/extensions": "off",
"max-len": 0,
"no-async-promise-executor": "off",
"no-cond-assign": "off",
"no-console": "off",
"no-const-assign": "off",
"no-const-assignt": "off",
"no-constant-condition": "off",
"no-mixed-spaces-and-tabs": "off",
"no-new": "off",
"no-restricted-syntax": "off",
"no-tabs": "off",
"no-undef": "off",
"no-unused-vars": "off",
"node/no-unsupported-features/node-builtins": "off",
"radix": "off",
"valid-typeof": "off"
}

}
}
32 changes: 22 additions & 10 deletions .github/workflows/validate.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
name: Validate Homey App
name: CI

on:
pull_request:
Expand All @@ -13,22 +13,34 @@ permissions:
contents: read

jobs:
validate:
homey-validate:
runs-on: ubuntu-latest
name: Validate Homey App

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Node.js
uses: actions/setup-node@v2
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 20.9.0
cache: "npm"
cache: 'npm'

- name: Install Homey CLI
run: npm install --no-optional homey
- run: npm install --include=optional sharp
run: npm ci --no-optional homey
- run: npm ci --include=optional sharp

- name: Validate Homey App
run: npx homey app validate --level=publish

lint-eslint:
name: eslint
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20.9.0
cache: 'npm'

- run: npm ci
- run: npm run lint-check
26 changes: 26 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
repos:
- repo: local
hooks:
- id: linter
name: Linter
pass_filenames: False
language: system
entry: npm run lint

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.1.0
hooks:
- id: no-commit-to-branch
name: Check if commit is not in branch 'master'
args:
- --branch=main # For future us
- --branch=master

- id: end-of-file-fixer
- id: check-json
- id: check-yaml
- id: check-added-large-files
- id: check-case-conflict
- id: trailing-whitespace
- id: mixed-line-ending
24 changes: 12 additions & 12 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
"use strict";
'use strict';

const Homey = require('homey');

const Testing = false;

class HomeWizardApp extends Homey.App {
onInit() {
console.log("HomeWizard app ready!");
if (process.env.DEBUG === '1' && Testing) {
try{
require('inspector').waitForDebugger();
}
catch(error){
require('inspector').open(9225, '0.0.0.0', true);
}
}
onInit() {
console.log('HomeWizard app ready!');
if (process.env.DEBUG === '1' && Testing) {
try {
require('inspector').waitForDebugger();
}
catch (error) {
require('inspector').open(9225, '0.0.0.0', true);
}
}

}
}
}

module.exports = HomeWizardApp;
101 changes: 49 additions & 52 deletions drivers/SDM230/device.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = class HomeWizardEnergyDevice230 extends Homey.Device {
}

onDeleted() {
if( this.onPollInterval ) {
if (this.onPollInterval) {
clearInterval(this.onPollInterval);
}
}
Expand All @@ -42,28 +42,28 @@ module.exports = class HomeWizardEnergyDevice230 extends Homey.Device {
}

onPoll() {
if( !this.url ) return;
if (!this.url) return;

Promise.resolve().then(async () => {

let res = await fetch(`${this.url}/data`);
if( !res || !res.ok ) {
await new Promise((resolve) => setTimeout(resolve, 60000)); // wait 60s to avoid false reports due to bad wifi from users

if (!res || !res.ok) {
await new Promise((resolve) => setTimeout(resolve, 60000)); // wait 60s to avoid false reports due to bad wifi from users
// try again
res = await fetch(`${this.url}/data`);
if( !res || !res.ok )
throw new Error(res ? res.statusText : 'Unknown error during fetch');
if (!res || !res.ok)
{ throw new Error(res ? res.statusText : 'Unknown error during fetch'); }
}

const data = await res.json();

// OLD CODE / REPLACED BY SOCKET METHOD
// if (((data.active_power_w < 0) || (data.active_power_l1_w < 0)) && (this.getClass() == 'sensor')) {
// if (this.getClass() != 'solarpanel') {
// await this.setClass('solarpanel').catch(this.error);
// }
// }
// OLD CODE / REPLACED BY SOCKET METHOD
// if (((data.active_power_w < 0) || (data.active_power_l1_w < 0)) && (this.getClass() == 'sensor')) {
// if (this.getClass() != 'solarpanel') {
// await this.setClass('solarpanel').catch(this.error);
// }
// }

// Save export data check if capabilities are present first
if (!this.hasCapability('measure_power')) {
Expand All @@ -76,7 +76,7 @@ module.exports = class HomeWizardEnergyDevice230 extends Homey.Device {

if (!this.hasCapability('meter_power.consumed.t1')) {
await this.addCapability('meter_power.consumed.t1').catch(this.error);
//await this.addCapability('meter_power.consumed.t2').catch(this.error);
// await this.addCapability('meter_power.consumed.t2').catch(this.error);
}

if (!this.hasCapability('measure_power.l1')) {
Expand All @@ -88,7 +88,7 @@ module.exports = class HomeWizardEnergyDevice230 extends Homey.Device {
}

if (this.getCapabilityValue('rssi') != data.wifi_strength)
await this.setCapabilityValue('rssi', data.wifi_strength).catch(this.error);
{ await this.setCapabilityValue('rssi', data.wifi_strength).catch(this.error); }

// Update values 3phase kwh
// KWH 1 fase
Expand All @@ -101,85 +101,82 @@ module.exports = class HomeWizardEnergyDevice230 extends Homey.Device {

// First we need to check if the kwh active_power_w is negative (solar)

// if ((data.active_power_w < 0) || (data.active_power_l1_w < 0) || (this.getClass() != 'socket')) {
// if (this.getClass() != 'solarpanel') {
// await this.setClass('solarpanel').catch(this.error);
// }
// }

// if ((data.active_power_w < 0) || (data.active_power_l1_w < 0) || (this.getClass() != 'socket')) {
// if (this.getClass() != 'solarpanel') {
// await this.setClass('solarpanel').catch(this.error);
// }
// }

// There are old paired SDM230 devices that still have the old sensor and show negative values that needs to be inverted
if (this.getClass() == 'solarpanel') {
await this.setCapabilityValue('measure_power', data.active_power_w * -1).catch(this.error);
await this.setCapabilityValue('measure_power', data.active_power_w * -1).catch(this.error);
} else {
await this.setCapabilityValue('measure_power', data.active_power_w).catch(this.error);
}


//await this.setCapabilityValue('measure_power.active_power_w', data.active_power_w).catch(this.error);
// await this.setCapabilityValue('measure_power.active_power_w', data.active_power_w).catch(this.error);
await this.setCapabilityValue('meter_power.consumed.t1', data.total_power_import_t1_kwh).catch(this.error);

//There are old paired SDM230 devices that still have the old sensor and show negative values that needs to be inverted
// There are old paired SDM230 devices that still have the old sensor and show negative values that needs to be inverted
if (this.getClass() == 'solarpanel') {
await this.setCapabilityValue('measure_power.l1', data.active_power_l1_w *-1).catch(this.error);
await this.setCapabilityValue('measure_power.l1', data.active_power_l1_w * -1).catch(this.error);
} else {
await this.setCapabilityValue('measure_power.l1', data.active_power_l1_w).catch(this.error);
await this.setCapabilityValue('measure_power.l1', data.active_power_l1_w).catch(this.error);
}
//await this.setCapabilityValue('meter_power.consumed.t2', data.total_power_import_t2_kwh).catch(this.error);
// await this.setCapabilityValue('meter_power.consumed.t2', data.total_power_import_t2_kwh).catch(this.error);

// Check to see if there is solar panel production exported if received value is more than 1 it returned back to the power grid
if (data.total_power_export_t1_kwh > 1) {
if (!this.hasCapability('meter_power.produced.t1')) {
// add production meters
await this.addCapability('meter_power.produced.t1').catch(this.error);
}
// update values for solar production
await this.setCapabilityValue('meter_power.produced.t1', data.total_power_export_t1_kwh).catch(this.error);
}
if (!this.hasCapability('meter_power.produced.t1')) {
// add production meters
await this.addCapability('meter_power.produced.t1').catch(this.error);
}
// update values for solar production
await this.setCapabilityValue('meter_power.produced.t1', data.total_power_export_t1_kwh).catch(this.error);
}
else if (data.total_power_export_t1_kwh < 1) {
await this.removeCapability('meter_power.produced.t1').catch(this.error);
await this.removeCapability('meter_power.produced.t1').catch(this.error);
}

// aggregated meter for Power by the hour support
if (!this.hasCapability('meter_power')) {
await this.addCapability('meter_power').catch(this.error);
await this.addCapability('meter_power').catch(this.error);
}
// update calculated value which is sum of import deducted by the sum of the export this overall kwh number is used for Power by the hour app
await this.setCapabilityValue('meter_power', (data.total_power_import_t1_kwh-data.total_power_export_t1_kwh)).catch(this.error);
await this.setCapabilityValue('meter_power', (data.total_power_import_t1_kwh - data.total_power_export_t1_kwh)).catch(this.error);

//active_voltage_l1_v
// active_voltage_l1_v
if (data.active_voltage_v !== undefined) {
if (!this.hasCapability('measure_voltage')) {
await this.addCapability('measure_voltage').catch(this.error);
}
if (this.getCapabilityValue('measure_voltage') != data.active_voltage_v)
await this.setCapabilityValue("measure_voltage", data.active_voltage_v).catch(this.error);
}
if (this.getCapabilityValue('measure_voltage') != data.active_voltage_v)
{ await this.setCapabilityValue('measure_voltage', data.active_voltage_v).catch(this.error); }
}
else if ((data.active_voltage_v == undefined) && (this.hasCapability('measure_voltage'))) {
await this.removeCapability('measure_voltage').catch(this.error);
}

//active_current_a Amp's
// active_current_a Amp's
if (data.active_current_a !== undefined) {
if (!this.hasCapability('measure_current')) {
await this.addCapability('measure_current').catch(this.error);
}
if (this.getCapabilityValue('measure_current') != data.active_current_a)
await this.setCapabilityValue("measure_current", data.active_current_a).catch(this.error);
}
if (this.getCapabilityValue('measure_current') != data.active_current_a)
{ await this.setCapabilityValue('measure_current', data.active_current_a).catch(this.error); }
}
else if ((data.active_current_a == undefined) && (this.hasCapability('measure_current'))) {
await this.removeCapability('measure_current').catch(this.error);
await this.removeCapability('measure_current').catch(this.error);
}


})
.then(() => {
this.setAvailable().catch(this.error);
})
.catch(err => {
.catch((err) => {
this.error(err);
this.setUnavailable(err).catch(this.error);
})
});
}

}
};
Loading