Compare commits

...

7 Commits

2 changed files with 113 additions and 51 deletions

View File

@ -1,3 +1,6 @@
#!/bin/bash -e
source $(dirname $0)/shelly.conf
./eval_script 'JSON.stringify(status)'
curl -s $SHELLY_RPC/Sys.GetStatus | jq .

161
pool.js
View File

@ -16,6 +16,10 @@ let status = {
duration: null,
schedule: null,
time: null,
uptime: null,
tick: 0,
tick_mqtt: 0,
tick_temp: 0,
tick_lock: 0,
@ -24,27 +28,37 @@ let status = {
tick_day: 0,
};
// compute duration of filtration for a given max temperature
// temperature->duration chart
let filt_time = [
[ 5, 1.0 ], // at 5°C, 1 hour of filtering
[ 10, 2.0 ],
[ 12, 4.0 ],
[ 16, 6.0 ],
[ 24, 8.0 ],
[ 27, 12.0 ],
[ 30, 24.0 ]
];
// compute filtration time 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;
function compute_filtration_time(t) {
let len = filt_time.length;
if (t < filt_time[0][0])
return filt_time[0][1];
for (let i = 0; i < len-1; i++) {
if (t >= filt_time[i][0] && t < filt_time[i+1][0]) {
// linear interpolation between two points
return filt_time[i][1] + (filt_time[i+1][1] - filt_time[i][1]) / (filt_time[i+1][0] - filt_time[i][0]) * (t - filt_time[i][0]);
}
}
return filt_time[len-1][1];
}
// compute the pump schedule for a given duration
// returns an array of start/stop times in float
// [ start1, stop1, start2, stop2, ... ]
@ -88,6 +102,14 @@ function update_new_day() {
print("[POOL] update_new_day", status.tick_day);
status.temp_yesterday = status.temp_today;
status.temp_today = null;
Shelly.call(
"KVS.Set",
{ key: "pool.temp_yesterday", value: status.temp_yesterday },
function (result) {
print("[POOL] KVS set: ", JSON.stringify(result));
}
);
}
// call a chain of API calls
@ -123,7 +145,7 @@ function update_pump(temp, max, time) {
status.tick_pump++;
print("[POOL] update_pump", status.tick_pump, "- temp:", temp, "max:", max, "time:", time);
let duration = compute_duration_filt(max);
let duration = compute_filtration_time(max);
let schedule = compute_schedule_filt(duration);
print("[POOL] update_pump - duration:", duration);
@ -154,11 +176,20 @@ function update_pump(temp, max, time) {
// 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;
if (schedule.length === 1) {
on = true;
}
else {
for (let i = 0; i < schedule.length; i+=2) {
let a=schedule[i];
let b=schedule[i+1];
if (a<b && time >= a && time < b) {
on = true;
}
else if (a>b && (time >= a || time < b)) {
on = true;
}
}
}
calls.push({method: "Switch.Set", params: {id: 0, on: on}});
@ -194,43 +225,53 @@ function update_temp(temp) {
print("[POOL] update_temp - max:", status.temp_max, "today:", status.temp_today, "yesterday:", status.temp_yesterday);
if (status.temp_max !== status.update_temp_max_last) {
Shelly.call (
"Sys.GetStatus",
{},
function (result) {
let time = result.time; // "HH:MM"
print("[POOL] time", time);
Shelly.call (
"Sys.GetStatus",
{},
function (result) {
let time = result.time; // "HH:MM"
print("[POOL] time", 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;
// 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();
if (t < status.update_time)
update_new_day();
status.update_time = t;
status.update_time = t;
if (status.temp_max !== null) {
if ((t - status.update_time_last) > 0.15) { // 9 minutes
update_pump(status.temp, status.temp_max, t);
status.update_time_last = t;
status.update_temp_max_last = status.temp_max;
}
else {
status.tick_pump_skip++;
print("[POOL] to much update_pump, skipped", status.tick_pump_skip);
}
}
if ((status.temp_max !== null) && (status.temp_max !== status.update_temp_max_last)) {
if ((t - status.update_time_last) > 0.15) { // 9 minutes
update_pump(status.temp, status.temp_max, t);
status.update_time_last = t;
status.update_temp_max_last = status.temp_max;
}
else {
status.tick_pump_skip++;
print("[POOL] to much update_pump, skipped", status.tick_pump_skip);
}
}
);
}
else {
print("[POOL] no temp change, skip update_pump");
}
else {
print("[POOL] no temp change, skip update_pump");
}
}
);
status.lock_update = false;
}
// Set initial yesterday temp from KVS
Shelly.call (
"KVS.Get",
{ key: "pool.temp_yesterday" },
function (result) {
if (result) {
status.temp_yesterday = result.value;
print("[POOL] Restore from KVS: temp_yesterday:", status.temp_yesterday);
}
}
)
// receives update from Pool Sensor
// - trigger all temperature and pump updates
@ -271,4 +312,22 @@ Shelly.addEventHandler(
}
);
// Debug...
Timer.set(
60 * 1000,
true,
function() {
status.tick++;
Shelly.call (
"Sys.GetStatus",
{},
function (result) {
print("[POOL] tick", result.time);
status.time = result.time;
status.uptime = result.uptime;
}
);
}
);