Something went wrong. Try again.
Automated watering for the Jolt.js board
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250Jolt.setDriverMode(0, "auto");Jolt.setDriverMode(1, "auto");
function jolterInit() { let ready = false; let unlocked = true; let activeTimer; let advTimer;
const pumps = { 0: H0, 1: H1, 2: H2, 3: H3, 4: H4, 5: H5, 6: H6, 7: H7, }; const nextDay = 86400000; const advConfig = { name: "Jolter", manufacturer: false, connectable: unlocked, scannable: unlocked, interval: 100, }; const bleConfig = { uart: unlocked, }; const voltage = { type: "voltage", v: 0, }; const powerOn = { type: "power_on", v: false, }; const timers = [];
NRF.setTxPower(4); unlockUart(unlocked);
setWatch( function btnWatcher() { unlocked = !unlocked; unlockUart(unlocked); bleActivate(); }, BTN, { edge: "rising", debounce: 50, repeat: true } );
function setPowerAdv(power) { voltage.v = E.getAnalogVRef(); powerOn.v = power;
if (advTimer) clearTimeout(advTimer); advTimer = setTimeout(closeAdv, 10000); bleActivate(); NRF.setAdvertising( require("BTHome").getAdvertisement([voltage, powerOn]), advConfig ); }
function closeAdv() { advTimer = undefined; bleActivate(); }
function bleActivate() { if (unlocked || advTimer) { NRF.wake(); } else { NRF.sleep(); } setLEDStatus(); }
function updateTimerToNext(config) { config.timer.setTime(config.timer.getTime() + nextDay * config.every); }
function calcDelay(alarm) { let now = Date.now(); return alarm.getTime() - now; }
function schedulerResolver(resolve, val) { activeTimer = undefined; resolve(val); }
function schedule(delay, val) { return new Promise((resolve) => { activeTimer = setTimeout(schedulerResolver, delay, resolve, val); }); }
function scheduleOn(date, val) { return schedule(calcDelay(date), val); }
function unlockUart(isUnlocked) { bleConfig.uart = advConfig.connectable = advConfig.scannable = isUnlocked; NRF.setServices(undefined, bleConfig); }
function sortTime(a, b) { return a.timer.getTime() - b.timer.getTime() || a.pump - b.pump; }
function scheduleTimers() { setPowerAdv(false);
let when; let next_timers = timers.sort(sortTime).filter((t) => { if (!when) { when = t.timer; return true; } else { return when === t.timer; } });
return when ? scheduleOn(when, next_timers).then(executeTimers) : Promise.resolve(); }
function executeTimers(next) { setPowerAdv(true); return next.reduce(loadSequence, Promise.resolve()).then(scheduleTimers); }
function loadSequence(sequence, timer) { return sequence .then(startSequence.bind(undefined, timer)) .then(finishSequence); }
function startSequence(config) { pumps[config.pump].set(); return schedule(config.duration, config); }
function finishSequence(config) { pumps[config.pump].read(); updateTimerToNext(config); }
function setLEDStatus() { if (unlocked) { LED1.write(1); LED2.write(0); } else { LED1.write(0); LED2.write(!!advTimer); } }
function configureTimers(config) { if (config.pump < 0 || config.pump > 7) { throw new Error("Invalid pump config: " + config.pump); } let now = new Date(); let time = new Date(); time.setHours(config.hour, config.minute, 0, 0); config.timer = time; config.duration = config.duration * 1000; if (config.timer < now) { updateTimerToNext(config); } return config; }
return { clear: function () { if (activeTimer) clearTimeout(activeTimer); ready = false; timers.length = 0; return this; },
load: function (timer) { timers.push(configureTimers(timer)); return this; },
loadTimers: function (loaded) { for (let i = 0; i < loaded.length; i += 1) { this.load(loaded[i]); } return this; },
loadJSON: function (objString) { let obj = JSON.parse(objString);
if (obj.timers) { this.loadTimers(obj.timers); } if (obj.datetime) { this.setTime(obj.datetime); } if (obj.tz) { this.setTz(tz); }
return this; },
setTime: function (datetime) { if (activeTimer) clearTimeout(activeTimer); if (typeof datetime === "number") setTime(new Date(datetime)); return this; },
setTz: function (tz) { if (activeTimer) clearTimeout(activeTimer); if (typeof tz === "number" && E.setTimeZone) E.setTimeZone(tz); return this; },
ready: function () { ready = true; return this; },
start: function () { if (ready) { scheduleTimers(); } else { throw new Error("Jolter is not properly configured and can't run"); } }, };}
var Jolter = jolterInit();
Jolter.clear() .loadTimers([ { pump: 0, hour: 17, minute: 46, duration: 15, every: 1 }, { pump: 0, hour: 17, minute: 47, duration: 15, every: 2 }, ]) .ready() .start();