This commit is contained in:
Karl Hudgell 2020-10-10 13:56:55 +01:00
parent 3871bf76db
commit 26893aef7a
20 changed files with 337 additions and 48 deletions

3
.gitignore vendored
View File

@ -1 +1,4 @@
node_modules
logs/
logger.lock
package-lock.json

29
app.js
View File

@ -5,6 +5,15 @@ const globalVars = require('./libs/globalVars')
const led = require('./libs/led')
const lcd = require('./libs/lcd')
const menu = require('./modules/mainMenu')
const logger = require('perfect-logger');
logger.initialize('houseStatus', {
logLevelFile: 0, // Log level for file
logLevelConsole: 0, // Log level for STDOUT/STDERR
logDirectory: 'logs/', // Log directory
// customBannerHeaders: 'This is a custom banner' // Custom Log Banner
});
async function main() {
lcd.clearScreen()
@ -16,12 +25,12 @@ async function main() {
functionSwitch.watch(async (err, value) => {
if (err) {
console.log('Error', err);
logger.info('Error', err);
}
if (value === 1) {
switch (globalVars.currentPage) {
case 'water':
console.log('Water Switch')
logger.info('Water Switch')
if (globalVars.waterOn === 'true') {
globalVars.lastWaterRequest = ""
await common.request(0)
@ -50,12 +59,12 @@ async function main() {
}
})
const arr = ['water', 'heating', 'pihole', 'mainMenu']
const arr = ['hassOcto', 'water', 'heating', 'pihole', 'capitalXtra', 'mainMenu']
arrLength = arr.length
let i = 0
appSwitch.watch(async (err, value) => {
if (err) {
console.log('Error', err);
logger.info('Error', err);
}
if (value === 1) {
switch (arr[i]) {
@ -78,10 +87,20 @@ async function main() {
led.set('off')
await menu.piHole()
break;
case 'capitalXtra':
globalVars.currentPage = arr[i]
led.set('off')
await menu.capitalXtra()
break;
case 'hassOcto':
globalVars.currentPage = arr[i]
led.set('off')
await menu.hassOcto()
break;
default:
break;
}
console.log(arr[i])
logger.info(arr[i])
i = i + 1
if (i === arrLength) {
i = 0

View File

@ -1,3 +1,5 @@
const logger = require('perfect-logger');
module.exports = {
time: () => {
try {
@ -6,7 +8,7 @@ module.exports = {
("0" + time.getMinutes()).slice(-2)
return currentTime
} catch (error) {
console.log(error)
logger.info(error)
}
}
}

View File

@ -1,7 +1,7 @@
const got = require('got');
const moment = require('moment');
const globalVars = require('./globalVars')
const logger = require('perfect-logger');
module.exports = {
request: async (input) => {
@ -49,6 +49,8 @@ module.exports = {
await clearInterval(globalVars.heatingPolling)
await clearInterval(globalVars.piHolePolling)
await clearInterval(globalVars.weatherPolling)
await clearInterval(globalVars.capitalXtraPolling)
await clearInterval(globalVars.hassOctoPolling)
},
clearGlobalVars: async () => {
globalVars.lastHeatingRequest = ""

View File

@ -8,10 +8,12 @@ class globalVariables {
heatingPageSwitch = "";
heatingPageS = 1;
piHolePolling = "";
lastWeatherRequest = ""
lastWaterRequest = ""
lastHeatingRequest = ""
weatherPolling = ""
lastWeatherRequest = "";
lastWaterRequest = "";
lastHeatingRequest = "";
weatherPolling = "";
capitalXtraPolling = "";
hassOctoPolling = "";
}
module.exports = new globalVariables();

View File

@ -3,6 +3,8 @@ const common = require('./common')
const globalVars = require('./globalVars')
const clock = require('./clock');
var commaNumber = require('comma-number')
const logger = require('perfect-logger');
const lcd = new LCD(1, 0x27, 20, 4);
@ -31,7 +33,7 @@ module.exports = {
},
time: async () => {
let t = new Date().toUTCString()
console.log(t + ' get time')
logger.info('get time')
lcd.setCursorSync(15, 0);
lcd.printSync(await clock.time())
},
@ -94,6 +96,8 @@ module.exports = {
lcd.printLineSync(3, 'Blocked=' + commaNumber(queriesBlockedToday) + ' (' + percentageBlocked.toFixed() + '%)')
},
weather: async (city, weatherDescription, currentTemp, highTemp, lowTemp) => {
module.exports.clearLine(3)
module.exports.clearLine(4)
weatherDescription = weatherDescription.replace(/(^\w{1})|(\s{1}\w{1})/g, match => match.toUpperCase());
if (currentTemp.toString().length == 2) {
lcd.printLineSync(1, ' ' + currentTemp + '\xDF')
@ -103,5 +107,14 @@ module.exports = {
lcd.printLineSync(2, weatherDescription)
lcd.printLineSync(3, 'High-' + highTemp + '\xDF' + ' / ' + 'Low-' + lowTemp + '\xDF')
}
},
capitalXtra: async (capitalXtraData) => {
lcd.printLineSync(2, capitalXtraData.currentlyPlaying.artist)
lcd.printLineSync(3, capitalXtraData.currentlyPlaying.song)
},
hassOcto: async (octoData) => {
lcd.printLineSync(1, 'State=' + octoData.currentState)
lcd.printLineSync(2, 'Progress=' + octoData.jobPercentage)
lcd.printLineSync(3, 'Remaining=' + octoData.timeRemaining)
},
}

51
modules/capitalXtra.js Normal file
View File

@ -0,0 +1,51 @@
const globalVars = require('../libs/globalVars')
const led = require('../libs/led')
const common = require('../libs/common')
const lcd = require('../libs/lcd')
const logger = require('perfect-logger');
const https = require('https')
const wrapKey = 'UBAJvtJksjWnJDQh3KUySmPjDUaZOCLO'
module.exports = {
getStatus: () => {
var rest_options = {
host: 'wrapapi.com',
port: 443,
path: '/use/karl0ss/statusscreen/capitalXtraReloadedPlaying/0.0.1?wrapAPIKey=' + wrapKey,
method: 'GET'
};
logger.info('capital request')
var request = https.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 capitalXtraData = {
"currentlyPlaying": {
"artist": data.data.nowPlaying[0].artist,
"song": data.data.nowPlaying[0].song
},
"lastplayed": data.data.LastPlayed,
}
lcd.capitalXtra(capitalXtraData)
});
})
// Report errors
request.on('error', function (error) {
console.log(error)
led.set('green')
lcd.heatingStatus('Error No Data')
globalVars.heatingOn = 'error'
});
request.end();
}
}

28
modules/hassOcto.js Normal file
View File

@ -0,0 +1,28 @@
const HomeAssistant = require('homeassistant');
const hass = new HomeAssistant({
host: 'http://192.168.4.5',
port: 8123,
token: process.env.homeAssistantKey,
ignoreCert: false
});
const lcd = require('../libs/lcd')
const logger = require('perfect-logger');
module.exports = {
getStatus: async () => {
logger.info('Printer Request request')
let jobPercentage = await hass.states.get('sensor', 'octoprint_job_percentage')
let timeRemaining = await hass.states.get('sensor', 'octoprint_time_remaining')
let currentState = await hass.states.get('sensor', 'octoprint_current_state')
let octoData = {
"currentState": currentState.state,
"jobPercentage": jobPercentage.state + jobPercentage.attributes.unit_of_measurement,
"timeRemaining": new Date(timeRemaining.state * 1000).toISOString().substr(11, 8),
}
lcd.hassOcto(octoData)
}
}

View File

@ -3,6 +3,7 @@ const globalVars = require('../libs/globalVars')
const led = require('../libs/led')
const common = require('../libs/common')
const lcd = require('../libs/lcd')
const logger = require('perfect-logger');
module.exports = {
@ -13,8 +14,7 @@ module.exports = {
path: '/heating/status',
method: 'GET'
};
let t = new Date().toUTCString()
console.log(t + ' heating request')
logger.info('heating request')
request = http.request(rest_options, function (response) {
var content = "";

View File

@ -21,6 +21,7 @@ module.exports = {
globalVars.weatherPolling = setInterval(() => {
modules.weather.getStatus()
}, 1800000);
// 1800000
},
water: async () => {
common.clearPolling()
@ -55,4 +56,26 @@ module.exports = {
modules.pihole.getStatus()
}, 30000);
},
capitalXtra: async () => {
common.clearPolling()
common.clearGlobalVars()
await screen.clearScreen()
await screen.heading('Capital Xtra')
await screen.time()
await modules.capitalXtra.getStatus()
globalVars.capitalXtraPolling = setInterval(() => {
modules.capitalXtra.getStatus()
}, 180000);
},
hassOcto: async () => {
common.clearPolling()
common.clearGlobalVars()
await screen.clearScreen()
await screen.heading('3d Printer')
await screen.time()
await modules.hassOcto.getStatus()
globalVars.hassOctoPolling = setInterval(() => {
modules.hassOcto.getStatus()
}, 30000);
}
}

View File

@ -3,6 +3,8 @@ const globalVars = require('../libs/globalVars')
const led = require('../libs/led')
const common = require('../libs/common')
const lcd = require('../libs/lcd')
const logger = require('perfect-logger');
module.exports = {
@ -13,8 +15,7 @@ module.exports = {
path: '/admin/api.php',
method: 'GET'
};
let t = new Date().toUTCString()
console.log(t + ' piHole request')
logger.info('piHole request')
var request = http.request(rest_options, function (response) {
var content = "";
@ -26,12 +27,14 @@ module.exports = {
// 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
let piHoleData = {
"domainsBeingBlocked": data.domains_being_blocked,
"queriesToday": data.dns_queries_today,
"queriesBlockedToday": data.ads_blocked_today,
"percentageBlocked": data.ads_percentage_today
}
lcd.piHolePage(domainsBeingBlocked, queriesToday, queriesBlockedToday, percentageBlocked)
lcd.piHolePage(piHoleData.domainsBeingBlocked, piHoleData.queriesToday, piHoleData.queriesBlockedToday, piHoleData.percentageBlocked)
});
})

View File

@ -3,6 +3,8 @@ const globalVars = require('../libs/globalVars')
const led = require('../libs/led')
const common = require('../libs/common')
const lcd = require('../libs/lcd')
const logger = require('perfect-logger');
module.exports = {
@ -13,8 +15,7 @@ module.exports = {
path: '/water/status',
method: 'GET'
};
let t = new Date().toUTCString()
console.log(t + ' water request')
logger.info('water request')
var request = http.request(rest_options, function (response) {
var content = "";
@ -58,11 +59,11 @@ module.exports = {
}
if (globalVars.lastWaterRequest === "") {
console.log('initial load')
logger.info('initial load')
globalVars.lastWaterRequest = waterdata
updateWater()
} else if (globalVars.lastWaterRequest = waterdata) {
console.log('no update')
} else if (JSON.stringify(globalVars.lastWaterRequest) == JSON.stringify(waterdata)) {
logger.info('no update')
} else {
updateWater()
}

View File

@ -3,6 +3,8 @@ const globalVars = require('../libs/globalVars')
const led = require('../libs/led')
const common = require('../libs/common')
const lcd = require('../libs/lcd')
const logger = require('perfect-logger');
const city = "Basingstoke"
const appid = "ba24c6018ddd72041749018d0c1b1ef8"
@ -16,8 +18,7 @@ module.exports = {
path: '/data/2.5/weather?q=' + city + '&appid=' + appid + '&units=metric',
method: 'GET'
};
let t = new Date().toUTCString()
console.log(t + ' weather request')
logger.info('weather request')
var request = http.request(rest_options, function (response) {
var content = "";
@ -37,16 +38,16 @@ module.exports = {
"lowTemp": Math.floor(data.main.temp_min)
}
async function updateWeather() {
console.log('weather updated')
logger.info('weather updated')
globalVars.lastWeatherRequest = weatherData
await lcd.weather(weatherData.city, weatherData.weatherDescription, weatherData.currentTemp, weatherData.highTemp, weatherData.lowTemp)
}
if (globalVars.lastWeatherRequest === "") {
console.log('initial load')
logger.info('initial load')
globalVars.lastWeatherRequest = weatherData
updateWeather()
} else if (globalVars.lastWeatherRequest = weatherData) {
console.log('no update')
} else if (JSON.stringify(globalVars.lastWeatherRequest) == JSON.stringify(weatherData)) {
logger.info('no update')
} else {
updateWeather()
}

5
package-lock.json generated
View File

@ -679,6 +679,11 @@
"better-assert": "~1.0.0"
}
},
"perfect-logger": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/perfect-logger/-/perfect-logger-2.0.1.tgz",
"integrity": "sha512-MGjZ4KcKFJ0w2LOvO2kSILZMU2KUOESaIJnI4sJ6qAumEmrRHiJVPx088WgAYnZMnys6gFI2ZP2YbNTL308xkA=="
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",

View File

@ -1,5 +1,5 @@
{
"name": "test_1",
"name": "house_status",
"version": "1.0.0",
"description": "",
"main": "index.js",
@ -16,6 +16,7 @@
"http": "0.0.1-security",
"moment": "^2.28.0",
"onoff": "^6.0.0",
"perfect-logger": "^2.0.1",
"pigpio": "^3.2.3",
"raspberrypi-liquid-crystal": "^1.15.0",
"readline": "^1.3.0",

View File

@ -2,10 +2,43 @@ const LCD = require('raspberrypi-liquid-crystal');
const lcd = new LCD(1, 0x27, 20, 4);
lcd.beginSync();
lcd.beginSync();
lcd.clearSync();
lcd.printLineSync(0, 'Welcome to KWorld');
lcd.printLineSync(1, ' then');
lcd.printLineSync(2, 'This is line 3');
lcd.printLineSync(3, 'This is line 4');
async function main(input) {
function sleep(millis) {
return new Promise(resolve => setTimeout(resolve, millis));
}
lcd.clearSync();
lcd.printLineSync(0, input)
await sleep(500);
lcd.scrollDisplayRightSync()
await sleep(500);
lcd.scrollDisplayRightSync()
await sleep(500);
lcd.scrollDisplayRightSync()
await sleep(500);
lcd.scrollDisplayRightSync()
await sleep(500);
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.scrollDisplayRightSync()
lcd.printLine(0, ' ')
}
async function runner() {
await main('karl')
await main('karl2')
}
runner()
// lcd.scrollDisplayLeftSync(3)

99
samples/rgb.html Normal file
View File

@ -0,0 +1,99 @@
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<style>
.slider {
-webkit-appearance: none;
width: 100%;
height: 15px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {opacity: 1;}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background: #4CAF50;
cursor: pointer;
}
#redSlider::-webkit-slider-thumb {background: red;}
#redSlider::-moz-range-thumb {background: red;}
#greenSlider::-webkit-slider-thumb {background: green;}
#greenSlider::-moz-range-thumb {background: green;}
#blueSlider::-webkit-slider-thumb {background: blue;}
#blueSlider::-moz-range-thumb {background: blue;}
</style>
<body>
<div class="w3-container">
<h1>RGB Color</h1>
<div class="w3-cell-row">
<div class="w3-container w3-cell w3-mobile">
<p><input type="range" min="0" max="255" value="0" class="slider" id="redSlider"></p>
<p><input type="range" min="0" max="255" value="0" class="slider" id="greenSlider"></p>
<p><input type="range" min="0" max="255" value="0" class="slider" id="blueSlider"></p>
</div>
<div class="w3-container w3-cell w3-mobile" style="background-color:black" id="colorShow">
<div></div>
</div>
</div>
<p>Or pick a color: <input type="color" id="pickColor"></p>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script src="https://www.w3schools.com/lib/w3color.js"></script>
<script>
var socket = io(); //load socket.io-client and connect to the host that serves the page
var rgb = w3color("rgb(0,0,0)"); //we use the w3color.js library to keep the color as an object
window.addEventListener("load", function(){ //when page loads
var rSlider = document.getElementById("redSlider");
var gSlider = document.getElementById("greenSlider");
var bSlider = document.getElementById("blueSlider");
var picker = document.getElementById("pickColor");
rSlider.addEventListener("change", function() { //add event listener for when red slider changes
rgb.red = this.value; //update the RED color according to the slider
colorShow.style.backgroundColor = rgb.toRgbString(); //update the "Current color"
socket.emit("rgbLed", rgb); //send the updated color to RGB LED via WebSocket
});
gSlider.addEventListener("change", function() { //add event listener for when green slider changes
rgb.green = this.value; //update the GREEN color according to the slider
colorShow.style.backgroundColor = rgb.toRgbString(); //update the "Current color"
socket.emit("rgbLed", rgb); //send the updated color to RGB LED via WebSocket
});
bSlider.addEventListener("change", function() { //add event listener for when blue slider changes
rgb.blue = this.value; //update the BLUE color according to the slider
colorShow.style.backgroundColor = rgb.toRgbString(); //update the "Current color"
socket.emit("rgbLed", rgb); //send the updated color to RGB LED via WebSocket
});
picker.addEventListener("input", function() { //add event listener for when colorpicker changes
rgb.red = w3color(this.value).red; //Update the RED color according to the picker
rgb.green = w3color(this.value).green; //Update the GREEN color according to the picker
rgb.blue = w3color(this.value).blue; //Update the BLUE color according to the picker
colorShow.style.backgroundColor = rgb.toRgbString(); //update the "Current color"
rSlider.value = rgb.red; //Update the RED slider position according to the picker
gSlider.value = rgb.green; //Update the GREEN slider position according to the picker
bSlider.value = rgb.blue; //Update the BLUE slider position according to the picker
socket.emit("rgbLed", rgb); //send the updated color to RGB LED via WebSocket
});
});
</script>
</body>
</html>

View File

@ -30,7 +30,7 @@ function handler (req, res) { //what to do on requests to port 8080
io.sockets.on('connection', function (socket) {// Web Socket Connection
socket.on('rgbLed', function(data) { //get light switch status from client
console.log(data); //output data from WebSocket connection to console
logger.info(data); //output data from WebSocket connection to console
//for common cathode RGB LED 0 is fully off, and 255 is fully on
redRGB=parseInt(data.red);

4
t.js
View File

@ -1,5 +1,5 @@
// repeat with the interval of 2 seconds
let timerId = setInterval(() => console.log('tick'), 2000);
let timerId = setInterval(() => logger.info('tick'), 2000);
// after 5 seconds stop
setTimeout(() => { clearInterval(timerId); console.log('stop'); }, 5000);
setTimeout(() => { clearInterval(timerId); logger.info('stop'); }, 5000);

13
test.js
View File

@ -2,14 +2,17 @@ const HomeAssistant = require('homeassistant');
const hass = new HomeAssistant({
host: 'http://192.168.4.5',
port: 8123,
token: process.env.homeAssistantKey,
// token: process.env.homeAssistantKey,
token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxNjgyODUxMWI4Nzc0YTAwYTA0ZGRmYzgyZWIzODRlZiIsImlhdCI6MTYwMDEwNjMxOSwiZXhwIjoxOTE1NDY2MzE5fQ.18uSUFbLMJnlQBuhUO6uXL25fZ7jBzyU3i5qiOCgnuc",
ignoreCert: false
});
async function main() {
console.log(process.env.homeAssistantKey)
t = await hass.states.get('switch', 'migenie_water_switch')
console.log(t)
let jobPercentage = await hass.states.get('sensor', 'octoprint_job_percentage')
let timeRemaining = await hass.states.get('sensor', 'octoprint_time_remaining')
let percent = jobPercentage.state + jobPercentage.attributes.unit_of_measurement
console.log(percent)
console.log(new Date(timeRemaining.state * 1000).toISOString().substr(11, 8) )
}
main()