initial commit
This commit is contained in:
commit
a09fd25462
246
pool.js
Normal file
246
pool.js
Normal file
@ -0,0 +1,246 @@
|
||||
print("[POOL] start");
|
||||
|
||||
let status = {
|
||||
temp: null,
|
||||
temp_max: null,
|
||||
temp_today: null,
|
||||
temp_yesterday: null,
|
||||
|
||||
update_time: null,
|
||||
|
||||
disable_temp: null,
|
||||
|
||||
tick_timer: 0,
|
||||
tick_day: 0,
|
||||
};
|
||||
|
||||
// compute duration of filtration for a given max temperature
|
||||
// duration is returned in float format (1.25 -> 1h 15mn)
|
||||
|
||||
function compute_duration_filt(t) {
|
||||
if (t < 5)
|
||||
return 1;
|
||||
if (t < 10)
|
||||
return (t/5); // 1 -> 2
|
||||
if (t < 12)
|
||||
return (t-8); // 2 -> 4
|
||||
if (t < 16)
|
||||
return (t/2-2); // 4 -> 6
|
||||
if (t < 24)
|
||||
return (t/4+2); // 6 -> 8
|
||||
if (t < 27)
|
||||
return (t*4/3-24) // 8 -> 12
|
||||
if (t < 30)
|
||||
return (t*4 - 96); // 12 -> 24
|
||||
return 24;
|
||||
}
|
||||
|
||||
// compute the pump schedule for a given duration
|
||||
// returns an array of start/stop times in float
|
||||
// [ start1, stop1, start2, stop2, ... ]
|
||||
|
||||
function compute_schedule_filt(d) {
|
||||
let s = null;
|
||||
if (d < 2) {
|
||||
s = [ 9, 9+d ];
|
||||
} else if (d < 8) {
|
||||
s = [ 9, 10, 14, 14+d-1 ];
|
||||
} else if (d < 11) {
|
||||
s = [ 9, 11, 14, 14+d-2 ];
|
||||
} else if (d < 14) {
|
||||
s = [ 9, 9+d-9, 14, 23];
|
||||
} else if (d < 15) {
|
||||
s = [ 9, 9+d ];
|
||||
} else if (d < 18) {
|
||||
s = [ 24-d, 0 ];
|
||||
} else if (d < 24) {
|
||||
s = [ 6, d-18 ];
|
||||
} else {
|
||||
s = [ 6 ];
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// convert a time to a crontab-like timespec
|
||||
|
||||
function time_to_timespec(t) {
|
||||
let h = Math.floor(t);
|
||||
let m = Math.floor((t-h)*60);
|
||||
let ts = "0 " + JSON.stringify(m) + " " + JSON.stringify(h) + " * * SUN,MON,TUE,WED,THU,FRI,SAT";
|
||||
return ts;
|
||||
}
|
||||
|
||||
// update temperature from Sensor
|
||||
|
||||
function update_temp(temp) {
|
||||
print("[POOL] update_temp", temp);
|
||||
if (status.disable_temp !== null) {
|
||||
print("[POOL] updated disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
status.temp = temp;
|
||||
status.temp_today = Math.max(status.temp_today, temp);
|
||||
status.temp_max = Math.max(status.temp_today, status.temp_yesterday);
|
||||
|
||||
print("[POOL] update_temp - max:", status.temp_max, "today:", status.temp_today, "yesterday:", status.temp_yesterday);
|
||||
}
|
||||
|
||||
// new day, update status
|
||||
|
||||
function update_new_day() {
|
||||
status.tick_day++;
|
||||
print("[POOL] update_new_day", status.tick_day);
|
||||
status.temp_yesterday = status.temp_today;
|
||||
status.temp_today = null;
|
||||
}
|
||||
|
||||
// call a chain of API calls
|
||||
|
||||
function do_call(calls) {
|
||||
if (calls.length === 0) {
|
||||
print("[POOL] call: done.");
|
||||
return;
|
||||
}
|
||||
|
||||
let m = calls[0].method;
|
||||
let p = calls[0].params;
|
||||
calls.splice(0, 1);
|
||||
|
||||
print("[POOL] call:", m, JSON.stringify(p));
|
||||
|
||||
Shelly.call(
|
||||
m,
|
||||
p,
|
||||
function (r, errc, errm, _calls) {
|
||||
do_call(_calls);
|
||||
},
|
||||
calls
|
||||
);
|
||||
}
|
||||
|
||||
// compute & configure pump schedule
|
||||
// TODO force on when duration==24
|
||||
// TODO force off when duration==0
|
||||
// TODO freeze mode if cur < 1
|
||||
|
||||
function update_pump(temp, max, time) {
|
||||
print("[POOL] update_pump", temp, max, time);
|
||||
|
||||
let duration = compute_duration_filt(max);
|
||||
let schedule = compute_schedule_filt(duration);
|
||||
|
||||
print("[POOL] update_pump - duration:", duration);
|
||||
print("[POOL] update_pump - schedule:", JSON.stringify(schedule));
|
||||
|
||||
let calls = [];
|
||||
|
||||
calls.push({method: "Schedule.DeleteAll", params: null});
|
||||
|
||||
let on = true;
|
||||
for (let i = 0; i < schedule.length; i++) {
|
||||
let ts = time_to_timespec(schedule[i]);
|
||||
let p = {
|
||||
id: i+1,
|
||||
enable: true,
|
||||
timespec: ts,
|
||||
calls: [{
|
||||
method: "Switch.Set",
|
||||
params: { id: 0, on: on }
|
||||
}]
|
||||
};
|
||||
calls.push({method: "Schedule.Create", params: p});
|
||||
on = !on;
|
||||
}
|
||||
|
||||
// compute the current switch state according to the schedule
|
||||
let on = false;
|
||||
let j = false;
|
||||
for (let i = 0; i < schedule.length; i++) {
|
||||
j = !j;
|
||||
if (time >= schedule[i])
|
||||
on = j;
|
||||
}
|
||||
|
||||
calls.push({method: "Switch.Set", params: {id: 0, on: on}});
|
||||
|
||||
do_call(calls);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function update_pool() {
|
||||
Shelly.call (
|
||||
"Sys.GetStatus",
|
||||
{},
|
||||
function (result) {
|
||||
let time = result.time; // "HH:MM"
|
||||
print("[POOL] timer", time);
|
||||
|
||||
// compute current time in float format (12h45 -> 12.75)
|
||||
let t = JSON.parse(time.slice(0,2)) + JSON.parse(time.slice(3,5)) / 60;
|
||||
|
||||
if (t < status.update_time)
|
||||
update_new_day();
|
||||
|
||||
status.update_time = t;
|
||||
|
||||
if (status.temp_max !== null)
|
||||
update_pump(status.temp, status.temp_max, t);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// receives updated from Pool Sensor
|
||||
|
||||
MQTT.subscribe(
|
||||
"zigbee2mqtt/Piscine",
|
||||
function (topic, msg) {
|
||||
let obj = JSON.parse(msg);
|
||||
if (obj.temperature === undefined) {
|
||||
return;
|
||||
}
|
||||
update_temp(obj.temperature);
|
||||
}
|
||||
)
|
||||
|
||||
// after a Switch Event, disable temp update
|
||||
// during 10 minutes
|
||||
|
||||
Shelly.addEventHandler(
|
||||
function (data) {
|
||||
if (data.info.event === "toggle") {
|
||||
print("[POOL] disable temp");
|
||||
|
||||
if (status.disable_temp !== null)
|
||||
Timer.clear(status.disable_temp);
|
||||
|
||||
status.disable_temp = Timer.set(
|
||||
600 * 1000,
|
||||
false,
|
||||
function () {
|
||||
print("[POOL] re-enable temp");
|
||||
status.disable_temp = null;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// Run once per hour
|
||||
// - update transition today -> yesterday
|
||||
// - update pump schedule
|
||||
|
||||
Timer.set (
|
||||
3600 * 1000,
|
||||
true,
|
||||
function () {
|
||||
status.tick_timer++;
|
||||
print("[POOL] timer", status.tick_timer);
|
||||
|
||||
update_pool();
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user