From a262fef79cce70e58151d7ef9a4a6710200401e7 Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Mon, 28 Sep 2020 10:50:23 +0100 Subject: [PATCH] working bits --- app.js | 59 +++++++++++++++++++++++++++++++--------- libs/globalVars.js | 5 ++++ libs/lcd.js | 65 ++++++++++++++++++++++++--------------------- modules/heating.js | 24 +++++++++-------- modules/mainMenu.js | 58 +++++++++++++++++++++++++++------------- modules/pihole.js | 46 ++++++++++++++++++++++++++++++++ modules/water.js | 3 ++- package-lock.json | 5 ++++ package.json | 1 + 9 files changed, 192 insertions(+), 74 deletions(-) create mode 100644 modules/pihole.js diff --git a/app.js b/app.js index aa171ef..ea9e597 100644 --- a/app.js +++ b/app.js @@ -11,28 +11,44 @@ async function main() { await lcd.intro() menu.home() - const heatingSwitch = new Gpio('17', 'in', 'both'); + const functionSwitch = new Gpio('17', 'in', 'both'); const appSwitch = new Gpio('23', 'in', 'both'); - heatingSwitch.watch(async (err, value) => { + functionSwitch.watch(async (err, value) => { if (err) { console.log('Error', err); } if (value === 1) { - console.log('Water Switch') - if (globalVars.waterOn === 'true') { - await common.request(0) - await common.pause(2000) - menu.water() - } else { - await common.request(1) - await common.pause(2000) - menu.water() + switch (globalVars.currentPage) { + case 'water': + console.log('Water Switch') + if (globalVars.waterOn === 'true') { + await common.request(0) + await common.pause(2000) + await menu.water() + } else { + await common.request(1) + await common.pause(2000) + await menu.water() + } + break; + case 'heating': + if (globalVars.heatingPageS === 1) { + clearInterval(globalVars.heatingPolling) + globalVars.heatingPageS = 2 + } else { + clearInterval(globalVars.heatingPolling) + globalVars.heatingPageS = 1 + } + await menu.heating(globalVars.heatingPageS) + break; + default: + break; } } }) - const arr = ['water', 'heating', 'mainMenu'] + const arr = ['water', 'heating', 'pihole', 'mainMenu'] arrLength = arr.length let i = 0 appSwitch.watch(async (err, value) => { @@ -42,18 +58,36 @@ async function main() { if (value === 1) { switch (arr[i]) { case 'water': + globalVars.currentPage = arr[i] + clearInterval(globalVars.waterPolling) + clearInterval(globalVars.heatingPageSwitch) + clearInterval(globalVars.heatingPolling) await menu.water() break; case 'mainMenu': + globalVars.currentPage = arr[i] + clearInterval(globalVars.waterPolling) + clearInterval(globalVars.heatingPageSwitch) clearInterval(globalVars.heatingPolling) led.set('off') await menu.home() break; case 'heating': + globalVars.currentPage = arr[i] clearInterval(globalVars.waterPolling) + clearInterval(globalVars.heatingPageSwitch) + clearInterval(globalVars.heatingPolling) led.set('off') await menu.heating() break; + case 'pihole': + globalVars.currentPage = arr[i] + clearInterval(globalVars.waterPolling) + clearInterval(globalVars.heatingPageSwitch) + clearInterval(globalVars.heatingPolling) + led.set('off') + await menu.piHole() + break; default: break; } @@ -74,4 +108,5 @@ process.on('SIGINT', function () { process.exit(1) }); +setInterval(lcd.time, 55000) main() \ No newline at end of file diff --git a/libs/globalVars.js b/libs/globalVars.js index fb6339b..7cabf0f 100644 --- a/libs/globalVars.js +++ b/libs/globalVars.js @@ -4,6 +4,11 @@ class globalVariables { waterPolling = ""; heatingNextEvent = ""; heatingPolling = ""; + currentPage = ""; + heatingPageSwitch = ""; + heatingPageSwitchActive = ""; + heatingPageS = 1; + piHolePolling = ""; } module.exports = new globalVariables(); \ No newline at end of file diff --git a/libs/lcd.js b/libs/lcd.js index a3ad1c3..64b96f0 100644 --- a/libs/lcd.js +++ b/libs/lcd.js @@ -2,6 +2,7 @@ const LCD = require('raspberrypi-liquid-crystal'); const common = require('./common') const globalVars = require('./globalVars') const clock = require('./clock'); +var commaNumber = require('comma-number') const lcd = new LCD(1, 0x27, 20, 4); @@ -18,7 +19,7 @@ module.exports = { }, intro: async () => { lcd.clearSync(); - lcd.printLineSync(1, 'MiGenie Status') + lcd.printLineSync(1, 'House Status') lcd.setCursorSync(13, 2); lcd.printSync('By Karl') await common.pause(3000) @@ -29,7 +30,8 @@ module.exports = { lcd.printSync(title) }, time: async () => { - console.log('get time') + let t = new Date().toUTCString() + console.log(t + ' get time') lcd.setCursorSync(15, 0); lcd.printSync(await clock.time()) }, @@ -48,46 +50,47 @@ module.exports = { lcd.printSync(input) }, NextEvent: async (input) => { - if (globalVars.waterOn === "true") { + if (input === 'Not Set') { lcd.setCursorSync(0, 3) - lcd.printSync("Switch Off=") - lcd.setCursorSync(11, 3); - lcd.printSync(' ') - lcd.setCursorSync(11, 3); - lcd.printSync(input) + lcd.printSync("Always Off") } else { - lcd.setCursorSync(0, 3) - lcd.printSync("Switch On=") - lcd.setCursorSync(10, 3); - lcd.printSync(' ') - lcd.setCursorSync(10, 3); - lcd.printSync(input) + if (globalVars.waterOn === "true") { + lcd.setCursorSync(0, 3) + lcd.printSync("Switch Off=") + lcd.setCursorSync(11, 3); + lcd.printSync(' ') + lcd.setCursorSync(11, 3); + lcd.printSync(input) + } else { + lcd.setCursorSync(0, 3) + lcd.printSync("Switch On=") + lcd.setCursorSync(10, 3); + lcd.printSync(' ') + lcd.setCursorSync(10, 3); + lcd.printSync(input) + } } }, currentRoomTemp: async (temp) => { - lcd.setCursorSync(0, 1); - let icon = '\xDF' - temp = temp + icon - lcd.printSync('CT:' + temp); + lcd.printLineSync(2, 'Current Temp:' + temp + '\xDF') }, lastSetTemp: async (temp) => { - lcd.setCursorSync(14, 1); - let icon = '\xDF' - temp = temp + icon - lcd.printSync('LT:' + temp); + lcd.printLineSync(3, 'Last Set Temp:' + temp + '\xDF') }, - heatingPageOne: async (heatingStatus, measuredRoomTemp, lastTimerSetPoint, heatingNextEvent) => { - module.exports.currentRoomTemp(measuredRoomTemp) - module.exports.lastSetTemp(lastTimerSetPoint) - module.exports.NextEvent(heatingNextEvent) - module.exports.heatingStatus(heatingStatus) + heatingPageOne: async (heatingStatus, heatingNextEvent) => { + await module.exports.NextEvent(heatingNextEvent) + await module.exports.heatingStatus(heatingStatus) }, heatingPageTwo: async (measuredRoomTemp, lastTimerSetPoint) => { - module.exports.currentRoomTemp(measuredRoomTemp) - module.exports.lastSetTemp(lastTimerSetPoint) + await module.exports.currentRoomTemp(measuredRoomTemp) + await module.exports.lastSetTemp(lastTimerSetPoint) }, waterPageOne: async (waterStatus, waterNextEvent) => { - module.exports.NextEvent(waterNextEvent) - module.exports.waterStatus(waterStatus) + await module.exports.NextEvent(waterNextEvent) + await module.exports.waterStatus(waterStatus) + }, + piHolePage: async (domainsBeingBlocked, queriesToday, queriesBlockedToday, percentageBlocked) => { + lcd.printLineSync(2, 'Queries=' + commaNumber(queriesToday)) + lcd.printLineSync(3, 'Blocked=' + commaNumber(queriesBlockedToday) + ' (' + percentageBlocked.toFixed() + '%)') } } \ No newline at end of file diff --git a/modules/heating.js b/modules/heating.js index fb77cde..6139003 100644 --- a/modules/heating.js +++ b/modules/heating.js @@ -6,15 +6,16 @@ const lcd = require('../libs/lcd') module.exports = { - getStatus: () => { + getStatus: (page) => { var rest_options = { host: '192.168.4.5', port: 2020, path: '/heating/status', method: 'GET' }; - console.log('heating request') - var request = http.request(rest_options, function (response) { + let t = new Date().toUTCString() + console.log(t + ' heating request') + request = http.request(rest_options, function (response) { var content = ""; // Handle data chunks @@ -29,33 +30,34 @@ module.exports = { var time = await common.nextEvent(data.nextScheduleEventUtcTime) - globalVars.waterNextEvent = time + globalVars.heatingNextEvent = time let m = await common.time(data.nextScheduleEventUtcTime) if (globalVars.heatingOn === "" || globalVars.heatingOn === "error") { if (heatingOn === 'true') { globalVars.heatingOn = heatingOn - lcd.heatingPageOne('On', data.measuredRoomTemp, data.lastTimerSetPoint, globalVars.waterNextEvent) + lcd.heatingPageOne('On', data.measuredRoomTemp, data.lastTimerSetPoint, globalVars.heatingNextEvent) led.set('red') } else { globalVars.heatingOn = heatingOn - lcd.heatingPageOne('Off', data.measuredRoomTemp, data.lastTimerSetPoint, globalVars.waterNextEvent) + lcd.heatingPageOne('Off', data.measuredRoomTemp, data.lastTimerSetPoint, globalVars.heatingNextEvent) led.set('blue') } } else { - // if (waterOn != globalVars.waterOn) { if (heatingOn === 'true') { globalVars.heatingOn = heatingOn - lcd.heatingPageOne('On', data.measuredRoomTemp, data.lastTimerSetPoint, globalVars.waterNextEvent) + lcd.heatingPageOne('On', data.measuredRoomTemp, data.lastTimerSetPoint, globalVars.heatingNextEvent) led.set('red') } else { + if (page === 1) { + await lcd.heatingPageOne('Off', globalVars.heatingNextEvent) + } else { + await lcd.heatingPageTwo(data.measuredRoomTemp, data.lastTimerSetPoint) + } globalVars.heatingOn = heatingOn - // lcd.heatingPageOne('Off', data.measuredRoomTemp, data.lastTimerSetPoint, globalVars.waterNextEvent) - lcd.heatingPageTwo(data.measuredRoomTemp, data.lastTimerSetPoint) led.set('blue') } - // } } }); }); diff --git a/modules/mainMenu.js b/modules/mainMenu.js index d561afd..66fe1d5 100644 --- a/modules/mainMenu.js +++ b/modules/mainMenu.js @@ -8,31 +8,51 @@ var requireDir = require('require-dir'); var modules = requireDir('../modules'); module.exports = { - home: () => { + home: async () => { clearInterval(globalVars.waterPolling); - screen.clearScreen() - screen.heading('Main Menu') - screen.time() - setInterval(screen.time, 55000) + clearInterval(globalVars.heatingPolling) + clearInterval(globalVars.piHolePolling) + await screen.clearScreen() + await screen.heading('Main Menu') + await screen.clearLine(2) + await screen.clearLine(3) + await screen.clearLine(4) + await screen.time() }, - water: () => { - screen.clearScreen() - screen.heading('Hot Water') - screen.time() - setInterval(screen.time, 55000) - modules.water.getStatus() + water: async () => { + clearInterval(globalVars.waterPolling); + clearInterval(globalVars.heatingPolling) + clearInterval(globalVars.piHolePolling) + await screen.clearScreen() + await screen.heading('Hot Water') + await screen.time() + await modules.water.getStatus() globalVars.waterPolling = setInterval(() => { modules.water.getStatus() }, 60000); }, - heating: () => { - screen.clearScreen() - screen.heading('Heating') - screen.time() - setInterval(screen.time, 55000) - modules.heating.getStatus() - globalVars.heatingPolling = setInterval(() => { - modules.heating.getStatus() + heating: async () => { + clearInterval(globalVars.waterPolling); + clearInterval(globalVars.heatingPolling) + clearInterval(globalVars.piHolePolling) + await screen.clearScreen() + await screen.heading('Heating') + await screen.time() + await modules.heating.getStatus(globalVars.heatingPageS) + globalVars.heatingPolling = setInterval(async () => { + await modules.heating.getStatus(globalVars.heatingPageS) }, 60000); + }, + piHole: async () => { + clearInterval(globalVars.waterPolling); + clearInterval(globalVars.heatingPolling) + clearInterval(globalVars.piHolePolling) + await screen.clearScreen() + await screen.heading('PiHole') + await screen.time() + await modules.pihole.getStatus() + globalVars.piHolePolling = setInterval(() => { + modules.pihole.getStatus() + }, 30000); } } \ No newline at end of file diff --git a/modules/pihole.js b/modules/pihole.js new file mode 100644 index 0000000..5aaf17a --- /dev/null +++ b/modules/pihole.js @@ -0,0 +1,46 @@ +const http = require('http') +const globalVars = require('../libs/globalVars') +const led = require('../libs/led') +const common = require('../libs/common') +const lcd = require('../libs/lcd') + +module.exports = { + + getStatus: () => { + var rest_options = { + host: '192.168.4.5', + port: 80, + path: '/admin/api.php', + method: 'GET' + }; + let t = new Date().toUTCString() + console.log(t + ' piHole request') + var request = http.request(rest_options, function (response) { + var content = ""; + + // Handle data chunks + response.on('data', function (chunk) { + content += chunk; + }); + + // Once we're done streaming the response, parse it as json. + response.on('end', async function () { + var data = JSON.parse(content); + let domainsBeingBlocked = data.domains_being_blocked + let queriesToday = data.dns_queries_today + let queriesBlockedToday = data.ads_blocked_today + let percentageBlocked = data.ads_percentage_today + + lcd.piHolePage(domainsBeingBlocked, queriesToday, queriesBlockedToday, percentageBlocked) + + }); + }) + // Report errors + request.on('error', function (error) { + led.set('green') + lcd.heatingStatus('Error No Data') + globalVars.heatingOn = 'error' + }); + request.end(); + } +} \ No newline at end of file diff --git a/modules/water.js b/modules/water.js index cf44f3b..0f0ae63 100644 --- a/modules/water.js +++ b/modules/water.js @@ -13,7 +13,8 @@ module.exports = { path: '/water/status', method: 'GET' }; - console.log('water request') + let t = new Date().toUTCString() + console.log(t + ' water request') var request = http.request(rest_options, function (response) { var content = ""; diff --git a/package-lock.json b/package-lock.json index dfa2bfb..70a5b7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -206,6 +206,11 @@ "delayed-stream": "~1.0.0" } }, + "comma-number": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/comma-number/-/comma-number-2.0.1.tgz", + "integrity": "sha512-hrxY6UjA+tSUV5uZS2iOF8+/q7AACiq/zc9R6SO61MmOhrzNC0qXXh7g/jNYTm09fp6T40vQg15zkCmTJVA8Ww==" + }, "component-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", diff --git a/package.json b/package.json index 5562529..44433f7 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "author": "", "license": "ISC", "dependencies": { + "comma-number": "^2.0.1", "fs": "0.0.1-security", "got": "^11.6.2", "homeassistant": "^0.2.0",