1
0

Compare commits

..

9 Commits

Author SHA1 Message Date
xadammr 7d0272606a Update Dockerfile to better pull from git 2024-08-14 19:45:34 +10:00
xadammr 64491b9cb0 Update version and author of client 2024-08-14 19:31:14 +10:00
xadammr 3ee620db01 update client dist 2024-08-14 19:31:03 +10:00
xadammr 78bbe26fa8 scaffolding for a timestamp 2024-08-14 19:30:42 +10:00
xadammr ad25774ef9 Migrate to ReactDOM 2024-08-14 19:29:48 +10:00
xadammr b32b18adc6 Update graph colours 2024-08-14 19:29:32 +10:00
xadammr a6a1fe0a76 Update Author and Version 2024-08-14 18:17:29 +10:00
xadammr a38e757e82 Change graph colours for temperature 2024-08-14 18:17:04 +10:00
xadammr 77b69e9fc8 Update defaults 2024-08-14 18:16:49 +10:00
14 changed files with 12440 additions and 5883 deletions
+6 -4
View File
@@ -1,12 +1,14 @@
FROM alpine/git:latest
WORKDIR /clone-workspace
RUN git clone https://git.spd.ltd/xadammr/pi-weather-station.git
FROM node:18-alpine FROM node:18-alpine
RUN apk add git
RUN mkdir /home/node/app RUN mkdir /home/node/app
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app COPY --from=0 /clone-workspace/pi-weather-station /home/node/app/pi-weather-station
RUN rm -rf *
RUN git clone https://git.spd.ltd/xadammr/pi-weather-station.git WORKDIR /home/node/app
RUN chown -R node:node . RUN chown -R node:node .
WORKDIR /home/node/app/pi-weather-station WORKDIR /home/node/app/pi-weather-station
+1
View File
@@ -0,0 +1 @@
(self.webpackChunkpi_weather_station_client=self.webpackChunkpi_weather_station_client||[]).push([[810],{1249:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var i=n(6314),s=n.n(i)()(!1);s.push([e.id,"body {\n font-family: Rubik; \n margin: 0px; \n }",""]);const a=s},6810:(e,t,n)=>{var i=n(5072),s=n(1249);"string"==typeof(s=s.__esModule?s.default:s)&&(s=[[e.id,s,""]]);i(s,{insert:"head",singleton:!1}),e.exports=s.locals||{}}}]);
+5307 -316
View File
File diff suppressed because one or more lines are too long
+54
View File
@@ -0,0 +1,54 @@
/* @preserve
* Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com
* (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade
*/
/*!
* Chart.js v2.9.4
* https://www.chartjs.org
* (c) 2020 Chart.js Contributors
* Released under the MIT License
*/
/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
//! moment.js
//! moment.js locale configuration
+23 -1
View File
@@ -1 +1,23 @@
<!doctype html><html lang="en"><head><link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/><script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script><link href="https://fonts.googleapis.com/css2?family=Rubik:wght@300&display=swap" rel="stylesheet"><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Pi Weather Station</title></head><body><div id="root"></div><script src="/bundle.min.js"></script></body></html> <!DOCTYPE html>
<html lang="en">
<head>
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossorigin=""
/>
<script
src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
crossorigin=""
></script>
<link href="https://fonts.googleapis.com/css2?family=Rubik:wght@300&display=swap" rel="stylesheet">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Pi Weather Station</title>
</head>
<body>
<div id="root"></div>
<script src="/bundle.min.js"></script></body>
</html>
@@ -0,0 +1,32 @@
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(self["webpackChunkpi_weather_station_client"] = self["webpackChunkpi_weather_station_client"] || []).push([["node_modules_style-loader_dist_cjs_js_node_modules_css-loader_dist_cjs_js_src_styles_main_css"],{
/***/ "./node_modules/css-loader/dist/cjs.js!./src/styles/main.css":
/*!*******************************************************************!*\
!*** ./node_modules/css-loader/dist/cjs.js!./src/styles/main.css ***!
\*******************************************************************/
/***/ ((module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);\n// Imports\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(false);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"body {\\n font-family: Rubik; \\n margin: 0px; \\n }\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://pi-weather-station-client/./src/styles/main.css?./node_modules/css-loader/dist/cjs.js");
/***/ }),
/***/ "./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./src/styles/main.css":
/*!***********************************************************************************************************!*\
!*** ./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./src/styles/main.css ***!
\***********************************************************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
eval("var api = __webpack_require__(/*! !../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n var content = __webpack_require__(/*! !!../../node_modules/css-loader/dist/cjs.js!./main.css */ \"./node_modules/css-loader/dist/cjs.js!./src/styles/main.css\");\n\n content = content.__esModule ? content.default : content;\n\n if (typeof content === 'string') {\n content = [[module.id, content, '']];\n }\n\nvar options = {};\n\noptions.insert = \"head\";\noptions.singleton = false;\n\nvar update = api(content, options);\n\n\n\nmodule.exports = content.locals || {};\n\n//# sourceURL=webpack://pi-weather-station-client/./src/styles/main.css?./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js");
/***/ })
}]);
+6971 -5526
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -1,14 +1,14 @@
{ {
"name": "pi-weather-station-client", "name": "pi-weather-station-client",
"version": "1.0.0", "version": "2.1",
"description": "Client for pi-weather-station", "description": "Client for pi-weather-station",
"main": "webpack.config.js", "main": "webpack.config.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --progress --watch --mode development", "dev": "webpack --progress --watch --mode development",
"prod": "webpack -p --env.BUILD_PRODUCTION=1" "prod": "webpack --mode production --env BUILD_PRODUCTION=1"
}, },
"author": "Eric Lewin", "author": "Adam Roe",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/core": "^7.11.1", "@babel/core": "^7.11.1",
@@ -24,7 +24,7 @@
"@iconify/icons-wi": "^1.0.3", "@iconify/icons-wi": "^1.0.3",
"@iconify/react": "^1.1.3", "@iconify/react": "^1.1.3",
"autoprefixer": "^9.8.6", "autoprefixer": "^9.8.6",
"axios": "^0.19.2", "axios": "^1.7.4",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
"chart.js": "^2.9.3", "chart.js": "^2.9.3",
@@ -46,14 +46,14 @@
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.7.0", "postcss-preset-env": "^6.7.0",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"react": "^16.13.1", "react": "^18.1.0",
"react-dom": "^18.1.0",
"react-chartjs-2": "^2.10.0", "react-chartjs-2": "^2.10.0",
"react-dom": "^16.13.1",
"react-leaflet": "^2.7.0", "react-leaflet": "^2.7.0",
"react-transition-group": "^4.4.1", "react-transition-group": "^4.4.1",
"style-loader": "^1.2.1", "style-loader": "^1.2.1",
"url-loader": "^4.1.0", "url-loader": "^4.1.0",
"webpack": "^4.44.1", "webpack": "^5.93.0",
"webpack-cli": "^3.3.12" "webpack-cli": "^5.1.4"
} }
} }
+4 -4
View File
@@ -39,10 +39,10 @@ export function AppContextProvider({ children }) {
const [dailyWeatherDataErrMsg, setDailyWeatherDataErrMsg] = useState(null); const [dailyWeatherDataErrMsg, setDailyWeatherDataErrMsg] = useState(null);
const [panToCoords, setPanToCoords] = useState(null); const [panToCoords, setPanToCoords] = useState(null);
const [markerIsVisible, setMarkerIsVisible] = useState(true); const [markerIsVisible, setMarkerIsVisible] = useState(true);
const [tempUnit, setTempUnit] = useState("f"); // fahrenheit or celsius const [tempUnit, setTempUnit] = useState("c"); // fahrenheit or celsius
const [speedUnit, setSpeedUnit] = useState("mph"); // mph or ms for m/s const [speedUnit, setSpeedUnit] = useState("ms"); // mph or ms for m/s
const [lengthUnit, setLengthUnit] = useState("in"); // in or mm const [lengthUnit, setLengthUnit] = useState("mm"); // in or mm
const [clockTime, setClockTime] = useState("12"); // 12h or 24h time for clock const [clockTime, setClockTime] = useState("24"); // 12h or 24h time for clock
const [animateWeatherMap, setAnimateWeatherMap] = useState(false); const [animateWeatherMap, setAnimateWeatherMap] = useState(false);
const [settingsMenuOpen, setSettingsMenuOpen] = useState(false); const [settingsMenuOpen, setSettingsMenuOpen] = useState(false);
const [customLat, setCustomLat] = useState(null); const [customLat, setCustomLat] = useState(null);
+9 -2
View File
@@ -49,12 +49,14 @@ const WeatherMap = ({ zoom, dark }) => {
const [currentMapTimestampIdx, setCurrentMapTimestampIdx] = useState(0); const [currentMapTimestampIdx, setCurrentMapTimestampIdx] = useState(0);
const MAP_TIMESTAMP_REFRESH_FREQUENCY = 1000 * 60 * 10; //update every 10 minutes const MAP_TIMESTAMP_REFRESH_FREQUENCY = 1000 * 60 * 10; //update every 10 minutes
const MAP_CYCLE_RATE = 1000; //ms const MAP_CYCLE_RATE = 500; //ms
const getMapApiKeyCallback = useCallback(() => getMapApiKey(), [ const getMapApiKeyCallback = useCallback(() => getMapApiKey(), [
getMapApiKey, getMapApiKey,
]); ]);
//const delay = ms => new Promise(res => setTimeout(res, ms));
useEffect(() => { useEffect(() => {
getMapApiKeyCallback().catch((err) => { getMapApiKeyCallback().catch((err) => {
console.log("err!", err); console.log("err!", err);
@@ -101,16 +103,21 @@ const WeatherMap = ({ zoom, dark }) => {
useEffect(() => { useEffect(() => {
if (mapTimestamps) { if (mapTimestamps) {
if (animateWeatherMap) { if (animateWeatherMap) {
let cycleRate = MAP_CYCLE_RATE;
const interval = setInterval(() => { const interval = setInterval(() => {
let nextIdx; let nextIdx;
//let d = new Date(mapTimestamps[currentMapTimestampIdx]*1000);
//console.log(d.toTimeString());
if (currentMapTimestampIdx + 1 >= mapTimestamps.length) { if (currentMapTimestampIdx + 1 >= mapTimestamps.length) {
nextIdx = 0; nextIdx = 0;
cycleRate = 5000;
} else { } else {
nextIdx = currentMapTimestampIdx + 1; nextIdx = currentMapTimestampIdx + 1;
} }
setCurrentMapTimestampIdx(nextIdx); setCurrentMapTimestampIdx(nextIdx);
}, MAP_CYCLE_RATE); }, cycleRate);
return () => { return () => {
//console.log(cycleRate);
clearInterval(interval); clearInterval(interval);
}; };
} else { } else {
@@ -27,12 +27,11 @@ const createChartOptions = ({
stacked: false, stacked: false,
title: { title: {
display: true, display: true,
/*text: `5 Day ${ text: `5-Day ${
altMode altMode
? `Wind Speed / Precipitation (${lengthUnit})` ? `Wind / Rain (${lengthUnit})`
: `Temp / Precipitation` : `Temperature / Rain (%)`
}`,*/ }`,
text: "Five-Day Forecast",
fontColor: fontColor(darkMode), fontColor: fontColor(darkMode),
fontFamily: "Rubik, sans-serif", fontFamily: "Rubik, sans-serif",
}, },
@@ -88,6 +87,8 @@ const createChartOptions = ({
const chartColors = { const chartColors = {
blue: "rgba(63, 127, 191, 0.5)", blue: "rgba(63, 127, 191, 0.5)",
gray: "rgba(127, 127, 127, 0.5)", gray: "rgba(127, 127, 127, 0.5)",
orange: "rgba(226, 99, 71)",
white: "rgba(255, 255, 255)",
}; };
const mapChartData = ({ const mapChartData = ({
@@ -121,8 +122,8 @@ const mapChartData = ({
: convertTemp(temperature, tempUnit); : convertTemp(temperature, tempUnit);
}), }),
yAxisID: "y-axis-1", yAxisID: "y-axis-1",
borderColor: chartColors.gray, borderColor: altMode ? chartColors.gray : chartColors.orange,
backgroundColor: chartColors.gray, backgroundColor: altMode ? chartColors.gray : chartColors.orange,
fill: false, fill: false,
}, },
{ {
@@ -27,12 +27,11 @@ const chartOptions = ({
stacked: false, stacked: false,
title: { title: {
display: true, display: true,
/*text: `24 Hour ${ text: `24-Hour ${
altMode altMode
? `Wind Speed / Precipitation (${lengthUnit})` ? `Wind / Rain (${lengthUnit})`
: `Temp / Precipitation` : `Temperature / Rain (%)`
}`,*/ }`,
text: "24-hour Forecast",
fontColor: fontColor(darkMode), fontColor: fontColor(darkMode),
fontFamily: "Rubik, sans-serif", fontFamily: "Rubik, sans-serif",
}, },
@@ -88,6 +87,7 @@ const chartOptions = ({
const chartColors = { const chartColors = {
blue: "rgba(63, 127, 191, 0.5)", blue: "rgba(63, 127, 191, 0.5)",
gray: "rgba(127, 127, 127, 0.5)", gray: "rgba(127, 127, 127, 0.5)",
orange: "rgba(226, 99, 71)",
}; };
const mapChartData = ({ const mapChartData = ({
@@ -126,8 +126,8 @@ const mapChartData = ({
: convertTemp(temperature, tempUnit); : convertTemp(temperature, tempUnit);
}), }),
yAxisID: "y-axis-1", yAxisID: "y-axis-1",
borderColor: chartColors.gray, borderColor: altMode ? chartColors.gray : chartColors.orange,
backgroundColor: chartColors.gray, backgroundColor: altMode ? chartColors.gray : chartColors.orange,
fill: false, fill: false,
}, },
{ {
+8 -6
View File
@@ -1,12 +1,14 @@
import React from "react"; import React from 'react';
import ReactDOM from "react-dom";
import App from "~/components/App"; import App from "~/components/App";
import { AppContextProvider } from "~/AppContext"; import { AppContextProvider } from "~/AppContext";
import "~/styles"; import "~/styles";
ReactDOM.render( import { createRoot } from 'react-dom/client';
const container = document.getElementById('root');
const root = createRoot(container); // createRoot(container!) if you use TypeScript
root.render(
<AppContextProvider> <AppContextProvider>
<App /> <App />
</AppContextProvider>, </AppContextProvider>
document.getElementById("root")
); );
+2 -2
View File
@@ -1,13 +1,13 @@
{ {
"name": "pi-weather-station", "name": "pi-weather-station",
"version": "2.0.1", "version": "2.1",
"description": "A weather station designed for the Raspberry Pi 7 inch touchscreen", "description": "A weather station designed for the Raspberry Pi 7 inch touchscreen",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"start": "node ./server/index.js" "start": "node ./server/index.js"
}, },
"author": "Eric Lewin", "author": "Adam Roe",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"axios": "^0.19.2", "axios": "^0.19.2",