Skip to content

Commit

Permalink
error corrections, introduce state for running program, config value …
Browse files Browse the repository at this point in the history
…for normal number of days between watering
  • Loading branch information
tukey42 committed Apr 9, 2024
1 parent cd26234 commit 7e4d7d0
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 26 deletions.
14 changes: 13 additions & 1 deletion admin/jsonConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@
"lg":4,
"xs":4,
"newLine": true
},
"numdays": {
"type": "number",
"label": "Number of days used for weather factor calculation",
"min": 0,
"max": 7,
"default": 1,
"sm":4,
"md":4,
"lg":4,
"xs":4,
"newLine": true
}
}
},
Expand Down Expand Up @@ -50,7 +62,7 @@
"tooltip": "eindeutiger Name der Zone",
"filter": false,
"sort": false,
"default": "",
"default": ""
},
{
"type": "objectId",
Expand Down
13 changes: 13 additions & 0 deletions io-package.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,19 @@
},
"native": {}
},
{
"_id": "info.actprogram",
"type": "state",
"common": {
"role": "state",
"name": "Active Program",
"type": "string",
"read": true,
"write": false,
"def": "none"
},
"native": {}
},
{
"_id": "zones",
"type": "device",
Expand Down
6 changes: 6 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ async function delete_devices(gadapter, device, conflist, statelist, namelist) {


async function config2object(gadapter, conflist, device, statelist) {

if (conflist == null || typeof conflist[Symbol.iterator] !== 'function') {
gadapter.log.info(`No ${device} configure`);
return;
}

try {
const actlist_long = await gadapter.getChannelsAsync(device);
const actlist_names = actlist_long.map((x) => x.common.name);
Expand Down
29 changes: 23 additions & 6 deletions lib/program.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Programs {
for (let s of slist) {
gadapter.log.debug(`Getting value for state ${s.common.name} (id: ${s._id})`);
const obj = await this.adapter.getStateAsync(s._id);
if (s.common.name == 'running') {
if (s.common.name == 'running' || s.common.name == 'enabled') {
await this.adapter.subscribeStatesAsync(s._id);
}
this.adapter.log.debug(`State value ${s._id}: ` + JSON.stringify(obj));
Expand Down Expand Up @@ -106,10 +106,17 @@ class Programs {
return;
}

if (state.val) {
if (!p.isRunning()) this.startProgram(p, true);
} else {
if (p.isRunning()) this.stopProgram(p);
const comp = id.split('.');
const entry = comp.at(-1);

if (entry == 'running') {
if (state.val) {
if (!p.isRunning()) this.startProgram(p, true);
} else {
if (p.isRunning()) this.stopProgram(p);
}
} else if (entry == 'enabled') {
p.doenable(state.val);
}
}

Expand All @@ -130,6 +137,7 @@ class Programs {
async startProgram(p, force = false) {
if (!p.isEnabled()) {
gadapter.log.info(`Program ${p.name} is disabled`);
await gadapter.setStateAsync(`${gadapter.namespace}.${device_name}.${p.name}.running`, false, true);
return;
}
// check weather
Expand All @@ -156,7 +164,7 @@ class Programs {

if (!p || p.zoneActive()) return;

p.start(await this.weather.condition());
p.start(await this.weather.condition(gadapter.config.numdays));


}
Expand Down Expand Up @@ -274,6 +282,7 @@ class Program {
}
this.running = true;
await gadapter.setStateAsync(`${gadapter.namespace}.${device_name}.${this.name}.running`, true, true);
await gadapter.setStateAsync(`${gadapter.namespace}.info.actprogram`, this.name, true);
}

async stop() {
Expand All @@ -296,6 +305,7 @@ class Program {
this.running = false;
this.active = 0;
await gadapter.setStateAsync(`${gadapter.namespace}.${device_name}.${this.name}.running`, false, true);
await gadapter.setStateAsync(`${gadapter.namespace}.info.actprogram`, 'none', true);
}
}

Expand Down Expand Up @@ -328,6 +338,7 @@ class Program {
this.active = 0;
this.running = false;
await gadapter.setStateAsync(`${gadapter.namespace}.${device_name}.${this.name}.running`, false, true);
await gadapter.setStateAsync(`${gadapter.namespace}.info.actprogram`, 'none', true);
return false;
} else {
let act_zone = zl[this.active-1];
Expand All @@ -343,6 +354,7 @@ class Program {
this.active = 0;
this.running = false;
await gadapter.setStateAsync(`${gadapter.namespace}.${device_name}.${this.name}.running`, false, true);
await gadapter.setStateAsync(`${gadapter.namespace}.info.actprogram`, 'none', true);
return false;
} else {
let new_zone = zl[this.active-1];
Expand All @@ -362,6 +374,11 @@ class Program {
return this.enabled;
}

doenable(val) {
gadapter.log.info(`${val ? "Enable" : "Disable"} program ${this.name}`);
this.enabled = val;
}

activeZone() {
let zl = this.zone_list;
if (this.active > 0 && zl.length >= this.active) {
Expand Down
35 changes: 33 additions & 2 deletions lib/schedule.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ class Schedules {

this.adapter.log.info(`state value ${s._id}: ` + JSON.stringify(obj));
a[s.common.name] = obj.val;

if (s.common.name == 'enabled') {
await this.adapter.subscribeStatesAsync(s._id);
}

}
if (a.hasOwnProperty('schedule') && a.hasOwnProperty('program') && a.hasOwnProperty('enabled')) {
let sched = new Schedule(sc.common.name, a.schedule, a.program, a.enabled);
Expand All @@ -72,6 +77,22 @@ class Schedules {
await this.startAll();
}

async stateChange(id, state) {
const s = this.getSchedule(id);
gadapter.log.info(`State change (schedule) ${id} (${s.name}), state: ` + JSON.stringify(state));

if (!s || !state) {
return;
}

const comp = id.split('.');
const entry = comp.at(-1);
if (entry == 'enabled') {
s.doenable(state.val);
}
}



getschedules() {
return this.schedules;
Expand All @@ -80,7 +101,7 @@ class Schedules {
getSchedule(id) {
for (let z of this.schedules) {
gadapter.log.debug(`getSchedule, id=${id}, ${device_name}.${z.name}`);
if (z.name == id || `${device_name}.${z.name}` == id) {
if (z.name == id || id.startsWith(`${device_name}.${z.name}`)) {
return z;
}
}
Expand Down Expand Up @@ -154,7 +175,7 @@ class Schedule {
if (!this.enabled || !this.schedule || !this.program) return;

if (this.job) {
gadapter.log.error('Scheduler for ${this.name} already running');
gadapter.log.error(`Scheduler for ${this.name} already running`);
return;
}

Expand All @@ -176,6 +197,16 @@ class Schedule {
}

}

doenable(val) {
gadapter.log.info(`${val ? "Enable" : "Disable"} schedule ${this.name}`);
this.enabled = val;
if (val) {
this.start();
} else {
this.stop();
}
}
}

module.exports = { Schedules, Schedule };
10 changes: 7 additions & 3 deletions lib/weather.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,18 @@ class Weather {
return this.raining;
}

async condition() {
async condition(days) {
// return factor to correct irrigation time
let ret = 1.0;
const obj = await this.adapter.getForeignStateAsync(this.weatherFactor);
gadapter.log.debug(`ret is ${ret}, ${typeof obj.val}`);
gadapter.log.debug(`ret is ${ret}, ${typeof obj.val}, ${typeof days}, ${days}`);
if (obj && obj.val) {
const oval = JSON.parse(obj.val);
ret = oval[0];
ret = 0;
for (let i = 0; i < days; i++) {
ret += oval[i];
}
ret /= days;
}
// limit value between 0% and 200%
if (ret < 0) ret = 0;
Expand Down
37 changes: 26 additions & 11 deletions lib/zone.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class Zones {
for (let s of slist) {
this.adapter.log.debug(`Getting value for state ${s.common.name}`);
const obj = await this.adapter.getStateAsync(s._id);
if (s.common.name == 'state') {
if (s.common.name == 'state' || s.common.name == 'enabled') {
await this.adapter.subscribeStatesAsync(s._id);
}
if (s.common.name == 'state_device') {
Expand Down Expand Up @@ -87,7 +87,7 @@ class Zones {
}
return 0;
*/
return this.zonelist.find(z => (z.name == id || z.state_device == id || z.ontime_device == id || `${device_name}.${z.name}.state` == id));
return this.zonelist.find(z => (z.name == id || z.state_device == id || z.ontime_device == id || id.startsWith(`${device_name}.${z.name}`)));
}

static async incrActive() {
Expand All @@ -107,18 +107,25 @@ class Zones {

async stateChange(id, state) {
const z = this.getZone(id);
gadapter.log.info(`(Zone) State change ${id}, zone: ${z.name}, state: ${state}`);
gadapter.log.info(`(Zone) State change ${id}, zone: ${z.name}, state: ${JSON.stringify(state)}`);

if (!z || !state) return;

if (id.startsWith(device_name)) {
if (!state.ack) {
gadapter.log.debug(`do zone: ${state.val}`);
if (state.val) {
z.start();
} else {
z.stop();
const comp = id.split('.');
const entry = comp.at(-1);

if (comp[0] == device_name) {
if (entry == 'state') {
if (!state.ack) {
gadapter.log.debug(`do zone: ${state.val}`);
if (state.val) {
z.start();
} else {
z.stop();
}
}
} else if (entry == 'enabled') {
z.doenable(state.val);
}
} else {
if (state.ack) {
Expand Down Expand Up @@ -193,10 +200,18 @@ class Zone {
this.timeout = null;
}

doenable(val) {
gadapter.log.info(`${val ? "Enable" : "Disable"} zone ${this.name}`);
this.enabled = val;
}


async start(timo = 0, factor = 1) {

if (!this.enabled) return;
if (!this.enabled) {
await gadapter.setStateAsync(`${gadapter.namespace}.${device_name}.${this.name}.state`, false, true);
return;
}
if (timo == 0) timo = this.default_ontime;
timo = timo * factor;
gadapter.log.info(`Zone ${this.name} start (timo=${timo}), ontime=${this.ontime_device}`);
Expand Down
3 changes: 2 additions & 1 deletion main.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,10 @@ class IrrigationControl extends utils.Adapter {
const i = id.substring(this.namespace.length+1);
if (comp[2] == 'zones' && this.zones) {
this.zones.stateChange(i, state);
this.progs.zoneChange(i, state);
if (comp.at(-1) == 'state') this.progs.zoneChange(i, state);
}
if (comp[2] == 'programs' && this.progs) this.progs.stateChange(i, state);
if (comp[2] == 'schedules' && this.schedules) this.schedules.stateChange(i, state);
} else {
if (id == this.config.rainSensor) {
this.weather.stateChange(id, state);
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7e4d7d0

Please sign in to comment.