Compare commits
7 Commits
ee0983fe3a
...
ca092a41c0
Author | SHA1 | Date |
---|---|---|
Gilles Grandou | ca092a41c0 | |
Gilles Grandou | 016d1cf5ce | |
Gilles Grandou | 3da8b1c4d5 | |
Gilles Grandou | 34143560a7 | |
Gilles Grandou | f3c444d0de | |
Gilles Grandou | 2b6652411a | |
Gilles Grandou | 33d79e48f2 |
|
@ -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
161
pool.js
|
@ -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;
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue