From f69001560f18b9866d7a4aedb3db784c76848c98 Mon Sep 17 00:00:00 2001
From: Claude
Date: Thu, 2 Jul 2026 00:45:58 +0000
Subject: [PATCH] Modernize code style and unify mobile/desktop frontend
Backend:
- Eliminate implicit globals (db, logger, moment, passport, etc.) across
the whole src tree in favor of explicit require()s per module
- Break the database.js/query-module circular dependency by introducing
database/connection.js as the single source for the raw mysql connection
- Replace var with const/let, == with ===, string concatenation with
template literals, and callback-style code with async/await where used
- Fix bugs surfaced by removing globals and modernizing: broken
express-validator v7 subpath imports, passport 0.7 req.logout() missing
callback, undefined `id` refs in log messages, an always-true array
comparison in the firmware update check, a dead `last_update` branch,
and a fire-before-await ordering bug in firmware update deletion
- Pin package.json dependencies (was entirely "latest") and drop unused
packages (async, bluebird, body-parser, debug, dotenv, morgan)
Frontend:
- Remove express-device and the server-side mobile/desktop template
split; delete views/mobile and unify each page into a single
responsive template
- Rewrite style.css as a small design-token based system (colors,
cards, nav, forms) applied via layout.pug so it cascades across
every page
- Redesign the home page as a responsive station card grid instead of
a fixed desktop table duplicated for mobile
Verified end-to-end against a real MySQL instance: schema init, admin
seed, login/logout, station CRUD, sensor ingestion, history/map/config
pages.
---
.env.example | 5 +-
src/app.js | 125 ++---
src/database/connection.js | 36 ++
src/database/database.js | 92 ++--
.../firmware_update/create_firmware_update.js | 10 +-
.../firmware_update/delete_firmware_update.js | 14 +-
.../get_all_firmware_updates.js | 15 +-
.../firmware_update/query_update_available.js | 13 +-
.../firmware_update/query_update_by_id.js | 16 +-
src/database/init_tables.js | 217 ++++----
src/database/station/config/create_station.js | 17 +-
src/database/station/config/delete_station.js | 14 +-
.../station/config/get_all_stations.js | 17 +-
src/database/station/config/modify_station.js | 14 +-
.../station/data_query/delete_data.js | 62 ++-
.../station/data_query/list_station.js | 14 +-
.../data_query/query_history_station_data.js | 69 ++-
.../query_last_data_from_all_station.js | 18 +-
.../query_single_station_last_data.js | 182 ++++---
.../station/data_query/update_station_data.js | 70 ++-
src/database/user/create_user.js | 13 +-
src/database/user/delete_user.js | 18 +-
src/database/user/get_all_users.js | 16 +-
src/database/user/get_user_by_id.js | 15 +-
src/database/user/login_user.js | 15 +-
src/database/user/modify_user.js | 16 +-
src/package.json | 41 +-
src/passport/init_passport.js | 30 +-
src/passport/is_admin.js | 7 +-
src/passport/is_auth.js | 5 +-
src/public/stylesheets/style.css | 479 +++++++++++++++++-
src/routes/api/firmware_update.js | 60 ++-
src/routes/api/station.js | 70 ++-
src/routes/api/update.js | 65 ++-
src/routes/web/config/configuration.js | 65 ++-
src/routes/web/config/delete_data.js | 61 +--
.../config/firmware_update/delete_update.js | 41 +-
.../web/config/firmware_update/new_update.js | 56 +-
.../web/config/station/delete_station.js | 21 +-
.../web/config/station/modify_station.js | 41 +-
src/routes/web/config/station/new_station.js | 43 +-
src/routes/web/history.js | 104 ++--
src/routes/web/index.js | 40 +-
src/routes/web/map.js | 36 +-
src/routes/web/station.js | 32 +-
src/routes/web/user/delete_user.js | 31 +-
src/routes/web/user/login.js | 41 +-
src/routes/web/user/logout.js | 14 +-
src/routes/web/user/modify_user.js | 63 +--
src/routes/web/user/new_user.js | 58 +--
src/utils/date_convert.js | 9 +-
src/utils/forecast.js | 142 +++---
src/utils/logger.js | 14 +-
src/utils/meteo_utils.js | 80 +--
src/utils/paths.js | 3 +
src/views/config/configuration.pug | 8 +-
src/views/history/chart.pug | 16 +-
src/views/history/history.pug | 57 ++-
src/views/history/table.pug | 4 +-
src/views/index.pug | 255 +++++-----
src/views/layout.pug | 134 +++--
src/views/login.pug | 28 +-
src/views/map.pug | 24 +-
src/views/mobile/history/m_chart.pug | 462 -----------------
src/views/mobile/history/m_history.pug | 74 ---
src/views/mobile/m_index.pug | 191 -------
src/views/mobile/m_layout.pug | 80 ---
src/views/mobile/m_login.pug | 19 -
src/views/mobile/m_map.pug | 47 --
src/views/station.pug | 3 +-
70 files changed, 1834 insertions(+), 2433 deletions(-)
create mode 100644 src/database/connection.js
create mode 100644 src/utils/paths.js
delete mode 100644 src/views/mobile/history/m_chart.pug
delete mode 100644 src/views/mobile/history/m_history.pug
delete mode 100644 src/views/mobile/m_index.pug
delete mode 100644 src/views/mobile/m_layout.pug
delete mode 100644 src/views/mobile/m_login.pug
delete mode 100644 src/views/mobile/m_map.pug
diff --git a/.env.example b/.env.example
index 3698f48..55d3e21 100644
--- a/.env.example
+++ b/.env.example
@@ -2,4 +2,7 @@
DB_NAME=database_name
USER_DB=database_user
PASS_DB=database_password
-MYSQL_ROOT_PASSWORD=random #only for production docker
\ No newline at end of file
+MYSQL_ROOT_PASSWORD=random #only for production docker
+
+#Mapbox access token used to render the station map (https://account.mapbox.com/access-tokens/)
+MAPBOX_TOKEN=your_mapbox_token
\ No newline at end of file
diff --git a/src/app.js b/src/app.js
index 1fe74e0..ee76d1d 100644
--- a/src/app.js
+++ b/src/app.js
@@ -1,38 +1,26 @@
-var createError = require("http-errors");
-var express = require("express");
-var path = require("path");
-var cookieParser = require("cookie-parser");
-var compression = require("compression");
-var cookieParser = require("cookie-parser");
-var flash = require("connect-flash");
-var helmet = require("helmet");
-var session = require("express-session");
-var device = require("express-device");
-var MySQLStore = require('express-mysql-session')(session);
-
-moment = require('moment')
-const { v4: uuidv4 } = require('uuid');
-crypto = require("crypto");
-async = require("async");
-WORKING_DIR = __dirname;
-
-
-logger = require("./utils/logger");
-meteoUtils = require('./utils/meteo_utils')
-dateConvert = require('./utils/date_convert')
-
-/*DATABASE MySQL*/
-db = require("./database/database");
+const createError = require("http-errors");
+const express = require("express");
+const path = require("path");
+const cookieParser = require("cookie-parser");
+const compression = require("compression");
+const flash = require("connect-flash");
+const helmet = require("helmet");
+const session = require("express-session");
+const MySQLStore = require("express-mysql-session")(session);
+
+const logger = require("./utils/logger");
+const database = require("./database/connection");
+
+/*DATABASE MySQL - required for its startup side effects (connect + init tables)*/
+require("./database/database");
/*PASSPORT*/
-passport = require("passport");
-var initPassport = require("./passport/init_passport");
-isAuthenticated = require("./passport/is_auth");
-isAdmin = require("./passport/is_admin");
+const passport = require("passport");
+const initPassport = require("./passport/init_passport");
initPassport();
/*Express*/
-var app = express();
+const app = express();
// view engine setup
app.set("views", path.join(__dirname, "views"));
@@ -41,13 +29,12 @@ app.set("view engine", "pug");
app.use(helmet());
app.use(compression());
-//app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
-var sessionStore = new MySQLStore({}, database);
+const sessionStore = new MySQLStore({}, database);
app.use(
session({
@@ -64,26 +51,25 @@ app.use(
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
-app.use(device.capture());
/*Web Routing*/
-var indexRouter = require("./routes/web/index");
-var history = require("./routes/web/history");
-var station = require("./routes/web/station");
-
-var map = require("./routes/web/map");
-var login = require("./routes/web/user/login");
-var logout = require("./routes/web/user/logout");
-var new_user = require("./routes/web/user/new_user");
-var modify_user = require("./routes/web/user/modify_user");
-var delete_user = require("./routes/web/user/delete_user");
-var configuration = require("./routes/web/config/configuration");
-var configuration_new_station = require("./routes/web/config/station/new_station");
-var configuration_delete_station = require("./routes/web/config/station/delete_station");
-var configuration_modify_station = require("./routes/web/config/station/modify_station");
-var configuration_delete_data = require("./routes/web/config/delete_data");
-var configuration_new_update = require("./routes/web/config/firmware_update/new_update");
-var configuration_delete_update = require("./routes/web/config/firmware_update/delete_update");
+const indexRouter = require("./routes/web/index");
+const history = require("./routes/web/history");
+const station = require("./routes/web/station");
+
+const map = require("./routes/web/map");
+const login = require("./routes/web/user/login");
+const logout = require("./routes/web/user/logout");
+const newUser = require("./routes/web/user/new_user");
+const modifyUser = require("./routes/web/user/modify_user");
+const deleteUser = require("./routes/web/user/delete_user");
+const configuration = require("./routes/web/config/configuration");
+const configurationNewStation = require("./routes/web/config/station/new_station");
+const configurationDeleteStation = require("./routes/web/config/station/delete_station");
+const configurationModifyStation = require("./routes/web/config/station/modify_station");
+const configurationDeleteData = require("./routes/web/config/delete_data");
+const configurationNewUpdate = require("./routes/web/config/firmware_update/new_update");
+const configurationDeleteUpdate = require("./routes/web/config/firmware_update/delete_update");
app.use("/", indexRouter);
app.use("/history", history);
@@ -92,43 +78,42 @@ app.use("/map", map);
app.use("/login", login);
app.use("/logout", logout);
-app.use("/user/new_user", new_user);
-app.use("/user/modify_user", modify_user);
-app.use("/user/delete_user", delete_user);
+app.use("/user/new_user", newUser);
+app.use("/user/modify_user", modifyUser);
+app.use("/user/delete_user", deleteUser);
app.use("/config/configuration", configuration);
-app.use("/config/station/new_station", configuration_new_station);
-app.use("/config/station/delete_station", configuration_delete_station);
-app.use("/config/station/modify_station", configuration_modify_station);
+app.use("/config/station/new_station", configurationNewStation);
+app.use("/config/station/delete_station", configurationDeleteStation);
+app.use("/config/station/modify_station", configurationModifyStation);
-app.use("/config/firmware_update/new_update", configuration_new_update);
-app.use("/config/firmware_update/delete_update", configuration_delete_update);
+app.use("/config/firmware_update/new_update", configurationNewUpdate);
+app.use("/config/firmware_update/delete_update", configurationDeleteUpdate);
-app.use("/config/delete_data", configuration_delete_data);
+app.use("/config/delete_data", configurationDeleteData);
/*API Routing*/
-var update = require("./routes/api/update");
-var api_station = require("./routes/api/station");
-var firmw_updater = require("./routes/api/firmware_update");
+const update = require("./routes/api/update");
+const apiStation = require("./routes/api/station");
+const firmwareUpdater = require("./routes/api/firmware_update");
//Data posting
app.use("/api/update", update);
-app.use("/api/station", api_station);
-app.use("/api/firmware_update", firmw_updater);
+app.use("/api/station", apiStation);
+app.use("/api/firmware_update", firmwareUpdater);
// catch 404 and forward to error handler
-app.use(function (req, res, next) {
+app.use((req, res, next) => {
next(createError(404));
});
// error handler
-app.use(function (err, req, res, next) {
- // set locals, only providing error in development
- logger.error("GENERIC ERROR: " + err.message)
+app.use((err, req, res, next) => {
+ logger.error(`GENERIC ERROR: ${err.message}`);
res.locals.message = err.message;
- process.exit(-1)
+ process.exit(1);
});
logger.info("APP: Starting completed. MeteoServer Ready.");
-app.listen(3000);
\ No newline at end of file
+app.listen(3000);
diff --git a/src/database/connection.js b/src/database/connection.js
new file mode 100644
index 0000000..5a367ca
--- /dev/null
+++ b/src/database/connection.js
@@ -0,0 +1,36 @@
+const mysql = require("mysql");
+const util = require("util");
+const logger = require("../utils/logger");
+
+if (!process.env.DB_HOST || !process.env.DB_NAME || !process.env.USER_DB || !process.env.PASS_DB) {
+ logger.error("ENV: Missing some environment variables.");
+ process.exit(1);
+}
+
+const database = mysql.createConnection({
+ host: process.env.DB_HOST,
+ database: process.env.DB_NAME,
+ user: process.env.USER_DB,
+ password: process.env.PASS_DB,
+ timezone: "utc"
+});
+
+database.connect((err) => {
+ if (err) {
+ logger.error("DATABASE: Can't connect to database. Check configuration.");
+ logger.error(err);
+ process.exit(1);
+ }
+});
+
+database.on("error", (err) => {
+ logger.error("DATABASE: Connection error, shutting down.");
+ logger.error(err);
+ process.exit(1);
+});
+
+logger.info(`DATABASE: Connected to SQL database ${process.env.DB_NAME} at ${process.env.DB_HOST}`);
+
+database.asynchQuery = util.promisify(database.query).bind(database);
+
+module.exports = database;
diff --git a/src/database/database.js b/src/database/database.js
index 63a3f02..be15573 100644
--- a/src/database/database.js
+++ b/src/database/database.js
@@ -1,73 +1,45 @@
-var express = require('express');
-
+const logger = require("../utils/logger");
+const database = require("./connection");
+const initTables = require("./init_tables");
//STATION DATA
-var queryLastDataFromAllStation = require('./station/data_query/query_last_data_from_all_station');
-var querySingleStationLastData = require('./station/data_query/query_single_station_last_data');
-var listStation = require('./station/data_query/list_station');
-var updateStationData = require('./station/data_query/update_station_data');
-var queryHistoryStationData = require('./station/data_query/query_history_station_data');
-var deleteData = require('./station/data_query/delete_data');
+const queryLastDataFromAllStation = require("./station/data_query/query_last_data_from_all_station");
+const querySingleStationLastData = require("./station/data_query/query_single_station_last_data");
+const listStation = require("./station/data_query/list_station");
+const updateStationData = require("./station/data_query/update_station_data");
+const queryHistoryStationData = require("./station/data_query/query_history_station_data");
+const deleteData = require("./station/data_query/delete_data");
//STATION
-var createStation = require('./station/config/create_station');
-var deleteStation = require('./station/config/delete_station');
-var getAllStations = require('./station/config/get_all_stations');
-var modifyStation = require('./station/config/modify_station');
+const createStation = require("./station/config/create_station");
+const deleteStation = require("./station/config/delete_station");
+const getAllStations = require("./station/config/get_all_stations");
+const modifyStation = require("./station/config/modify_station");
//USER
-var deleteUser = require('./user/delete_user');
-var loginUser = require('./user/login_user');
-var getUserById = require('./user/get_user_by_id');
-var createUser = require('./user/create_user');
-var modifyUser = require('./user/modify_user');
-var getAllUsers = require('./user/get_all_users');
+const deleteUser = require("./user/delete_user");
+const loginUser = require("./user/login_user");
+const getUserById = require("./user/get_user_by_id");
+const createUser = require("./user/create_user");
+const modifyUser = require("./user/modify_user");
+const getAllUsers = require("./user/get_all_users");
//FIRMWARE UPDATE
-var queryUpdateAvailable = require('./firmware_update/query_update_available');
-var createFirmwareUpdate = require('./firmware_update/create_firmware_update');
-var deleteFirmwareUpdate = require('./firmware_update/delete_firmware_update');
-var queryUpdateById = require('./firmware_update/query_update_by_id');
-var getAllFirmwareUpdates = require('./firmware_update/get_all_firmware_updates');
-
-
-var mysql = require("mysql");
-var util = require("util");
-
-if (process.env.DB_HOST == "" || process.env.DB_NAME == "" || process.env.USER_DB == "" || process.env.PASS_DB == "") {
- logger.error("ENV: Missing some enviroment variables.");
- process.exit();
-}
-
-
-database = mysql.createConnection({
- host: process.env.DB_HOST,
- database: process.env.DB_NAME,
- user: process.env.USER_DB,
- password: process.env.PASS_DB,
- timezone: 'utc'
-});
-
+const queryUpdateAvailable = require("./firmware_update/query_update_available");
+const createFirmwareUpdate = require("./firmware_update/create_firmware_update");
+const deleteFirmwareUpdate = require("./firmware_update/delete_firmware_update");
+const queryUpdateById = require("./firmware_update/query_update_by_id");
+const getAllFirmwareUpdates = require("./firmware_update/get_all_firmware_updates");
-database.connect(function (err) {
- if (err) {
- logger.error("DATABASE: Can't connect to database. Check configuration.");
- logger.error(err);
- process.exit();
- }
-});
-
-logger.info("DATABASE: Connected to SQL database " + process.env.DB_NAME + " at " + process.env.DB_HOST);
-
-database.asynchQuery = util.promisify(database.query);
-
-var initTables = require("./init_tables");
initTables().catch((err) => {
- logger.error("DATABASE: Error initializing tables, message: " + err.message)
- process.exit();
-})
+ logger.error(`DATABASE: Error initializing tables, message: ${err.message}`);
+ process.exit(1);
+});
-module.exports = Object.assign({},
+// Mutated in place (not reassigned) so modules that require this file while
+// it is still loading (see query_last_data_from_all_station.js) keep a live
+// reference to the fully populated exports once the require graph settles.
+Object.assign(module.exports,
database,
queryLastDataFromAllStation,
querySingleStationLastData,
@@ -91,5 +63,3 @@ module.exports = Object.assign({},
deleteFirmwareUpdate,
getAllFirmwareUpdates
);
-
-
diff --git a/src/database/firmware_update/create_firmware_update.js b/src/database/firmware_update/create_firmware_update.js
index bb597a1..b9f97e7 100644
--- a/src/database/firmware_update/create_firmware_update.js
+++ b/src/database/firmware_update/create_firmware_update.js
@@ -1,7 +1,9 @@
-var express = require('express');
+const moment = require("moment");
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.createFirmwareUpdate = async function (model, version, file_name) {
- var query = 'INSERT INTO FirmwareUpdate(Model, Version, FileName, Stamp) VALUES (?, ?, ?, ?)';
+ const query = "INSERT INTO FirmwareUpdate(Model, Version, FileName, Stamp) VALUES (?, ?, ?, ?)";
let res;
try {
res = await database.asynchQuery(query, [
@@ -14,5 +16,5 @@ module.exports.createFirmwareUpdate = async function (model, version, file_name)
logger.error("DATABASE: Error creating firmware update");
throw err;
}
- return res
-}
\ No newline at end of file
+ return res;
+};
diff --git a/src/database/firmware_update/delete_firmware_update.js b/src/database/firmware_update/delete_firmware_update.js
index c862e96..5d6529a 100644
--- a/src/database/firmware_update/delete_firmware_update.js
+++ b/src/database/firmware_update/delete_firmware_update.js
@@ -1,19 +1,17 @@
-var express = require('express');
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.deleteFirmwareUpdate = async function (update_id) {
- var delete_user_query = 'DELETE FROM FirmwareUpdate WHERE Id=?';
+ const delete_update_query = "DELETE FROM FirmwareUpdate WHERE Id=?";
let res;
try {
- res = await database.asynchQuery(delete_user_query, [
+ res = await database.asynchQuery(delete_update_query, [
update_id
]);
} catch (err) {
- logger.error("DATABASE: Error deleting firmware update id: " + id);
+ logger.error(`DATABASE: Error deleting firmware update id: ${update_id}`);
throw err;
}
return res;
-}
-
-
-
+};
diff --git a/src/database/firmware_update/get_all_firmware_updates.js b/src/database/firmware_update/get_all_firmware_updates.js
index 6c959fc..81f5c22 100644
--- a/src/database/firmware_update/get_all_firmware_updates.js
+++ b/src/database/firmware_update/get_all_firmware_updates.js
@@ -1,12 +1,12 @@
-var express = require('express');
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.getAllFirmwareUpdates = async function () {
-
- var query = 'SELECT * FROM FirmwareUpdate'
- let f_u = [];
+ const query = "SELECT * FROM FirmwareUpdate";
+ const f_u = [];
try {
- let res = await database.asynchQuery(query);
- for(item of res) {
+ const res = await database.asynchQuery(query);
+ for (const item of res) {
f_u.push({
id: item.Id,
model: item.Model,
@@ -20,5 +20,4 @@ module.exports.getAllFirmwareUpdates = async function () {
throw err;
}
return f_u;
-}
-
+};
diff --git a/src/database/firmware_update/query_update_available.js b/src/database/firmware_update/query_update_available.js
index 4feb349..bbc9886 100644
--- a/src/database/firmware_update/query_update_available.js
+++ b/src/database/firmware_update/query_update_available.js
@@ -1,13 +1,14 @@
-var express = require('express');
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.queryUpdateAvailable = async function (model) {
- var query = 'SELECT Id, Model, Version, FileName, Stamp FROM FirmwareUpdate WHERE Model=? ORDER BY Stamp DESC';
+ const query = "SELECT Id, Model, Version, FileName, Stamp FROM FirmwareUpdate WHERE Model=? ORDER BY Stamp DESC";
let station_update_available;
try {
- let res = await database.asynchQuery(query, [
+ const res = await database.asynchQuery(query, [
model
]);
- if (res.length == 0) {
+ if (res.length === 0) {
station_update_available = [];
} else {
station_update_available = {
@@ -18,8 +19,8 @@ module.exports.queryUpdateAvailable = async function (model) {
};
}
} catch (err) {
- logger.error("DATABASE: Error quering for firmware update available by model: " + model);
+ logger.error(`DATABASE: Error quering for firmware update available by model: ${model}`);
throw err;
}
return station_update_available;
-}
\ No newline at end of file
+};
diff --git a/src/database/firmware_update/query_update_by_id.js b/src/database/firmware_update/query_update_by_id.js
index 49c502f..74f22f6 100644
--- a/src/database/firmware_update/query_update_by_id.js
+++ b/src/database/firmware_update/query_update_by_id.js
@@ -1,14 +1,15 @@
-var express = require('express');
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.queryUpdateById = async function (update_id) {
- var query = 'SELECT Id, Model, Version, FileName, Stamp FROM FirmwareUpdate WHERE Id=?';
+ const query = "SELECT Id, Model, Version, FileName, Stamp FROM FirmwareUpdate WHERE Id=?";
let update;
try {
- let res = await database.asynchQuery(query, [
+ const res = await database.asynchQuery(query, [
update_id
]);
- if (res.length == 0) {
+ if (res.length === 0) {
update = undefined;
} else {
update = {
@@ -18,10 +19,9 @@ module.exports.queryUpdateById = async function (update_id) {
file_name: res[0].FileName
};
}
- }
- catch (err) {
- logger.error("DATABASE: Error quering firmware update available by id: " + id);
+ } catch (err) {
+ logger.error(`DATABASE: Error quering firmware update available by id: ${update_id}`);
throw err;
}
return update;
-}
\ No newline at end of file
+};
diff --git a/src/database/init_tables.js b/src/database/init_tables.js
index fed7c90..319ebae 100644
--- a/src/database/init_tables.js
+++ b/src/database/init_tables.js
@@ -1,144 +1,133 @@
-var express = require('express');
+const crypto = require("crypto");
+const database = require("./connection");
+const logger = require("../utils/logger");
/*
* First startup database init
*/
module.exports = async function initTables() {
try {
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS User(\n' +
- ' Id Int NOT NULL AUTO_INCREMENT,\n' +
- ' Email Varchar(255) NOT NULL,\n' +
- ' Name Varchar(255) NOT NULL,\n' +
- ' Password Varchar(255) NOT NULL,\n' +
- ' Admin ENUM(\'true\', \'false\') NOT NULL,\n' +
- ' PRIMARY KEY (Id), \n' +
- ' UNIQUE (Email) \n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS User(
+ Id Int NOT NULL AUTO_INCREMENT,
+ Email Varchar(255) NOT NULL,
+ Name Varchar(255) NOT NULL,
+ Password Varchar(255) NOT NULL,
+ Admin ENUM('true', 'false') NOT NULL,
+ PRIMARY KEY (Id),
+ UNIQUE (Email)
+);`);
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS sessions(\n' +
- 'session_id varchar(128) COLLATE utf8mb4_bin NOT NULL,\n' +
- 'expires int(11) unsigned NOT NULL,\n' +
- 'data mediumtext COLLATE utf8mb4_bin,\n' +
- 'PRIMARY KEY(session_id)\n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS sessions(
+session_id varchar(128) COLLATE utf8mb4_bin NOT NULL,
+expires int(11) unsigned NOT NULL,
+data mediumtext COLLATE utf8mb4_bin,
+PRIMARY KEY(session_id)
+);`);
-
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS Station(\n' +
- ' Id Int NOT NULL AUTO_INCREMENT,\n' +
- ' StationName Varchar(255) NOT NULL,\n' +
- ' Location Varchar(255) NOT NULL,\n' +
- ' Latitude Float NOT NULL,\n' +
- ' Longitude Float NOT NULL,\n' +
- ' Altitude Int NOT NULL,\n' +
- ' Model Varchar(255),\n' +
- ' FirmwareVersion Varchar(5),\n' +
- ' Token Varchar(255), \n' +
- ' LastUpdate DATETIME, \n' +
- ' PRIMARY KEY (Id) \n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS Station(
+ Id Int NOT NULL AUTO_INCREMENT,
+ StationName Varchar(255) NOT NULL,
+ Location Varchar(255) NOT NULL,
+ Latitude Float NOT NULL,
+ Longitude Float NOT NULL,
+ Altitude Int NOT NULL,
+ Model Varchar(255),
+ FirmwareVersion Varchar(5),
+ Token Varchar(255),
+ LastUpdate DATETIME,
+ PRIMARY KEY (Id)
+);`);
//Seed default Admin User (You should delete it after initial configuration)
- await database.asynchQuery('SELECT * FROM User').then((rows) => {
+ await database.asynchQuery("SELECT * FROM User").then((rows) => {
if (rows[0] === undefined) {
- let hash = crypto.createHash('sha256');
- database.query('INSERT INTO User(Email, Name, Password, Admin) VALUES (?, ?, ?, ?)',
+ const hash = crypto.createHash("sha256");
+ database.query("INSERT INTO User(Email, Name, Password, Admin) VALUES (?, ?, ?, ?)",
[
- 'admin@meteoserver.com',
- 'admin',
- hash.update('password').digest('hex'),
+ "admin@meteoserver.com",
+ "admin",
+ hash.update("password").digest("hex"),
true
]
);
}
});
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS Temperature(\n' +
- ' Id Int NOT NULL,\n' +
- ' Val Float,\n' +
- ' Stamp DATETIME, \n' +
- ' FOREIGN KEY (Id) \n' +
- ' REFERENCES Station (Id)\n' +
- ' ON DELETE CASCADE\n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS Temperature(
+ Id Int NOT NULL,
+ Val Float,
+ Stamp DATETIME,
+ FOREIGN KEY (Id)
+ REFERENCES Station (Id)
+ ON DELETE CASCADE
+);`);
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS Pressure(\n' +
- ' Id Int NOT NULL,\n' +
- ' Val Float,\n' +
- ' Stamp DATETIME, \n' +
- ' FOREIGN KEY (Id) \n' +
- ' REFERENCES Station (Id)\n' +
- ' ON DELETE CASCADE\n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS Pressure(
+ Id Int NOT NULL,
+ Val Float,
+ Stamp DATETIME,
+ FOREIGN KEY (Id)
+ REFERENCES Station (Id)
+ ON DELETE CASCADE
+);`);
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS Humidity(\n' +
- ' Id Int NOT NULL,\n' +
- ' Val Float,\n' +
- ' Stamp DATETIME, \n' +
- ' FOREIGN KEY (Id) \n' +
- ' REFERENCES Station (Id)\n' +
- ' ON DELETE CASCADE\n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS Humidity(
+ Id Int NOT NULL,
+ Val Float,
+ Stamp DATETIME,
+ FOREIGN KEY (Id)
+ REFERENCES Station (Id)
+ ON DELETE CASCADE
+);`);
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS Rain(\n' +
- ' Id Int NOT NULL,\n' +
- ' Val Float,\n' +
- ' Stamp DATETIME, \n' +
- ' FOREIGN KEY (Id) \n' +
- ' REFERENCES Station (Id)\n' +
- ' ON DELETE CASCADE\n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS Rain(
+ Id Int NOT NULL,
+ Val Float,
+ Stamp DATETIME,
+ FOREIGN KEY (Id)
+ REFERENCES Station (Id)
+ ON DELETE CASCADE
+);`);
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS Wind(\n' +
- ' Id Int NOT NULL,\n' +
- ' Speed Float,\n' +
- ' Direction Float,\n' +
- ' Stamp DATETIME, \n' +
- ' FOREIGN KEY (Id) \n' +
- ' REFERENCES Station (Id)\n' +
- ' ON DELETE CASCADE\n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS Wind(
+ Id Int NOT NULL,
+ Speed Float,
+ Direction Float,
+ Stamp DATETIME,
+ FOREIGN KEY (Id)
+ REFERENCES Station (Id)
+ ON DELETE CASCADE
+);`);
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS Lighting(\n' +
- ' Id Int NOT NULL,\n' +
- ' Distance Float,\n' +
- ' Stamp DATETIME, \n' +
- ' FOREIGN KEY (Id) \n' +
- ' REFERENCES Station (Id)\n' +
- ' ON DELETE CASCADE\n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS Lighting(
+ Id Int NOT NULL,
+ Distance Float,
+ Stamp DATETIME,
+ FOREIGN KEY (Id)
+ REFERENCES Station (Id)
+ ON DELETE CASCADE
+);`);
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS AirQuality(\n' +
- ' Id Int NOT NULL,\n' +
- ' PM25 Float,\n' +
- ' PM10 Float,\n' +
- ' Stamp DATETIME, \n' +
- ' FOREIGN KEY (Id) \n' +
- ' REFERENCES Station (Id)\n' +
- ' ON DELETE CASCADE\n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS AirQuality(
+ Id Int NOT NULL,
+ PM25 Float,
+ PM10 Float,
+ Stamp DATETIME,
+ FOREIGN KEY (Id)
+ REFERENCES Station (Id)
+ ON DELETE CASCADE
+);`);
- await database.asynchQuery('CREATE TABLE IF NOT EXISTS FirmwareUpdate(\n' +
- ' Id Int NOT NULL AUTO_INCREMENT, \n' +
- ' Model Varchar(255) NOT NULL, \n' +
- ' Version Varchar(5) NOT NULL, \n' +
- ' FileName Varchar(255) NOT NULL, \n' +
- ' Stamp DATETIME NOT NULL, \n' +
- ' PRIMARY KEY (Id)\n' +
- ');'
- );
+ await database.asynchQuery(`CREATE TABLE IF NOT EXISTS FirmwareUpdate(
+ Id Int NOT NULL AUTO_INCREMENT,
+ Model Varchar(255) NOT NULL,
+ Version Varchar(5) NOT NULL,
+ FileName Varchar(255) NOT NULL,
+ Stamp DATETIME NOT NULL,
+ PRIMARY KEY (Id)
+);`);
} catch (err) {
logger.error("DATABASE: Can't connect to database. Check configuration.");
throw err;
}
};
-
diff --git a/src/database/station/config/create_station.js b/src/database/station/config/create_station.js
index a971634..27552e7 100644
--- a/src/database/station/config/create_station.js
+++ b/src/database/station/config/create_station.js
@@ -1,11 +1,11 @@
-var express = require('express');
-const { v4: uuidv4 } = require('uuid');
-
+const moment = require("moment");
+const { v4: uuidv4 } = require("uuid");
+const database = require("../../connection");
+const logger = require("../../../utils/logger");
module.exports.createStation = async function (station_name, location, latitude, longitude, altitude) {
-
- let timestamp = moment.utc().format("Y-M-D H:mm");
- var query = 'INSERT INTO Station (StationName, Location, Latitude, Longitude, Altitude, Token, LastUpdate) VALUES (?, ?, ?, ?, ?, ?, ?)'
+ const timestamp = moment.utc().format("Y-M-D H:mm");
+ const query = "INSERT INTO Station (StationName, Location, Latitude, Longitude, Altitude, Token, LastUpdate) VALUES (?, ?, ?, ?, ?, ?, ?)";
let res;
try {
res = await database.asynchQuery(query, [
@@ -18,9 +18,8 @@ module.exports.createStation = async function (station_name, location, latitude,
timestamp
]);
} catch (err) {
- logger.error("DATABASE: Error creating station, message: " + err.message);
+ logger.error(`DATABASE: Error creating station, message: ${err.message}`);
throw err;
}
return res;
-}
-
+};
diff --git a/src/database/station/config/delete_station.js b/src/database/station/config/delete_station.js
index d8966a0..26b514a 100644
--- a/src/database/station/config/delete_station.js
+++ b/src/database/station/config/delete_station.js
@@ -1,16 +1,14 @@
-var express = require('express');
+const database = require("../../connection");
+const logger = require("../../../utils/logger");
module.exports.deleteStation = async function (id) {
- var delete_user_query = 'DELETE FROM Station WHERE Id=?';
+ const delete_station_query = "DELETE FROM Station WHERE Id=?";
let res;
try {
- res = await database.asynchQuery(delete_user_query, [id]);
+ res = await database.asynchQuery(delete_station_query, [id]);
} catch (err) {
- logger.error("DATABASE: Error deleting station id: " + id + ", message: " + err.message);
+ logger.error(`DATABASE: Error deleting station id: ${id}, message: ${err.message}`);
throw err;
}
return res;
-}
-
-
-
+};
diff --git a/src/database/station/config/get_all_stations.js b/src/database/station/config/get_all_stations.js
index 75f5217..cac9a87 100644
--- a/src/database/station/config/get_all_stations.js
+++ b/src/database/station/config/get_all_stations.js
@@ -1,12 +1,12 @@
-var express = require('express');
+const database = require("../../connection");
+const logger = require("../../../utils/logger");
module.exports.getAllStations = async function () {
- let timestamp = moment.utc().format("Y-M-D H:mm");
- var query = 'SELECT * FROM Station'
- let station = [];
+ const query = "SELECT * FROM Station";
+ const station = [];
try {
- let res = await database.asynchQuery(query);
- for (item of res) {
+ const res = await database.asynchQuery(query);
+ for (const item of res) {
station.push({
id: item.Id,
name: item.StationName,
@@ -21,9 +21,8 @@ module.exports.getAllStations = async function () {
});
}
} catch (err) {
- logger.error("DATABASE: Error getting all station , message: " + err.message);
+ logger.error(`DATABASE: Error getting all station , message: ${err.message}`);
throw err;
}
return station;
-}
-
+};
diff --git a/src/database/station/config/modify_station.js b/src/database/station/config/modify_station.js
index 3a4836f..3ed150e 100644
--- a/src/database/station/config/modify_station.js
+++ b/src/database/station/config/modify_station.js
@@ -1,8 +1,8 @@
-var express = require('express');
-
+const database = require("../../connection");
+const logger = require("../../../utils/logger");
module.exports.modifyStation = async function (station_name, location, latitude, longitude, altitude, id) {
- var query = 'UPDATE Station SET StationName=?, Location=?, Latitude=?, Longitude=?, Altitude=? WHERE Id=?';
+ const query = "UPDATE Station SET StationName=?, Location=?, Latitude=?, Longitude=?, Altitude=? WHERE Id=?";
let res;
try {
res = await database.asynchQuery(query, [
@@ -14,8 +14,8 @@ module.exports.modifyStation = async function (station_name, location, latitude,
id
]);
} catch (err) {
- logger.error("DATABASE: Error Updating Station: " + station_name + ", message: " + err.message);
- throw err
+ logger.error(`DATABASE: Error Updating Station: ${station_name}, message: ${err.message}`);
+ throw err;
}
- return res
-}
\ No newline at end of file
+ return res;
+};
diff --git a/src/database/station/data_query/delete_data.js b/src/database/station/data_query/delete_data.js
index 78835a1..ed23de6 100644
--- a/src/database/station/data_query/delete_data.js
+++ b/src/database/station/data_query/delete_data.js
@@ -1,81 +1,79 @@
-var express = require('express');
-
+const database = require("../../connection");
+const logger = require("../../../utils/logger");
module.exports.deleteSingleTemperature = async function (id, stamp) {
let res;
try {
- res = await database.asynchQuery('DELETE FROM Temperature WHERE Id = ? AND Stamp = ?', [id, stamp]);
+ res = await database.asynchQuery("DELETE FROM Temperature WHERE Id = ? AND Stamp = ?", [id, stamp]);
} catch (err) {
- logger.error("DATABASE: Error deleting from Temperature item: " + id + ',' + stamp);
- throw err
+ logger.error(`DATABASE: Error deleting from Temperature item: ${id},${stamp}, message: ${err.message}`);
+ throw err;
}
return res;
-}
+};
module.exports.deleteSingleHumidity = async function (id, stamp) {
let res;
try {
- res = await database.asynchQuery('DELETE FROM Humidity WHERE Id = ? AND Stamp = ?', [id, stamp]);
+ res = await database.asynchQuery("DELETE FROM Humidity WHERE Id = ? AND Stamp = ?", [id, stamp]);
} catch (err) {
- logger.error("DATABASE: Error deleting from Humidity item: " + id + ',' + stamp + ", message: " + err.message);
- throw err
+ logger.error(`DATABASE: Error deleting from Humidity item: ${id},${stamp}, message: ${err.message}`);
+ throw err;
}
return res;
-}
+};
module.exports.deleteSinglePressure = async function (id, stamp) {
let res;
try {
- res = await database.asynchQuery('DELETE FROM Pressure WHERE Id = ? AND Stamp = ?', [id, stamp]);
+ res = await database.asynchQuery("DELETE FROM Pressure WHERE Id = ? AND Stamp = ?", [id, stamp]);
} catch (err) {
- logger.error("DATABASE: Error deleting from Pressure item: " + id + ',' + stamp);
- throw err
+ logger.error(`DATABASE: Error deleting from Pressure item: ${id},${stamp}, message: ${err.message}`);
+ throw err;
}
return res;
-}
+};
module.exports.deleteSingleRain = async function (id, stamp) {
let res;
try {
- res = await database.asynchQuery('DELETE FROM Rain WHERE Id = ? AND Stamp = ?', [id, stamp]);
+ res = await database.asynchQuery("DELETE FROM Rain WHERE Id = ? AND Stamp = ?", [id, stamp]);
} catch (err) {
- logger.error("DATABASE: Error deleting from Rain item: " + id + ',' + stamp);
- throw err
+ logger.error(`DATABASE: Error deleting from Rain item: ${id},${stamp}, message: ${err.message}`);
+ throw err;
}
return res;
-}
+};
module.exports.deleteSingleWind = async function (id, stamp) {
let res;
try {
- res = await database.asynchQuery('DELETE FROM Wind WHERE Id = ? AND Stamp = ?', [id, stamp]);
+ res = await database.asynchQuery("DELETE FROM Wind WHERE Id = ? AND Stamp = ?", [id, stamp]);
} catch (err) {
- logger.error("DATABASE: Error deleting from Wind item: " + id + ',' + stamp);
- throw err
+ logger.error(`DATABASE: Error deleting from Wind item: ${id},${stamp}, message: ${err.message}`);
+ throw err;
}
return res;
-}
+};
module.exports.deleteSingleLighting = async function (id, stamp) {
let res;
try {
- res = await database.asynchQuery('DELETE FROM Lighting WHERE Id = ? AND Stamp = ?', [id, stamp]);
+ res = await database.asynchQuery("DELETE FROM Lighting WHERE Id = ? AND Stamp = ?", [id, stamp]);
} catch (err) {
- logger.error("DATABASE: Error deleting from Lighting item: " + id + ',' + stamp);
- throw err
+ logger.error(`DATABASE: Error deleting from Lighting item: ${id},${stamp}, message: ${err.message}`);
+ throw err;
}
return res;
-}
-
+};
module.exports.deleteSingleAirQuality = async function (id, stamp) {
let res;
try {
- res = await database.asynchQuery('DELETE FROM AirQuality WHERE Id = ? AND Stamp = ?', [id, stamp]);
+ res = await database.asynchQuery("DELETE FROM AirQuality WHERE Id = ? AND Stamp = ?", [id, stamp]);
} catch (err) {
- logger.error("DATABASE: Error deleting from AirQuality item: " + id + ',' + stamp);
- throw err
+ logger.error(`DATABASE: Error deleting from AirQuality item: ${id},${stamp}, message: ${err.message}`);
+ throw err;
}
return res;
-}
-
+};
diff --git a/src/database/station/data_query/list_station.js b/src/database/station/data_query/list_station.js
index 330d74d..b5f4dba 100644
--- a/src/database/station/data_query/list_station.js
+++ b/src/database/station/data_query/list_station.js
@@ -1,11 +1,11 @@
-var express = require('express');
-
+const database = require("../../connection");
+const logger = require("../../../utils/logger");
module.exports.listStation = async function () {
- let station = [];
+ const station = [];
try {
- let rows = await database.asynchQuery('SELECT Id, StationName, Location, Latitude, Longitude, Altitude FROM Station');
- for (item of rows) {
+ const rows = await database.asynchQuery("SELECT Id, StationName, Location, Latitude, Longitude, Altitude FROM Station");
+ for (const item of rows) {
station.push({
id: item.Id,
name: item.StationName,
@@ -16,8 +16,8 @@ module.exports.listStation = async function () {
});
}
} catch (err) {
- logger.error("DATABASE: Error getting all station (list), message: " + err.message);
+ logger.error(`DATABASE: Error getting all station (list), message: ${err.message}`);
throw err;
}
return station;
-}
\ No newline at end of file
+};
diff --git a/src/database/station/data_query/query_history_station_data.js b/src/database/station/data_query/query_history_station_data.js
index 506b927..349e8ce 100644
--- a/src/database/station/data_query/query_history_station_data.js
+++ b/src/database/station/data_query/query_history_station_data.js
@@ -1,20 +1,22 @@
-var express = require('express');
-
+const moment = require("moment");
+const database = require("../../connection");
+const meteoUtils = require("../../../utils/meteo_utils");
+const logger = require("../../../utils/logger");
module.exports.queryHistoryStationData = async function (station_id, timestamp_start, timestamp_end) {
- var station_query = 'SELECT * FROM Station WHERE Id=?';
- var temp_query = 'SELECT * FROM Temperature INNER JOIN Station ON Temperature.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC';
- var pres_query = 'SELECT * FROM Pressure INNER JOIN Station ON Pressure.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC';
- var hum_query = 'SELECT * FROM Humidity INNER JOIN Station ON Humidity.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC';
- var rain_query = 'SELECT * FROM Rain INNER JOIN Station ON Rain.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC';
- var wind_query = 'SELECT * FROM Wind INNER JOIN Station ON Wind.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC';
- var lighting_query = 'SELECT * FROM Lighting INNER JOIN Station ON Lighting.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC';
- var air_quality_query = 'SELECT * FROM AirQuality INNER JOIN Station ON AirQuality.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC';
+ const station_query = "SELECT * FROM Station WHERE Id=?";
+ const temp_query = "SELECT * FROM Temperature INNER JOIN Station ON Temperature.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC";
+ const pres_query = "SELECT * FROM Pressure INNER JOIN Station ON Pressure.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC";
+ const hum_query = "SELECT * FROM Humidity INNER JOIN Station ON Humidity.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC";
+ const rain_query = "SELECT * FROM Rain INNER JOIN Station ON Rain.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC";
+ const wind_query = "SELECT * FROM Wind INNER JOIN Station ON Wind.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC";
+ const lighting_query = "SELECT * FROM Lighting INNER JOIN Station ON Lighting.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC";
+ const air_quality_query = "SELECT * FROM AirQuality INNER JOIN Station ON AirQuality.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp ASC";
//DATA OBJECT
// Data that belong to the same table are placed in differnt array. Search a pair using the same index.
- var data = {
+ const data = {
name: "",
id: 0,
location: 0,
@@ -37,9 +39,8 @@ module.exports.queryHistoryStationData = async function (station_id, timestamp_s
}
};
-
if (!timestamp_start) {
- timestamp_start = moment.utc().startOf('day').format("Y-M-D H:mm");
+ timestamp_start = moment.utc().startOf("day").format("Y-M-D H:mm");
}
if (!timestamp_end) {
@@ -47,12 +48,11 @@ module.exports.queryHistoryStationData = async function (station_id, timestamp_s
}
try {
-
//Cerco la stazione attualmente selezionata
- rows = await database.asynchQuery(station_query, [station_id]);
- let selected_station = rows[0];
+ let rows = await database.asynchQuery(station_query, [station_id]);
+ const selected_station = rows[0];
- if (selected_station == undefined) return undefined; //station id not existing
+ if (selected_station === undefined) return undefined; //station id not existing
data.name = selected_station.StationName;
data.id = selected_station.Id;
@@ -62,7 +62,6 @@ module.exports.queryHistoryStationData = async function (station_id, timestamp_s
data.altitude = selected_station.Altitude;
data.last_update = selected_station.LastUpdate;
-
//TEMPERATURE
rows = await database.asynchQuery(temp_query, [
station_id,
@@ -70,12 +69,12 @@ module.exports.queryHistoryStationData = async function (station_id, timestamp_s
timestamp_end
]);
if (rows[0] !== undefined) {
- for (item of rows) {
+ for (const item of rows) {
data.temperature.val.push(item.Val);
data.temperature.stamp.push(moment.utc(item.Stamp).format("D/M/Y H:mm"));
}
} else {
- data.temperature = "N/A"
+ data.temperature = "N/A";
}
//PRESSURE
@@ -85,12 +84,12 @@ module.exports.queryHistoryStationData = async function (station_id, timestamp_s
timestamp_end
]);
if (rows[0] !== undefined) {
- for (item of rows) {
+ for (const item of rows) {
data.pressure.val.push(meteoUtils.seaLevelPressure(item.Val, selected_station.Altitude));
data.pressure.stamp.push(moment.utc(item.Stamp).format("D/M/Y H:mm"));
}
} else {
- data.pressure = "N/A"
+ data.pressure = "N/A";
}
//HUMIDITY
@@ -100,12 +99,12 @@ module.exports.queryHistoryStationData = async function (station_id, timestamp_s
timestamp_end
]);
if (rows[0] !== undefined) {
- for (item of rows) {
+ for (const item of rows) {
data.humidity.val.push(item.Val);
data.humidity.stamp.push(moment.utc(item.Stamp).format("D/M/Y H:mm"));
}
} else {
- data.humidity = "N/A"
+ data.humidity = "N/A";
}
//RAIN
@@ -115,16 +114,16 @@ module.exports.queryHistoryStationData = async function (station_id, timestamp_s
timestamp_end
]);
if (rows[0] !== undefined) {
- for (item of rows) {
+ for (const item of rows) {
data.rain.val.push(item.Val);
data.rain.stamp.push(moment.utc(item.Stamp).format("D/M/Y H:mm"));
}
- for (item of rows) {
+ for (const item of rows) {
data.rain.total_rainfall += item.Val;
}
} else {
- data.rain = "N/A"
+ data.rain = "N/A";
}
//LIGHTING
@@ -134,12 +133,12 @@ module.exports.queryHistoryStationData = async function (station_id, timestamp_s
timestamp_end
]);
if (rows[0] !== undefined) {
- for (item of rows) {
+ for (const item of rows) {
data.lighting.distance.push(item.Distance);
data.lighting.stamp.push(moment.utc(item.Stamp).format("D/M/Y H:mm"));
}
} else {
- data.lighting = "N/A"
+ data.lighting = "N/A";
}
//WIND
@@ -149,14 +148,14 @@ module.exports.queryHistoryStationData = async function (station_id, timestamp_s
timestamp_end
]);
if (rows[0] !== undefined) {
- for (item of rows) {
+ for (const item of rows) {
data.wind.speed.push(item.Speed);
data.wind.direction.push(item.Direction);
data.wind.cardinal_direction.push(meteoUtils.degToCardinal(item.Direction));
data.wind.stamp.push(moment.utc(item.Stamp).format("D/M/Y H:mm"));
}
} else {
- data.wind = "N/A"
+ data.wind = "N/A";
}
//AIR QUALITY
@@ -166,18 +165,18 @@ module.exports.queryHistoryStationData = async function (station_id, timestamp_s
timestamp_end
]);
if (rows[0] !== undefined) {
- for (item of rows) {
+ for (const item of rows) {
data.air_quality.PM25.push(item.PM25);
data.air_quality.PM10.push(item.PM10);
data.air_quality.iqa.push(meteoUtils.iqa(item.PM25, item.PM10));
data.air_quality.stamp.push(moment.utc(item.Stamp).format("D/M/Y H:mm"));
}
} else {
- data.air_quality = "N/A"
+ data.air_quality = "N/A";
}
} catch (err) {
- logger.error("DATABASE: Error getting history station data, message: " + err.message);
+ logger.error(`DATABASE: Error getting history station data, message: ${err.message}`);
throw err;
}
return data;
-}
\ No newline at end of file
+};
diff --git a/src/database/station/data_query/query_last_data_from_all_station.js b/src/database/station/data_query/query_last_data_from_all_station.js
index 1817fa9..0e628cb 100644
--- a/src/database/station/data_query/query_last_data_from_all_station.js
+++ b/src/database/station/data_query/query_last_data_from_all_station.js
@@ -1,16 +1,14 @@
-var express = require('express');
-
+const database = require("../../connection");
+const db = require("../../database");
module.exports.queryLastDataFromAllStation = async function () {
-
-
- var all_station_data = [];
- let station = await database.asynchQuery('SELECT * FROM Station');
+ const allStationData = [];
+ const station = await database.asynchQuery("SELECT * FROM Station");
for (let i = 0; i < station.length; i++) {
- let data = await db.querySingleStationLastData(station[i].Id);
- all_station_data.push(data);
+ const data = await db.querySingleStationLastData(station[i].Id);
+ allStationData.push(data);
}
- return all_station_data;
-}
\ No newline at end of file
+ return allStationData;
+};
diff --git a/src/database/station/data_query/query_single_station_last_data.js b/src/database/station/data_query/query_single_station_last_data.js
index b35d208..c12c413 100644
--- a/src/database/station/data_query/query_single_station_last_data.js
+++ b/src/database/station/data_query/query_single_station_last_data.js
@@ -1,41 +1,42 @@
-var express = require('express');
-
+const moment = require("moment");
+const database = require("../../connection");
+const meteoUtils = require("../../../utils/meteo_utils");
+const logger = require("../../../utils/logger");
module.exports.querySingleStationLastData = async function (station_id) {
- var temp_query = 'SELECT Station.Id, StationName, Location, Altitude, Val, Stamp FROM Temperature INNER JOIN Station ON Temperature.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC';
+ const temp_query = "SELECT Station.Id, StationName, Location, Altitude, Val, Stamp FROM Temperature INNER JOIN Station ON Temperature.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC";
- var max_temp_query = 'SELECT MAX(Val) AS Max FROM Temperature INNER JOIN Station ON Temperature.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ?';
- var min_temp_query = 'SELECT MIN(Val) AS Min FROM Temperature INNER JOIN Station ON Temperature.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ?';
+ const max_temp_query = "SELECT MAX(Val) AS Max FROM Temperature INNER JOIN Station ON Temperature.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ?";
+ const min_temp_query = "SELECT MIN(Val) AS Min FROM Temperature INNER JOIN Station ON Temperature.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ?";
- var pres_query = 'SELECT Station.Id, StationName, Location, Altitude, Val, Stamp FROM Pressure INNER JOIN Station ON Pressure.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC';
+ const pres_query = "SELECT Station.Id, StationName, Location, Altitude, Val, Stamp FROM Pressure INNER JOIN Station ON Pressure.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC";
- var hum_query = 'SELECT Station.Id, StationName, Location, Altitude, Val, Stamp FROM Humidity INNER JOIN Station ON Humidity.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC LIMIT 1';
+ const hum_query = "SELECT Station.Id, StationName, Location, Altitude, Val, Stamp FROM Humidity INNER JOIN Station ON Humidity.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC LIMIT 1";
- var rain_query = 'SELECT Station.Id, Val, Stamp FROM Rain INNER JOIN Station ON Rain.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC LIMIT 1';
- var rain_sum_query = 'SELECT SUM(Val) AS total FROM Rain INNER JOIN Station ON Rain.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ?';
- var rain_sum_query_hour = 'SELECT SUM(Val) AS total FROM Rain INNER JOIN Station ON Rain.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ?';
+ const rain_query = "SELECT Station.Id, Val, Stamp FROM Rain INNER JOIN Station ON Rain.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC LIMIT 1";
+ const rain_sum_query = "SELECT SUM(Val) AS total FROM Rain INNER JOIN Station ON Rain.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ?";
+ const rain_sum_query_hour = "SELECT SUM(Val) AS total FROM Rain INNER JOIN Station ON Rain.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ?";
- var lighting_query = 'SELECT Station.Id, Distance, Stamp FROM Lighting INNER JOIN Station ON Lighting.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC LIMIT 1';
+ const lighting_query = "SELECT Station.Id, Distance, Stamp FROM Lighting INNER JOIN Station ON Lighting.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC LIMIT 1";
- var wind_query = 'SELECT Station.Id, StationName, Location, Altitude, Speed, Direction, Stamp FROM Wind INNER JOIN Station ON Wind.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC LIMIT 1';
+ const wind_query = "SELECT Station.Id, StationName, Location, Altitude, Speed, Direction, Stamp FROM Wind INNER JOIN Station ON Wind.Id = Station.Id WHERE Station.Id=? AND Stamp BETWEEN ? AND ? ORDER BY Stamp DESC LIMIT 1";
- var air_quality_query = 'SELECT Station.Id, StationName, Location, Altitude, Round(AVG(PM25),1) AS PM25, Round(AVG(PM10),1) AS PM10, cast(AirQuality.Stamp as date) AS Stamp FROM AirQuality INNER JOIN Station ON AirQuality.Id = Station.Id WHERE Station.Id=? AND AirQuality.Stamp BETWEEN ? AND ? GROUP BY cast(AirQuality.Stamp as date) ORDER BY cast(AirQuality.Stamp as date) DESC LIMIT 1';
+ const air_quality_query = "SELECT Station.Id, StationName, Location, Altitude, Round(AVG(PM25),1) AS PM25, Round(AVG(PM10),1) AS PM10, cast(AirQuality.Stamp as date) AS Stamp FROM AirQuality INNER JOIN Station ON AirQuality.Id = Station.Id WHERE Station.Id=? AND AirQuality.Stamp BETWEEN ? AND ? GROUP BY cast(AirQuality.Stamp as date) ORDER BY cast(AirQuality.Stamp as date) DESC LIMIT 1";
- let station = await database.asynchQuery('SELECT * FROM Station WHERE Id = ?', [
+ let station = await database.asynchQuery("SELECT * FROM Station WHERE Id = ?", [
station_id
]);
station = station[0];
- if (station == undefined) return undefined; //station id not existing
+ if (station === undefined) return undefined; //station id not existing
/*------RETURN OBJECT INIT------*/
- let name = station.StationName;
- let id = station.Id;
- let location = station.Location;
- let latitude = station.Latitude;
- let longitude = station.Longitude;
- let altitude = station.Altitude;
- let last_update = undefined;
+ const name = station.StationName;
+ const location = station.Location;
+ const latitude = station.Latitude;
+ const longitude = station.Longitude;
+ const altitude = station.Altitude;
+ let last_update;
let temperature = 0;
let temperature_trend = 0;
let max_temperature = 0;
@@ -62,20 +63,20 @@ module.exports.querySingleStationLastData = async function (station_id) {
PM25: 0,
PM10: 0,
iqa: 0
- }
+ };
+ let windchill;
+ let forecast;
- if (last_update !== null) {
+ if (station.LastUpdate !== null) {
last_update = moment.utc(station.LastUpdate).format("D/M/Y H:mm");
- }
- else {
- last_update = 'N/A'
+ } else {
+ last_update = "N/A";
}
- midnight_time_stamp = moment.utc().startOf('day').format("Y-M-D H:mm");
- now_time_stamp = moment.utc().format("Y-M-D H:mm");
+ const midnight_time_stamp = moment.utc().startOf("day").format("Y-M-D H:mm");
+ const now_time_stamp = moment.utc().format("Y-M-D H:mm");
try {
-
//Temperature - related
let rows = await database.asynchQuery(temp_query, [
station_id,
@@ -83,7 +84,7 @@ module.exports.querySingleStationLastData = async function (station_id) {
now_time_stamp
]);
if (rows[0] === undefined) {
- temperature = 'N/A';
+ temperature = "N/A";
} else {
temperature = rows[0].Val;
temperature_trend = Math.round((rows[rows.length - 1].Val - rows[0].Val) * 10) / 10;
@@ -101,8 +102,8 @@ module.exports.querySingleStationLastData = async function (station_id) {
]);
min_temperature = Math.round(rows[0].Min * 10) / 10;
} else {
- max_temperature = 'N/A';
- min_temperature = 'N/A';
+ max_temperature = "N/A";
+ min_temperature = "N/A";
}
}
@@ -113,10 +114,9 @@ module.exports.querySingleStationLastData = async function (station_id) {
now_time_stamp
]);
if (rows[0] === undefined) {
- pressure = 'N/A';
- sea_level_pressure = 'N/A';
- }
- else {
+ pressure = "N/A";
+ sea_level_pressure = "N/A";
+ } else {
pressure = Math.round(rows[0].Val) / 100;
pressure_trend = Math.round(rows[rows.length - 1].Val - rows[0].Val) / 100;
sea_level_pressure = meteoUtils.seaLevelPressure(rows[0].Val, altitude);
@@ -129,19 +129,18 @@ module.exports.querySingleStationLastData = async function (station_id) {
now_time_stamp
]);
if (rows[0] === undefined) {
- humidity = 'N/A';
- }
- else {
+ humidity = "N/A";
+ } else {
humidity = rows[0].Val;
}
//Dew Point -- Humidex
- if (temperature !== 'N/A' && humidity !== 'N/A') {
+ if (temperature !== "N/A" && humidity !== "N/A") {
dew_point = meteoUtils.dewPoint(temperature, humidity);
humidex = meteoUtils.humidex(temperature, humidity);
} else {
- dew_point = 'N/A';
- humidex = 'N/A';
+ dew_point = "N/A";
+ humidex = "N/A";
}
//Rain - related
@@ -151,9 +150,8 @@ module.exports.querySingleStationLastData = async function (station_id) {
now_time_stamp
]);
if (rows[0] === undefined) {
- rain_last = 'N/A';
- }
- else {
+ rain_last = "N/A";
+ } else {
rain_last = Math.round(rows[0].Val * 100) / 100;
}
@@ -162,10 +160,8 @@ module.exports.querySingleStationLastData = async function (station_id) {
midnight_time_stamp,
now_time_stamp
]);
- if (rows === undefined) {
- rain_day = 'N/A';
- } else if (rows[0].total === null) {
- rain_day = 'N/A';
+ if (rows === undefined || rows[0].total === null) {
+ rain_day = "N/A";
} else {
rain_day = Math.round(rows[0].total * 100) / 100;
}
@@ -175,10 +171,8 @@ module.exports.querySingleStationLastData = async function (station_id) {
moment.utc().hour(moment.utc().hour() - 1).format("Y-M-D H:mm"),
now_time_stamp
]);
- if (rows === undefined) {
- rain_hour = 'N/A';
- } else if (rows[0].total === null) {
- rain_hour = 'N/A';
+ if (rows === undefined || rows[0].total === null) {
+ rain_hour = "N/A";
} else {
rain_hour = Math.round(rows[0].total * 100) / 100;
}
@@ -191,20 +185,18 @@ module.exports.querySingleStationLastData = async function (station_id) {
]);
if (rows[0] === undefined) {
- wind = 'N/A';
- }
- else {
+ wind = "N/A";
+ } else {
wind.speed = rows[0].Speed;
wind.direction = rows[0].Direction;
wind.cardinal_direction = meteoUtils.degToCardinal(wind.direction);
}
-
//Windchill
- if (temperature !== 'N/A' && wind !== 'N/A') {
- windchill = meteoUtils.windchill(temperature, wind.speed)
+ if (temperature !== "N/A" && wind !== "N/A") {
+ windchill = meteoUtils.windchill(temperature, wind.speed);
} else {
- windchill = 'N/A';
+ windchill = "N/A";
}
//Lighting - related
@@ -214,9 +206,8 @@ module.exports.querySingleStationLastData = async function (station_id) {
now_time_stamp
]);
if (rows[0] === undefined) {
- lighting = 'N/A';
- }
- else {
+ lighting = "N/A";
+ } else {
lighting.distance = rows[0].Distance;
lighting.stamp = moment.utc(rows[0].Stamp).format("D-M-Y H:mm");
}
@@ -228,57 +219,56 @@ module.exports.querySingleStationLastData = async function (station_id) {
now_time_stamp
]);
if (rows[0] === undefined) {
- air_quality = 'N/A';
- }
- else {
+ air_quality = "N/A";
+ } else {
air_quality.PM25 = rows[0].PM25;
air_quality.PM10 = rows[0].PM10;
- air_quality.iqa = meteoUtils.iqa(rows[0].PM25, rows[0].PM10)
+ air_quality.iqa = meteoUtils.iqa(rows[0].PM25, rows[0].PM10);
}
//Get forecast
- if (sea_level_pressure !== 'N/A') {
+ if (sea_level_pressure !== "N/A") {
let trend = 0;
if (pressure_trend > 1) trend = 1;
if (pressure_trend < -1) trend = 2;
- if (wind !== 'N/A' && wind.speed > 0) {
+ if (wind !== "N/A" && wind.speed > 0) {
forecast = meteoUtils.forecast(sea_level_pressure, wind.cardinal_direction, trend);
} else {
forecast = meteoUtils.forecast(sea_level_pressure, 1, trend);
}
} else {
- forecast = 'N/A';
+ forecast = "N/A";
}
} catch (err) {
- logger.error("DATABASE: Error getting single station last data, message: " + err.message);
+ logger.error(`DATABASE: Error getting single station last data, message: ${err.message}`);
throw err;
}
return {
station: name,
- location: location,
- latitude: latitude,
- longitude: longitude,
- altitude: altitude,
- last_update: last_update,
- temperature: temperature,
- temperature_trend: temperature_trend,
- max_temperature: max_temperature,
- min_temperature: min_temperature,
- pressure: pressure,
- sea_level_pressure: sea_level_pressure,
- pressure_trend: pressure_trend,
- humidity: humidity,
- dew_point: dew_point,
- humidex: humidex,
- rain_day: rain_day,
- rain_hour: rain_hour,
- rain_last: rain_last,
- lighting: lighting,
- wind: wind,
- air_quality: air_quality,
- windchill: windchill,
- forecast: forecast
+ location,
+ latitude,
+ longitude,
+ altitude,
+ last_update,
+ temperature,
+ temperature_trend,
+ max_temperature,
+ min_temperature,
+ pressure,
+ sea_level_pressure,
+ pressure_trend,
+ humidity,
+ dew_point,
+ humidex,
+ rain_day,
+ rain_hour,
+ rain_last,
+ lighting,
+ wind,
+ air_quality,
+ windchill,
+ forecast
};
-}
\ No newline at end of file
+};
diff --git a/src/database/station/data_query/update_station_data.js b/src/database/station/data_query/update_station_data.js
index 6e9f455..057874d 100644
--- a/src/database/station/data_query/update_station_data.js
+++ b/src/database/station/data_query/update_station_data.js
@@ -1,5 +1,6 @@
-var express = require('express');
-
+const moment = require("moment");
+const database = require("../../connection");
+const logger = require("../../../utils/logger");
module.exports.updateStationData = async function (data) {
@@ -25,89 +26,87 @@ module.exports.updateStationData = async function (data) {
}
*/
-
- let station = await database.asynchQuery('SELECT * FROM Station WHERE Token=?', [data.token]);
+ let station = await database.asynchQuery("SELECT * FROM Station WHERE Token=?", [data.token]);
//Unauthorized request
- if (station.length == 0) {
+ if (station.length === 0) {
return false;
}
station = station[0];
- let insert_temperature = 'INSERT INTO Temperature (Id, Val, Stamp) VALUES (?, ?, ?)';
- let insert_pressure = 'INSERT INTO Pressure (Id, Val, Stamp) VALUES (?, ?, ?)';
- let insert_humidity = 'INSERT INTO Humidity (Id, Val, Stamp) VALUES (?, ?, ?)';
- let insert_rain = 'INSERT INTO Rain (Id, Val, Stamp) VALUES (?, ?, ?)';
- let insert_wind = 'INSERT INTO Wind (Id, Speed, Direction, Stamp) VALUES (?, ?, ?, ?)';
- let insert_lighting = 'INSERT INTO Lighting (Id, Distance, Stamp) VALUES (?, ?, ?)';
- let insert_air_quality = 'INSERT INTO AirQuality (Id, PM25, PM10, Stamp) VALUES (?, ?, ?, ?)';
+ const insert_temperature = "INSERT INTO Temperature (Id, Val, Stamp) VALUES (?, ?, ?)";
+ const insert_pressure = "INSERT INTO Pressure (Id, Val, Stamp) VALUES (?, ?, ?)";
+ const insert_humidity = "INSERT INTO Humidity (Id, Val, Stamp) VALUES (?, ?, ?)";
+ const insert_rain = "INSERT INTO Rain (Id, Val, Stamp) VALUES (?, ?, ?)";
+ const insert_wind = "INSERT INTO Wind (Id, Speed, Direction, Stamp) VALUES (?, ?, ?, ?)";
+ const insert_lighting = "INSERT INTO Lighting (Id, Distance, Stamp) VALUES (?, ?, ?)";
+ const insert_air_quality = "INSERT INTO AirQuality (Id, PM25, PM10, Stamp) VALUES (?, ?, ?, ?)";
- let station_last_update = 'UPDATE Station SET LastUpdate=? WHERE Id=?';
- let station_ota = 'UPDATE Station SET FirmwareVersion=?, Model=? WHERE Id=?';
+ const station_last_update = "UPDATE Station SET LastUpdate=? WHERE Id=?";
+ const station_ota = "UPDATE Station SET FirmwareVersion=?, Model=? WHERE Id=?";
+ const timestamp = moment.utc().format("Y-M-D H:mm");
- let timestamp = moment.utc().format("Y-M-D H:mm");
-
- if (data.hasOwnProperty("temperature")) {
+ if (Object.hasOwn(data, "temperature")) {
try {
await database.asynchQuery(insert_temperature, [station.Id, data.temperature, timestamp]);
} catch (err) {
- logger.error("DATABASE: Error inserting new Temperature, message: " + err.message);
+ logger.error(`DATABASE: Error inserting new Temperature, message: ${err.message}`);
throw err;
}
}
- if (data.hasOwnProperty("pressure")) {
+ if (Object.hasOwn(data, "pressure")) {
try {
await database.asynchQuery(insert_pressure, [station.Id, data.pressure, timestamp]);
} catch (err) {
- logger.error("DATABASE: Error inserting new Pressure, message: " + err.message);
+ logger.error(`DATABASE: Error inserting new Pressure, message: ${err.message}`);
throw err;
}
}
- if (data.hasOwnProperty("humidity")) {
+ if (Object.hasOwn(data, "humidity")) {
try {
await database.asynchQuery(insert_humidity, [station.Id, data.humidity, timestamp]);
} catch (err) {
- logger.error("DATABASE: Error inserting new Humidity, message: " + err.message);
+ logger.error(`DATABASE: Error inserting new Humidity, message: ${err.message}`);
throw err;
}
}
- if (data.hasOwnProperty("rain")) {
+ if (Object.hasOwn(data, "rain")) {
try {
await database.asynchQuery(insert_rain, [station.Id, data.rain, timestamp]);
} catch (err) {
- logger.error("DATABASE: Error inserting new Rain, message: " + err.message);
+ logger.error(`DATABASE: Error inserting new Rain, message: ${err.message}`);
throw err;
}
}
- if (data.hasOwnProperty("wind")) {
+ if (Object.hasOwn(data, "wind")) {
try {
await database.asynchQuery(insert_wind, [station.Id, data.wind.speed, data.wind.direction, timestamp]);
} catch (err) {
- logger.error("DATABASE: Error inserting new Wind, message: " + err.message);
+ logger.error(`DATABASE: Error inserting new Wind, message: ${err.message}`);
throw err;
}
}
- if (data.hasOwnProperty("lighting")) {
+ if (Object.hasOwn(data, "lighting")) {
try {
await database.asynchQuery(insert_lighting, [station.Id, data.lighting, timestamp]);
} catch (err) {
- logger.error("DATABASE: Error inserting new Lighting, message: " + err.message);
+ logger.error(`DATABASE: Error inserting new Lighting, message: ${err.message}`);
throw err;
}
}
- if (data.hasOwnProperty("air_quality")) {
+ if (Object.hasOwn(data, "air_quality")) {
try {
await database.asynchQuery(insert_air_quality, [station.Id, data.air_quality.PM25, data.air_quality.PM10, timestamp]);
} catch (err) {
- logger.error("DATABASE: Error inserting new AirQuality, message: " + err.message);
+ logger.error(`DATABASE: Error inserting new AirQuality, message: ${err.message}`);
throw err;
}
}
@@ -116,12 +115,12 @@ module.exports.updateStationData = async function (data) {
try {
await database.asynchQuery(station_last_update, [timestamp, station.Id]);
} catch (err) {
- logger.error("DATABASE: Error updating LastUpdate, message: " + err.message);
+ logger.error(`DATABASE: Error updating LastUpdate, message: ${err.message}`);
throw err;
}
- //Upate model and firmware version
- if (data.hasOwnProperty("model") && data.hasOwnProperty("firmware_version")) {
+ //Update model and firmware version
+ if (Object.hasOwn(data, "model") && Object.hasOwn(data, "firmware_version")) {
try {
await database.asynchQuery(station_ota, [
data.firmware_version,
@@ -129,11 +128,10 @@ module.exports.updateStationData = async function (data) {
station.Id
]);
} catch (err) {
- logger.error("DATABASE: Error init tables, message: " + err.message);
+ logger.error(`DATABASE: Error init tables, message: ${err.message}`);
throw err;
}
}
return true;
-}
-
+};
diff --git a/src/database/user/create_user.js b/src/database/user/create_user.js
index 9f6545f..fc363fe 100644
--- a/src/database/user/create_user.js
+++ b/src/database/user/create_user.js
@@ -1,7 +1,8 @@
-var express = require('express');
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.createUser = async function (email, name, password, admin) {
- var query = 'INSERT INTO User(Email, Name, Password, Admin) VALUES (?, ?, ?, ?)';
+ const query = "INSERT INTO User(Email, Name, Password, Admin) VALUES (?, ?, ?, ?)";
let res;
try {
res = await database.asynchQuery(query, [
@@ -11,9 +12,9 @@ module.exports.createUser = async function (email, name, password, admin) {
admin
]);
} catch (err) {
- logger.error("DATABASE: Error creating user email: " + email);
- throw err
- };
+ logger.error(`DATABASE: Error creating user email: ${email}`);
+ throw err;
+ }
return res;
-}
\ No newline at end of file
+};
diff --git a/src/database/user/delete_user.js b/src/database/user/delete_user.js
index 606e2df..ac41339 100644
--- a/src/database/user/delete_user.js
+++ b/src/database/user/delete_user.js
@@ -1,17 +1,17 @@
-var express = require('express');
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.deleteUser = async function (user_id) {
- var query = 'DELETE FROM User WHERE Id=?';
+ const query = "DELETE FROM User WHERE Id=?";
let res;
try {
res = await database.asynchQuery(query, [
user_id
]);
- }catch(err){
- logger.error("DATABASE: Error deleting user id: " + id);
- throw err
- };
-}
-
-
+ } catch (err) {
+ logger.error(`DATABASE: Error deleting user id: ${user_id}`);
+ throw err;
+ }
+ return res;
+};
diff --git a/src/database/user/get_all_users.js b/src/database/user/get_all_users.js
index 79f8552..edac242 100644
--- a/src/database/user/get_all_users.js
+++ b/src/database/user/get_all_users.js
@@ -1,22 +1,22 @@
-var express = require('express');
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.getAllUsers = async function () {
- var query = 'SELECT Id, Email, Name, Admin FROM User'
- let users = [];
+ const query = "SELECT Id, Email, Name, Admin FROM User";
+ const users = [];
try {
- let res = await database.asynchQuery(query);
- for (row of res) {
+ const res = await database.asynchQuery(query);
+ for (const row of res) {
users.push({
id: row.Id,
email: row.Email,
name: row.Name,
admin: row.Admin
- })
+ });
}
-
} catch (err) {
logger.error("DATABASE: Error getting all users");
throw err;
}
return users;
-}
\ No newline at end of file
+};
diff --git a/src/database/user/get_user_by_id.js b/src/database/user/get_user_by_id.js
index c737880..6bd91d6 100644
--- a/src/database/user/get_user_by_id.js
+++ b/src/database/user/get_user_by_id.js
@@ -1,11 +1,12 @@
-var express = require('express');
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.getUserById = async function (id) {
- var query = 'SELECT Id, Email, Name, Admin FROM User WHERE Id = ?';
+ const query = "SELECT Id, Email, Name, Admin FROM User WHERE Id = ?";
let user;
try {
- let res = await database.asynchQuery(query, [id]);
- if (res.length == 0) {
+ const res = await database.asynchQuery(query, [id]);
+ if (res.length === 0) {
user = undefined;
} else {
user = {
@@ -13,11 +14,11 @@ module.exports.getUserById = async function (id) {
email: res[0].Email,
name: res[0].Name,
admin: res[0].Admin
- }
+ };
}
} catch (err) {
- logger.error("DATABASE: Error getting users id: " + id);
+ logger.error(`DATABASE: Error getting users id: ${id}`);
throw err;
}
return user;
-}
\ No newline at end of file
+};
diff --git a/src/database/user/login_user.js b/src/database/user/login_user.js
index 4e6c718..5dfef09 100644
--- a/src/database/user/login_user.js
+++ b/src/database/user/login_user.js
@@ -1,15 +1,16 @@
-var express = require('express');
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.loginUser = async function (user_email, user_password) {
- var query = 'SELECT Id, Email, Name, Admin FROM User WHERE Email = ? AND Password=?';
+ const query = "SELECT Id, Email, Name, Admin FROM User WHERE Email = ? AND Password=?";
let user;
try {
- let res = await database.asynchQuery(query, [
+ const res = await database.asynchQuery(query, [
user_email,
user_password
]);
- if (res.length == 0) {
+ if (res.length === 0) {
user = undefined;
} else {
user = {
@@ -17,12 +18,12 @@ module.exports.loginUser = async function (user_email, user_password) {
email: res[0].Email,
name: res[0].Name,
admin: res[0].Admin
- }
+ };
}
} catch (err) {
- logger.error("DATABASE: Error logging user email: " + user_email);
+ logger.error(`DATABASE: Error logging user email: ${user_email}`);
throw err;
}
return user;
-}
\ No newline at end of file
+};
diff --git a/src/database/user/modify_user.js b/src/database/user/modify_user.js
index 18132d4..5f384e9 100644
--- a/src/database/user/modify_user.js
+++ b/src/database/user/modify_user.js
@@ -1,9 +1,10 @@
-var express = require('express');
+const database = require("../connection");
+const logger = require("../../utils/logger");
module.exports.modifyUserPassword = async function (email, name, admin, id, password) {
let res;
try {
- var query = 'UPDATE User SET Email=?, Name=?, Password=?, Admin=? WHERE Id=?';
+ const query = "UPDATE User SET Email=?, Name=?, Password=?, Admin=? WHERE Id=?";
res = await database.asynchQuery(query, [
email,
name,
@@ -11,18 +12,17 @@ module.exports.modifyUserPassword = async function (email, name, admin, id, pass
admin,
id
]);
-
} catch (err) {
- logger.error("Error modifing password for users id: " + id);
+ logger.error(`Error modifing password for users id: ${id}`);
throw err;
}
return res;
-}
+};
module.exports.modifyUser = async function (email, name, admin, id) {
let res;
try {
- var query = 'UPDATE User SET Email=?, Name=?, Admin=? WHERE Id=?';
+ const query = "UPDATE User SET Email=?, Name=?, Admin=? WHERE Id=?";
res = await database.asynchQuery(query, [
email,
name,
@@ -30,8 +30,8 @@ module.exports.modifyUser = async function (email, name, admin, id) {
id
]);
} catch (err) {
- logger.error("DATABASE: Error modifing users id: " + id);
+ logger.error(`DATABASE: Error modifing users id: ${id}`);
throw err;
}
return res;
-}
\ No newline at end of file
+};
diff --git a/src/package.json b/src/package.json
index 7d2d30e..fceea84 100644
--- a/src/package.json
+++ b/src/package.json
@@ -8,29 +8,22 @@
"start": "node ./app.js"
},
"dependencies": {
- "async": "latest",
- "bluebird": "latest",
- "body-parser": "latest",
- "compression": "latest",
- "connect-flash": "latest",
- "cookie-parser": "latest",
- "debug": "latest",
- "dotenv": "latest",
- "express": "latest",
- "express-device": "latest",
- "express-mysql-session": "latest",
- "express-session": "latest",
- "express-validator": "latest",
- "helmet": "latest",
- "http-errors": "latest",
- "moment": "latest",
- "morgan": "latest",
- "multer": "latest",
- "mysql": "latest",
- "passport": "latest",
- "passport-local": "latest",
- "pug": "latest",
- "uuid": "latest",
- "winston": "latest"
+ "compression": "^1.8.1",
+ "connect-flash": "^0.1.1",
+ "cookie-parser": "^1.4.7",
+ "express": "^5.2.1",
+ "express-mysql-session": "^3.0.3",
+ "express-session": "^1.19.0",
+ "express-validator": "^7.3.2",
+ "helmet": "^8.2.0",
+ "http-errors": "^2.0.1",
+ "moment": "^2.30.1",
+ "multer": "^2.2.0",
+ "mysql": "^2.18.1",
+ "passport": "^0.7.0",
+ "passport-local": "^1.0.0",
+ "pug": "^3.0.4",
+ "uuid": "^14.0.1",
+ "winston": "^3.19.0"
}
}
diff --git a/src/passport/init_passport.js b/src/passport/init_passport.js
index 17e800b..4a23d38 100644
--- a/src/passport/init_passport.js
+++ b/src/passport/init_passport.js
@@ -1,29 +1,31 @@
-var passport = require('passport')
- , LocalStrategy = require('passport-local').Strategy;
+const passport = require("passport");
+const LocalStrategy = require("passport-local").Strategy;
+const crypto = require("crypto");
+const db = require("../database/database");
module.exports = function initPassport() {
//Ritorna un id da un oggetto user
- passport.serializeUser(function (user, done) {
+ passport.serializeUser((user, done) => {
done(null, user.id);
});
//ritorna un user da un id
- passport.deserializeUser(function (id, done) {
+ passport.deserializeUser((id, done) => {
db.getUserById(id).then((user) => {
- return done(null, user)
- })
+ return done(null, user);
+ });
});
//Funzione che controlla se la password è corretta e accetta il login NB username è l'email
- passport.use('login', new LocalStrategy(
- function (username, password, done) {
- let hash = crypto.createHash('sha256');
- db.loginUser(username, hash.update(password).digest('hex')).then((user) => {
- if (user == undefined) {
- return done(null, false, { message: 'Username non Presente o password errata.' });
+ passport.use("login", new LocalStrategy(
+ (username, password, done) => {
+ const hash = crypto.createHash("sha256");
+ db.loginUser(username, hash.update(password).digest("hex")).then((user) => {
+ if (user === undefined) {
+ return done(null, false, { message: "Username non Presente o password errata." });
}
return done(null, user);
- })
+ });
}
));
-};
\ No newline at end of file
+};
diff --git a/src/passport/is_admin.js b/src/passport/is_admin.js
index 93de4b4..359556f 100644
--- a/src/passport/is_admin.js
+++ b/src/passport/is_admin.js
@@ -1,11 +1,8 @@
-var express = require('express');
-
-
module.exports = function ensureAdmin(req, res, next) {
- if (req.user.admin === 'true') {
+ if (req.user.admin === "true") {
next();
} else {
req.flash("info", "Non disponi dei permessi di amministratore.");
res.redirect("/");
}
-};
\ No newline at end of file
+};
diff --git a/src/passport/is_auth.js b/src/passport/is_auth.js
index 4ad3d0f..8663867 100644
--- a/src/passport/is_auth.js
+++ b/src/passport/is_auth.js
@@ -1,6 +1,3 @@
-var express = require('express');
-
-
module.exports = function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
next();
@@ -8,4 +5,4 @@ module.exports = function ensureAuthenticated(req, res, next) {
req.flash("info", "Effettua l'accesso.");
res.redirect("/login");
}
-};
\ No newline at end of file
+};
diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css
index 999ba78..5d3dfe7 100644
--- a/src/public/stylesheets/style.css
+++ b/src/public/stylesheets/style.css
@@ -1,15 +1,72 @@
-.padding-base {
- padding: 40px;
- padding-bottom: 0;
+/* ==========================================================================
+ MeteoServer — design tokens
+ ========================================================================== */
+
+:root {
+ --color-bg: #0f172a;
+ --color-bg-elevated: #16213e;
+ --color-surface: #1b2a4a;
+ --color-surface-alt: #223258;
+ --color-border: rgba(255, 255, 255, 0.08);
+ --color-text: #eef2f8;
+ --color-text-muted: #9aa7c2;
+
+ --color-primary: #2dd4bf;
+ --color-primary-dark: #14b8a6;
+ --color-accent: #38bdf8;
+ --color-success: #34d399;
+ --color-warning: #fbbf24;
+ --color-danger: #f87171;
+
+ --radius-sm: 8px;
+ --radius-md: 14px;
+ --radius-lg: 20px;
+
+ --shadow-md: 0 10px 30px rgba(0, 0, 0, 0.35);
+ --shadow-sm: 0 4px 12px rgba(0, 0, 0, 0.25);
+
+ --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html, body {
+ min-height: 100%;
+}
+
+body {
+ background: radial-gradient(circle at top, #16213e 0%, #0b1120 65%) fixed;
+ color: var(--color-text);
+ font-family: var(--font-sans);
+ -webkit-font-smoothing: antialiased;
}
a {
- color: #00B7FF;
+ color: var(--color-accent);
+ text-decoration: none;
}
-.form-margin {
- margin-left: 10px;
- margin-right: 10px
+a:hover {
+ color: var(--color-primary);
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-weight: 600;
+ letter-spacing: -0.01em;
+}
+
+i {
+ margin-right: 10px;
+}
+
+/* ==========================================================================
+ Layout helpers (kept for backward compatibility with existing templates)
+ ========================================================================== */
+
+.padding-base {
+ padding: 40px 16px 0;
}
.padding-bottom {
@@ -28,14 +85,412 @@ a {
margin-top: 20px;
}
+.form-margin {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
.font-size {
font-size: 100%;
}
-i {
- margin-right: 10px;
+@media (max-width: 576px) {
+ .padding-base {
+ padding: 24px 12px 0;
+ }
+}
+
+/* ==========================================================================
+ Navigation
+ ========================================================================== */
+
+.navbar {
+ height: auto;
+ min-height: 64px;
+ padding: 10px 20px;
+ background: rgba(15, 23, 42, 0.85) !important;
+ backdrop-filter: saturate(180%) blur(14px);
+ border-bottom: 1px solid var(--color-border);
+}
+
+.navbar .navbar-brand img {
+ filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.35));
+}
+
+.navbar .nav-link {
+ color: var(--color-text-muted) !important;
+ font-weight: 500;
+ padding: 8px 14px !important;
+ border-radius: var(--radius-sm);
+ transition: color 0.15s ease, background-color 0.15s ease;
+}
+
+.navbar .nav-link:hover,
+.navbar .nav-item.active .nav-link {
+ color: var(--color-text) !important;
+ background-color: rgba(255, 255, 255, 0.06);
+}
+
+#clock {
+ font-variant-numeric: tabular-nums;
+ color: var(--color-text-muted) !important;
+}
+
+.dropdown-menu {
+ background-color: var(--color-surface);
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-md);
+ box-shadow: var(--shadow-md);
+ padding: 8px;
+}
+
+.dropdown-menu .dropdown-header {
+ color: var(--color-text-muted);
+ font-size: 0.75rem;
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+}
+
+.dropdown-item {
+ color: var(--color-text);
+ border-radius: var(--radius-sm);
+}
+
+.dropdown-item:hover, .dropdown-item:focus {
+ background-color: var(--color-surface-alt);
+ color: var(--color-text);
+}
+
+.dropdown-divider {
+ border-color: var(--color-border);
+}
+
+/* ==========================================================================
+ Buttons & forms
+ ========================================================================== */
+
+.btn {
+ border-radius: var(--radius-sm);
+ font-weight: 600;
+ letter-spacing: 0.01em;
+}
+
+.btn-primary {
+ background-color: var(--color-primary);
+ border-color: var(--color-primary);
+ color: #06251f;
+}
+
+.btn-primary:hover, .btn-primary:focus {
+ background-color: var(--color-primary-dark);
+ border-color: var(--color-primary-dark);
+ color: #06251f;
+}
+
+.btn-danger {
+ background-color: var(--color-danger);
+ border-color: var(--color-danger);
+}
+
+.form-control {
+ background-color: var(--color-bg-elevated);
+ border: 1px solid var(--color-border);
+ color: var(--color-text);
+ border-radius: var(--radius-sm);
+}
+
+.form-control:focus {
+ background-color: var(--color-bg-elevated);
+ color: var(--color-text);
+ border-color: var(--color-primary);
+ box-shadow: 0 0 0 3px rgba(45, 212, 191, 0.25);
+}
+
+.form-control::placeholder {
+ color: var(--color-text-muted);
+}
+
+label {
+ color: var(--color-text-muted);
+ font-weight: 500;
+ margin-bottom: 6px;
+}
+
+/* ==========================================================================
+ Cards / surfaces
+ ========================================================================== */
+
+.card {
+ background-color: var(--color-surface);
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-lg);
+ box-shadow: var(--shadow-sm);
+}
+
+.jumbotron {
+ background-color: var(--color-surface);
+ border-radius: var(--radius-lg);
+ border: 1px solid var(--color-border);
+ color: var(--color-text);
+}
+
+.alert-primary {
+ background-color: rgba(56, 189, 248, 0.12);
+ border: 1px solid rgba(56, 189, 248, 0.35);
+ color: #bfe9fc;
+ border-radius: var(--radius-md);
+}
+
+/* ==========================================================================
+ Tables
+ ========================================================================== */
+
+.table {
+ color: var(--color-text);
+ border-color: var(--color-border);
+}
+
+.table-dark, .table-bordered {
+ background-color: var(--color-surface);
+ border-radius: var(--radius-md);
+ overflow: hidden;
+}
+
+.table thead th {
+ border-bottom-color: var(--color-border);
+}
+
+.table td, .table th {
+ border-color: var(--color-border);
+ vertical-align: middle;
+}
+
+.nav-tabs {
+ border-bottom-color: var(--color-border);
+}
+
+.nav-tabs .nav-link {
+ color: var(--color-text-muted);
+ border-radius: var(--radius-sm) var(--radius-sm) 0 0;
+}
+
+.nav-tabs .nav-link.active {
+ background-color: var(--color-surface);
+ color: var(--color-text);
+ border-color: var(--color-border) var(--color-border) transparent;
+}
+
+/* ==========================================================================
+ Station cards (home page)
+ ========================================================================== */
+
+.station-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
+ gap: 20px;
}
-nav {
- height: 7vh;
-}
\ No newline at end of file
+.station-card {
+ background-color: var(--color-surface);
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-lg);
+ box-shadow: var(--shadow-sm);
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+}
+
+.station-card__header {
+ padding: 16px 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ border-bottom: 1px solid var(--color-border);
+}
+
+.station-card__title {
+ font-size: 1.05rem;
+ font-weight: 600;
+}
+
+.station-card__meta {
+ font-size: 0.85rem;
+ color: var(--color-text-muted);
+}
+
+.status-pill {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ font-size: 0.72rem;
+ font-weight: 700;
+ letter-spacing: 0.05em;
+ text-transform: uppercase;
+ padding: 3px 10px;
+ border-radius: 999px;
+ width: fit-content;
+}
+
+.status-pill::before {
+ content: "";
+ width: 7px;
+ height: 7px;
+ border-radius: 50%;
+ background: currentColor;
+}
+
+.status-pill--online {
+ color: var(--color-success);
+ background: rgba(52, 211, 153, 0.14);
+}
+
+.status-pill--offline {
+ color: var(--color-danger);
+ background: rgba(248, 113, 113, 0.14);
+}
+
+.station-card__section-title {
+ font-size: 0.72rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ color: var(--color-text-muted);
+ padding: 14px 20px 6px;
+}
+
+.station-card__body {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
+ gap: 4px 12px;
+ padding: 0 20px 16px;
+}
+
+.metric {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 6px 0;
+}
+
+.metric i {
+ margin-right: 0;
+ color: var(--color-accent);
+ font-size: 1.1rem;
+ width: 20px;
+ text-align: center;
+ flex-shrink: 0;
+}
+
+.metric__label {
+ color: var(--color-text-muted);
+ font-size: 0.85rem;
+}
+
+.metric__value {
+ font-weight: 600;
+}
+
+.station-card__forecast {
+ margin: 0 20px 18px;
+ padding: 12px 16px;
+ background: var(--color-surface-alt);
+ border-radius: var(--radius-md);
+ font-size: 0.9rem;
+ color: var(--color-text);
+}
+
+.iqa-badge {
+ display: inline-block;
+ padding: 3px 10px;
+ border-radius: 999px;
+ font-size: 0.78rem;
+ font-weight: 700;
+}
+
+.iqa-badge--good { color: var(--color-success); background: rgba(52, 211, 153, 0.14); }
+.iqa-badge--ok { color: var(--color-warning); background: rgba(251, 191, 36, 0.14); }
+.iqa-badge--bad { color: var(--color-danger); background: rgba(248, 113, 113, 0.14); }
+
+/* ==========================================================================
+ Charts (history page)
+ ========================================================================== */
+
+.chart-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
+ gap: 20px;
+}
+
+.chart-grid canvas {
+ width: 100% !important;
+ background-color: var(--color-surface);
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-lg);
+ padding: 12px;
+}
+
+/* ==========================================================================
+ Auth pages
+ ========================================================================== */
+
+.auth-wrapper {
+ min-height: 90vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 24px;
+}
+
+.auth-card {
+ width: 100%;
+ max-width: 380px;
+ background-color: var(--color-surface);
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-lg);
+ box-shadow: var(--shadow-md);
+ padding: 36px 32px;
+ text-align: center;
+}
+
+.auth-card img {
+ max-width: 160px;
+ margin-bottom: 24px;
+}
+
+.auth-card .form-group {
+ text-align: left;
+}
+
+/* ==========================================================================
+ Map
+ ========================================================================== */
+
+#mapid {
+ width: 100%;
+ height: calc(100vh - 64px);
+}
+
+/* ==========================================================================
+ History filter bar
+ ========================================================================== */
+
+.history-toolbar {
+ background-color: var(--color-surface);
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-lg);
+ padding: 18px 20px;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: flex-end;
+ gap: 12px 16px;
+}
+
+.history-toolbar .form-group-inline {
+ display: flex;
+ flex-direction: column;
+ min-width: 160px;
+}
+
+.history-toolbar label {
+ margin-bottom: 6px;
+}
diff --git a/src/routes/api/firmware_update.js b/src/routes/api/firmware_update.js
index 69a991a..0bf95ba 100644
--- a/src/routes/api/firmware_update.js
+++ b/src/routes/api/firmware_update.js
@@ -1,55 +1,53 @@
-var express = require('express');
-var router = express.Router();
-var path = require('path');
-var crypto = require('crypto');
-var fs = require('fs');
-
+const express = require("express");
+const router = express.Router();
+const path = require("path");
+const crypto = require("crypto");
+const fs = require("fs");
+const db = require("../../database/database");
+const logger = require("../../utils/logger");
+const { FIRMWARE_UPDATE_DIR } = require("../../utils/paths");
/* GET update for station. Param station_model will be choosen by the station */
-router.get('/:station_model', function (req, res, next) {
+router.get("/:station_model", (req, res) => {
//Check if request come from an ESP8266
//TODO: PLACE ON THE FOLLOWING IF TOKEN CHECK (AUTH)
- if (req.get('User-Agent') === 'ESP8266-http-Update') {
- var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
+ if (req.get("User-Agent") === "ESP8266-http-Update") {
+ const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
db.queryUpdateAvailable(req.params.station_model).then((station_update_available) => {
//Check if update available and if version is greater than onboard
- if (station_update_available != [] && station_update_available.version > req.get('x-esp8266-version')) {
- let file_path;
- file_path = path.join(WORKING_DIR, 'firmware_update', station_update_available.file_name); //Working dir is declared in app.js
+ if (!Array.isArray(station_update_available) && station_update_available.version > req.get("x-esp8266-version")) {
+ const file_path = path.join(FIRMWARE_UPDATE_DIR, station_update_available.file_name);
//Send file
res.status(200);
res.set({
- 'Content-Type': 'application/octet-stream',
- 'Content-Disposition': 'attachment; filename=update.bin',
- 'Content-Length': fs.statSync(file_path).size,
- 'x-MD5': crypto.createHash('md5').update(fs.readFileSync(file_path)).digest('hex')
+ "Content-Type": "application/octet-stream",
+ "Content-Disposition": "attachment; filename=update.bin",
+ "Content-Length": fs.statSync(file_path).size,
+ "x-MD5": crypto.createHash("md5").update(fs.readFileSync(file_path)).digest("hex")
});
- logger.info('API: firmware update requerst for station\nmodel:' + req.params.station_model + '\nStation IP: ' + ip + '\nUpdate find, sending')
- res.sendFile(file_path, 'update.bin');
+ logger.info(`API: firmware update requerst for station\nmodel:${req.params.station_model}\nStation IP: ${ip}\nUpdate find, sending`);
+ res.sendFile(file_path, "update.bin");
}
//If no update found or onboard version greater
else {
- logger.info('API: firmware update requerst for station\nmodel:' + req.params.station_model + '\nStation IP: ' + ip + '\nFirmware already at last version')
- res.status(500).send('500 No update available');
+ logger.info(`API: firmware update requerst for station\nmodel:${req.params.station_model}\nStation IP: ${ip}\nFirmware already at last version`);
+ res.status(500).send("500 No update available");
}
- }).catch((err) => {
- logger.error("API: Error processing firmware update for station\nmodel: " + req.params.station_model + '\nStation IP: ' + ip)
- res.status(500).json(
- {
- error: {
- //errors: [],
- code: "500",
- message: "Iternal Server Error"
- }
+ }).catch(() => {
+ logger.error(`API: Error processing firmware update for station\nmodel: ${req.params.station_model}\nStation IP: ${ip}`);
+ res.status(500).json({
+ error: {
+ code: "500",
+ message: "Iternal Server Error"
}
- );
+ });
});
}
//If not an ESP8266 Unauthorized
else {
- res.status(403).send('403 Forbidden');
+ res.status(403).send("403 Forbidden");
}
});
diff --git a/src/routes/api/station.js b/src/routes/api/station.js
index b81c827..62011a9 100644
--- a/src/routes/api/station.js
+++ b/src/routes/api/station.js
@@ -1,11 +1,31 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const db = require("../../database/database");
+const logger = require("../../utils/logger");
+
+function getNotFound() {
+ return {
+ error: {
+ code: "404",
+ message: "Station not found"
+ }
+ };
+}
+
+function getServerError() {
+ return {
+ error: {
+ code: "500",
+ message: "Iternal Server Error"
+ }
+ };
+}
//TODO: Validate dates params
/* GET single or all station. */
-router.get('/:station_id', function (req, res, next) {
- var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
+router.get("/:station_id", (req, res) => {
+ const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
if (req.params.station_id) {
//GET HISTORY DATA
if (req.query.date_start && req.query.date_end) {
@@ -15,58 +35,36 @@ router.get('/:station_id', function (req, res, next) {
} else {
res.status(404).json(getNotFound());
}
- }).catch((err) => {
- logger.error('API: Error processing get station history data\nstation id: ' + req.params.station_id + '\nRemote IP: ' + ip);
+ }).catch(() => {
+ logger.error(`API: Error processing get station history data\nstation id: ${req.params.station_id}\nRemote IP: ${ip}`);
res.status(500).json(getServerError());
});
//NO PARAMS -> GET LAST DATA
- } else {
+ } else {
db.querySingleStationLastData(req.params.station_id).then((data) => {
if (data) {
res.status(200).json(data);
} else {
res.status(404).json(getNotFound());
}
- }).catch((err) => {
- logger.error('API: Error processing get station last data\nstation id: ' + req.params.station_id + '\nRemote IP: ' + ip);
+ }).catch(() => {
+ logger.error(`API: Error processing get station last data\nstation id: ${req.params.station_id}\nRemote IP: ${ip}`);
res.status(500).json(getServerError());
});
}
}
-}).get('/', function (req, res, next) {
+}).get("/", (req, res) => {
+ const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
db.listStation().then((data) => {
- if (data != undefined) {
+ if (data !== undefined) {
res.json(data);
} else {
res.json(getNotFound());
}
- }).catch((err) => {
- logger.error('API: Error processing list all station'+ '\nRemote IP: ' + ip);
+ }).catch(() => {
+ logger.error(`API: Error processing list all station\nRemote IP: ${ip}`);
res.json(getServerError());
});
});
-
-function getNotFound() {
- return {
- error: {
- //errors: [],
- code: "404",
- message: "Station not found"
- }
- }
-}
-
-function getServerError() {
- return {
- error: {
- //errors: [],
- code: "500",
- message: "Iternal Server Error"
- }
- }
-}
-
-
module.exports = router;
-
diff --git a/src/routes/api/update.js b/src/routes/api/update.js
index 906d2dc..f4d8352 100644
--- a/src/routes/api/update.js
+++ b/src/routes/api/update.js
@@ -1,52 +1,45 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const db = require("../../database/database");
+const logger = require("../../utils/logger");
/* POST new data from sensor. */
-router.post('/', function (req, res, next) {
- var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
- let data = req.body;
+router.post("/", (req, res) => {
+ const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
+ const data = req.body;
if (!data) {
- logger.error('API: Bad request from station update (no data sended)\nStation IP: ' + ip);
- res.status(400).json(
- {
- error: {
- //errors: [],
- code: "400",
- message: "Bad request"
- }
+ logger.error(`API: Bad request from station update (no data sended)\nStation IP: ${ip}`);
+ res.status(400).json({
+ error: {
+ code: "400",
+ message: "Bad request"
}
- );
+ });
+ return;
}
db.updateStationData(data).then((result) => {
if (result) {
- logger.info("API: New data from station\nModel:" + data.model + '\nStation IP: ' + ip);
- res.status(200).send('ok');
+ logger.info(`API: New data from station\nModel:${data.model}\nStation IP: ${ip}`);
+ res.status(200).send("ok");
} else {
- logger.info("API: Unathorized data update\nData: " + JSON.stringify(data) + '\nStation IP: ' + ip);
- res.status(401).json(
- {
- error: {
- //errors: [],
- code: "401",
- message: "Unhauthorized"
- }
- }
- );
- }
- }).catch((err) => {
- logger.error("API: Error processing station update\nData: " + JSON.stringify(data) + '\nStation IP: ' + ip);
- res.status(500).json(
- {
+ logger.info(`API: Unathorized data update\nData: ${JSON.stringify(data)}\nStation IP: ${ip}`);
+ res.status(401).json({
error: {
- //errors: [],
- code: "500",
- message: "Iternal Server Error"
+ code: "401",
+ message: "Unhauthorized"
}
+ });
+ }
+ }).catch(() => {
+ logger.error(`API: Error processing station update\nData: ${JSON.stringify(data)}\nStation IP: ${ip}`);
+ res.status(500).json({
+ error: {
+ code: "500",
+ message: "Iternal Server Error"
}
- );
+ });
});
-
});
module.exports = router;
diff --git a/src/routes/web/config/configuration.js b/src/routes/web/config/configuration.js
index ab2ea15..1cb9d43 100644
--- a/src/routes/web/config/configuration.js
+++ b/src/routes/web/config/configuration.js
@@ -1,39 +1,36 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const moment = require("moment");
+const db = require("../../../database/database");
+const isAuthenticated = require("../../../passport/is_auth");
+const isAdmin = require("../../../passport/is_admin");
/* GET configuration page. */
-router.get('/', isAuthenticated, isAdmin, function (req, res, next) {
-
- var station;
- var user;
- var update;
-
- async function getData() {
- station = await db.getAllStations();
- user = await db.getAllUsers()
- update = await db.getAllFirmwareUpdates()
- }
-
- getData().then(
- (data) => {
- res.render('./config/configuration', {
- title: 'Meteo Server',
- logged_user: req.user,
- message: req.flash(),
- station: station,
- user: user,
- update: update
- });
- }).catch(
- (err) => {
- req.flash('info', 'Errore');
- res.redirect('/');
- }
- );
+router.get("/", isAuthenticated, isAdmin, (req, res) => {
+ Promise.all([
+ db.getAllStations(),
+ db.getAllUsers(),
+ db.getAllFirmwareUpdates()
+ ]).then(([station, user, update]) => {
+ station.forEach((item) => {
+ item.last_update_formatted = item.last_update ? moment.utc(item.last_update).format("D/M/Y H:mm") : "N/A";
+ });
+ update.forEach((item) => {
+ item.stamp_formatted = moment.utc(item.stamp).format("D/M/Y H:mm");
+ });
+
+ res.render("./config/configuration", {
+ title: "Meteo Server",
+ logged_user: req.user,
+ message: req.flash(),
+ station,
+ user,
+ update
+ });
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/");
+ });
});
-
-
module.exports = router;
-
-
diff --git a/src/routes/web/config/delete_data.js b/src/routes/web/config/delete_data.js
index 3a12067..1e5f855 100644
--- a/src/routes/web/config/delete_data.js
+++ b/src/routes/web/config/delete_data.js
@@ -1,42 +1,33 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const moment = require("moment");
+const db = require("../../../database/database");
+const logger = require("../../../utils/logger");
+const isAuthenticated = require("../../../passport/is_auth");
+const isAdmin = require("../../../passport/is_admin");
/* POST delete data. */
-router.post('/', isAuthenticated, isAdmin, function (req, res, next) {
- let time = moment.utc(req.body.Stamp, "D/M/Y H:mm").format("Y-M-D H:mm");
-
- switch (req.body.Type) {
- case "Temperature":
- db.deleteSingleTemperature(req.body.Id, time);
- break;
-
- case "Humidity":
- db.deleteSingleHumidity(req.body.Id, time);
- break;
-
- case "Pressure":
- db.deleteSinglePressure(req.body.Id, time);
- break;
-
- case "Rain":
- db.deleteSingleRain(req.body.Id, time);
- break;
-
- case "Wind":
- db.deleteSingleWind(req.body.Id, time);
- break;
-
- case "Lighting":
- db.deleteSingleLighting(req.body.Id, time);
- break;
-
- case "AirQuality":
- db.deleteSingleAirQuality(req.body.Id, time);
- break;
+router.post("/", isAuthenticated, isAdmin, (req, res) => {
+ const time = moment.utc(req.body.Stamp, "D/M/Y H:mm").format("Y-M-D H:mm");
+
+ const deleteByType = {
+ Temperature: db.deleteSingleTemperature,
+ Humidity: db.deleteSingleHumidity,
+ Pressure: db.deleteSinglePressure,
+ Rain: db.deleteSingleRain,
+ Wind: db.deleteSingleWind,
+ Lighting: db.deleteSingleLighting,
+ AirQuality: db.deleteSingleAirQuality
+ };
+
+ const deleteFn = deleteByType[req.body.Type];
+ if (deleteFn) {
+ deleteFn(req.body.Id, time).catch((err) => {
+ logger.error(`DATABASE: Error deleting ${req.body.Type} data, message: ${err.message}`);
+ });
}
-
- res.redirect('back');
+ res.redirect("back");
});
module.exports = router;
diff --git a/src/routes/web/config/firmware_update/delete_update.js b/src/routes/web/config/firmware_update/delete_update.js
index b731412..3f80fcc 100644
--- a/src/routes/web/config/firmware_update/delete_update.js
+++ b/src/routes/web/config/firmware_update/delete_update.js
@@ -1,26 +1,31 @@
-var express = require('express');
-var router = express.Router();
-
-var fs = require('fs');
-var path = require('path')
+const express = require("express");
+const router = express.Router();
+const fs = require("fs");
+const path = require("path");
+const db = require("../../../../database/database");
+const logger = require("../../../../utils/logger");
+const isAuthenticated = require("../../../../passport/is_auth");
+const isAdmin = require("../../../../passport/is_admin");
+const { FIRMWARE_UPDATE_DIR } = require("../../../../utils/paths");
/* POST delete update. */
-router.post('/', isAuthenticated, isAdmin, function (req, res, next) {
- var file_path;
- db.queryUpdateById(req.body.Id).then((update) => {
- file_path = path.join(WORKING_DIR, 'firmware_update', update.file_name);
+router.post("/", isAuthenticated, isAdmin, async (req, res) => {
+ try {
+ const update = await db.queryUpdateById(req.body.Id);
+ const file_path = path.join(FIRMWARE_UPDATE_DIR, update.file_name);
try {
fs.unlinkSync(file_path);
} catch (err) {
- logger.error("Error delting firmware update file from server");
+ logger.error("Error deleting firmware update file from server");
}
- }).then(db.deleteFirmwareUpdate(req.body.Id)).then((result) => {
- req.flash('info', 'Aggiornamento cancellato');
- res.redirect('/config/configuration');
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/config/configuration');
- });
+
+ await db.deleteFirmwareUpdate(req.body.Id);
+ req.flash("info", "Aggiornamento cancellato");
+ res.redirect("/config/configuration");
+ } catch (err) {
+ req.flash("info", "Errore");
+ res.redirect("/config/configuration");
+ }
});
-module.exports = router;
\ No newline at end of file
+module.exports = router;
diff --git a/src/routes/web/config/firmware_update/new_update.js b/src/routes/web/config/firmware_update/new_update.js
index 7b036a8..cb1b111 100644
--- a/src/routes/web/config/firmware_update/new_update.js
+++ b/src/routes/web/config/firmware_update/new_update.js
@@ -1,49 +1,51 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const fs = require("fs");
+const path = require("path");
+const multer = require("multer");
+const { check, validationResult } = require("express-validator");
+const db = require("../../../../database/database");
+const logger = require("../../../../utils/logger");
+const isAuthenticated = require("../../../../passport/is_auth");
+const isAdmin = require("../../../../passport/is_admin");
+const { FIRMWARE_UPDATE_DIR } = require("../../../../utils/paths");
-var fs = require('fs');
-var path = require('path');
-const { check, validationResult } = require('express-validator/check');
-
-var file_name;
-
-var multer = require('multer');
-var storage = multer.diskStorage({
+const storage = multer.diskStorage({
destination: (req, file, cb) => {
- return cb(null, path.join(WORKING_DIR, 'firmware_update'));
+ return cb(null, FIRMWARE_UPDATE_DIR);
},
filename: (req, file, cb) => {
- file_name = req.body.Model + '_' + Date.now() + '.bin';
+ const file_name = `${req.body.Model}_${Date.now()}.bin`;
return cb(null, file_name);
}
});
-var upload = multer({ storage: storage });
+const upload = multer({ storage });
/* POST new update. */
-router.post('/', isAuthenticated, isAdmin, upload.single('File'), [
- check('Model').exists().withMessage('Inserisci un Modello'),
- check('Version').exists().isLength({ min: 5, max: 5 })/*.matches('/([0-1]\.[0-1]\.[0-1])/')*/.withMessage('Inserisci una Versione'),
+router.post("/", isAuthenticated, isAdmin, upload.single("File"), [
+ check("Model").exists().withMessage("Inserisci un Modello"),
+ check("Version").exists().isLength({ min: 5, max: 5 }).withMessage("Inserisci una Versione")
],
- function (req, res, next) {
+ (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
- req.flash('info', errors.array()[0].msg);
+ req.flash("info", errors.array()[0].msg);
try {
- fs.unlinkSync(path.join(WORKING_DIR, 'firmware_update', file_name));
+ fs.unlinkSync(path.join(FIRMWARE_UPDATE_DIR, req.file.filename));
} catch (err) {
logger.error("Error saving firmware update file to server");
}
- return res.redirect('/config/configuration');
+ return res.redirect("/config/configuration");
}
- db.createFirmwareUpdate(req.body.Model, req.body.Version, file_name).then((result) => {
- req.flash('info', 'Aggiornamento creato');
- res.redirect('/config/configuration');
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/config/configuration');
- })
+ db.createFirmwareUpdate(req.body.Model, req.body.Version, req.file.filename).then(() => {
+ req.flash("info", "Aggiornamento creato");
+ res.redirect("/config/configuration");
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/config/configuration");
+ });
});
module.exports = router;
diff --git a/src/routes/web/config/station/delete_station.js b/src/routes/web/config/station/delete_station.js
index ae8d1da..44588a3 100644
--- a/src/routes/web/config/station/delete_station.js
+++ b/src/routes/web/config/station/delete_station.js
@@ -1,14 +1,17 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const db = require("../../../../database/database");
+const isAuthenticated = require("../../../../passport/is_auth");
+const isAdmin = require("../../../../passport/is_admin");
/* POST delete station. */
-router.post('/', isAuthenticated, isAdmin, function (req, res, next) {
- db.deleteStation(req.body.Id).then((result) => {
- req.flash('info', 'Stazione eliminata');
- res.redirect('/config/configuration');
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/config/configuration');
+router.post("/", isAuthenticated, isAdmin, (req, res) => {
+ db.deleteStation(req.body.Id).then(() => {
+ req.flash("info", "Stazione eliminata");
+ res.redirect("/config/configuration");
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/config/configuration");
});
});
diff --git a/src/routes/web/config/station/modify_station.js b/src/routes/web/config/station/modify_station.js
index 3be9919..541eebf 100644
--- a/src/routes/web/config/station/modify_station.js
+++ b/src/routes/web/config/station/modify_station.js
@@ -1,29 +1,30 @@
-var express = require('express');
-var router = express.Router();
-
-const { check, validationResult } = require('express-validator/check');
-const { matchedData, sanitize } = require('express-validator/filter');
+const express = require("express");
+const router = express.Router();
+const { check, validationResult } = require("express-validator");
+const db = require("../../../../database/database");
+const isAuthenticated = require("../../../../passport/is_auth");
+const isAdmin = require("../../../../passport/is_admin");
/* GET configuration page. */
-router.post('/', isAuthenticated, isAdmin, [
- check('ModifyStationName').exists().withMessage('Inserisci un nome'),
- check('ModifyLocation').exists().withMessage('Inserisci un luogo'),
- check('ModifyLatitude').exists().isFloat().withMessage('Inserisci una latitudine'),
- check('ModifyLongitude').exists().isFloat().withMessage('Inserisci un longitudine'),
- check('ModifyAltitude').exists().isInt().withMessage('Inserisci una altitudine')
-], function (req, res, next) {
+router.post("/", isAuthenticated, isAdmin, [
+ check("ModifyStationName").exists().withMessage("Inserisci un nome"),
+ check("ModifyLocation").exists().withMessage("Inserisci un luogo"),
+ check("ModifyLatitude").exists().isFloat().withMessage("Inserisci una latitudine"),
+ check("ModifyLongitude").exists().isFloat().withMessage("Inserisci un longitudine"),
+ check("ModifyAltitude").exists().isInt().withMessage("Inserisci una altitudine")
+], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
- req.flash('info', errors.array()[0].msg);
- return res.redirect('/config/configuration');
+ req.flash("info", errors.array()[0].msg);
+ return res.redirect("/config/configuration");
}
- db.modifyStation(req.body.ModifyStationName, req.body.ModifyLocation, req.body.ModifyLatitude, req.body.ModifyLongitude, req.body.ModifyAltitude, req.body.ModifyId).then((result) => {
- req.flash('info', 'Stazione modificata');
- res.redirect('/config/configuration');
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/config/configuration');
+ db.modifyStation(req.body.ModifyStationName, req.body.ModifyLocation, req.body.ModifyLatitude, req.body.ModifyLongitude, req.body.ModifyAltitude, req.body.ModifyId).then(() => {
+ req.flash("info", "Stazione modificata");
+ res.redirect("/config/configuration");
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/config/configuration");
});
});
diff --git a/src/routes/web/config/station/new_station.js b/src/routes/web/config/station/new_station.js
index e3876f3..f0850d3 100644
--- a/src/routes/web/config/station/new_station.js
+++ b/src/routes/web/config/station/new_station.js
@@ -1,30 +1,31 @@
-var express = require('express');
-var router = express.Router();
-
-const { check, validationResult } = require('express-validator/check');
-const { matchedData, sanitize } = require('express-validator/filter');
+const express = require("express");
+const router = express.Router();
+const { check, validationResult } = require("express-validator");
+const db = require("../../../../database/database");
+const isAuthenticated = require("../../../../passport/is_auth");
+const isAdmin = require("../../../../passport/is_admin");
/* POST new station. */
-router.post('/', isAuthenticated, isAdmin, [
- check('StationName').exists().withMessage('Inserisci un nome'),
- check('Location').exists().withMessage('Inserisci un luogo'),
- check('Latitude').exists().isFloat().withMessage('Inserisci una latitudine'),
- check('Longitude').exists().isFloat().withMessage('Inserisci un longitudine'),
- check('Altitude').exists().isInt().withMessage('Inserisci una altitudine')
-], function (req, res, next) {
+router.post("/", isAuthenticated, isAdmin, [
+ check("StationName").exists().withMessage("Inserisci un nome"),
+ check("Location").exists().withMessage("Inserisci un luogo"),
+ check("Latitude").exists().isFloat().withMessage("Inserisci una latitudine"),
+ check("Longitude").exists().isFloat().withMessage("Inserisci un longitudine"),
+ check("Altitude").exists().isInt().withMessage("Inserisci una altitudine")
+], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
- req.flash('info', errors.array()[0].msg);
- return res.redirect('/config/configuration');
+ req.flash("info", errors.array()[0].msg);
+ return res.redirect("/config/configuration");
}
- db.createStation(req.body.StationName, req.body.Location, req.body.Latitude, req.body.Longitude, req.body.Altitude).then((result) => {
- req.flash('info', 'Stazione creata');
- res.redirect('/config/configuration');
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/config/configuration');
+ db.createStation(req.body.StationName, req.body.Location, req.body.Latitude, req.body.Longitude, req.body.Altitude).then(() => {
+ req.flash("info", "Stazione creata");
+ res.redirect("/config/configuration");
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/config/configuration");
});
});
-module.exports = router;
+module.exports = router;
diff --git a/src/routes/web/history.js b/src/routes/web/history.js
index 597ba60..3705708 100644
--- a/src/routes/web/history.js
+++ b/src/routes/web/history.js
@@ -1,87 +1,55 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const moment = require("moment");
+const db = require("../../database/database");
+const isAuthenticated = require("../../passport/is_auth");
/* GET history page. */
-router.get('/', isAuthenticated, function (req, res, next) {
+router.get("/", isAuthenticated, (req, res) => {
//Check for empty date - limit result to current day
- let date_start;
- if (req.query.date_start) {
- date_start = req.query.date_start;
- } else {
- date_start = moment.utc().startOf('day').format("Y-M-D H:mm");
- }
-
- let date_end;
- if (req.query.date_end) {
- date_end = req.query.date_end;
- } else {
- date_end = moment.utc().format("Y-M-D H:mm");
- }
+ const date_start = req.query.date_start || moment.utc().startOf("day").format("Y-M-D H:mm");
+ const date_end = req.query.date_end || moment.utc().format("Y-M-D H:mm");
//Elenco stazioni per menu selezione
- db.listStation().then((rows) => {
- let station = rows;
-
+ db.listStation().then((station) => {
//A station is selected
- if (req.query.station_id && !(req.query.station_id === '0')) {
+ if (req.query.station_id && req.query.station_id !== "0") {
db.queryHistoryStationData(req.query.station_id, date_start, date_end).then((data) => {
- if (req.device.type === "phone") {
- res.render('mobile/history/m_chart', {
- title: 'Meteo Server',
+ if (req.query.type === "1") {
+ res.render("history/table", {
+ title: "Meteo Server",
logged_user: req.user,
- type: 0,
- data: data,
- station: station,
- date_start: date_start,
- date_end: date_end
+ type: 1,
+ data,
+ station,
+ date_start,
+ date_end
});
- } else if (req.query.type === "0") {
- res.render('history/chart', {
- title: 'Meteo Server',
+ } else {
+ res.render("history/chart", {
+ title: "Meteo Server",
logged_user: req.user,
type: 0,
- data: data,
- station: station,
- date_start: date_start,
- date_end: date_end
- });
- } else if (req.query.type === "1") {
- res.render('history/table', {
- title: 'Meteo Server',
- logged_user: req.user,
- type: 1,
- data: data,
- station: station,
- date_start: date_start,
- date_end: date_end
+ data,
+ station,
+ date_start,
+ date_end
});
}
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/');
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/");
});
-
} else { //Se non è selezionata una stazione non visualizzare niente
- if (req.device.type === "phone") {
- res.render('mobile/history/m_history', {
- title: 'Meteo Server',
- logged_user: req.user,
- message: req.flash(),
- station: station,
- date_start: date_start,
- date_end: date_end
- });
- } else {
- res.render('history/history', {
- title: 'Meteo Server',
- logged_user: req.user,
- message: req.flash(),
- station: station,
- date_start: date_start,
- date_end: date_end
- });
- }
+ res.render("history/history", {
+ title: "Meteo Server",
+ logged_user: req.user,
+ message: req.flash(),
+ station,
+ date_start,
+ date_end
+ });
}
});
});
diff --git a/src/routes/web/index.js b/src/routes/web/index.js
index f5974f5..e95b239 100644
--- a/src/routes/web/index.js
+++ b/src/routes/web/index.js
@@ -1,29 +1,23 @@
-var express = require('express');
-var router = express.Router();
-
+const express = require("express");
+const router = express.Router();
+const db = require("../../database/database");
+const dateConvert = require("../../utils/date_convert");
/* GET home page. */
-router.get('/', function (req, res, next) {
- //Execute the async function
+router.get("/", (req, res) => {
db.queryLastDataFromAllStation().then((data) => {
- if (req.device.type === "phone") {
- res.render('mobile/m_index', {
- title: 'Meteo Server',
- logged_user: req.user,
- message: req.flash(),
- data: data
- });
- } else {
- res.render('index', {
- title: 'Meteo Server',
- logged_user: req.user,
- message: req.flash(),
- data: data
- });
- }
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/');
+ data.forEach((item) => {
+ item.online = dateConvert.checkOnline(item.last_update);
+ });
+ res.render("index", {
+ title: "Meteo Server",
+ logged_user: req.user,
+ message: req.flash(),
+ data
+ });
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/");
});
});
diff --git a/src/routes/web/map.js b/src/routes/web/map.js
index 01c003f..c741770 100644
--- a/src/routes/web/map.js
+++ b/src/routes/web/map.js
@@ -1,28 +1,22 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const db = require("../../database/database");
+const isAuthenticated = require("../../passport/is_auth");
/* GET map page. */
-router.get('/', isAuthenticated, function (req, res, next) {
+router.get("/", isAuthenticated, (req, res) => {
db.queryLastDataFromAllStation().then((data) => {
- if (req.device.type === "phone") {
- res.render('mobile/m_map', {
- title: 'Meteo Server',
- stations_data: JSON.stringify(data),
- logged_user: req.user,
- message: req.flash(),
- });
- } else {
- res.render('map', {
- title: 'Meteo Server',
- stations_data: JSON.stringify(data),
- logged_user: req.user,
- message: req.flash(),
- });
- }
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/');
+ res.render("map", {
+ title: "Meteo Server",
+ stations_data: JSON.stringify(data),
+ mapbox_token: process.env.MAPBOX_TOKEN,
+ logged_user: req.user,
+ message: req.flash()
+ });
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/");
});
});
diff --git a/src/routes/web/station.js b/src/routes/web/station.js
index ccc1648..5781025 100644
--- a/src/routes/web/station.js
+++ b/src/routes/web/station.js
@@ -1,21 +1,25 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const db = require("../../database/database");
/* GET single or all station. */
-router.get('/:station_id', function (req, res, next) {
+router.get("/:station_id", (req, res) => {
//Execute the async function
- if (req.params.station_id != undefined) {
+ if (req.params.station_id !== undefined) {
db.querySingleStationLastData(req.params.station_id).then((data) => {
- if (data) res.render('station', {
- title: 'Meteo Server',
- logged_user: req.user,
- message: req.flash(),
- data: data
- });
- else res.redirect("/");
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/');
+ if (data) {
+ res.render("station", {
+ title: "Meteo Server",
+ logged_user: req.user,
+ message: req.flash(),
+ data
+ });
+ } else {
+ res.redirect("/");
+ }
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/");
});
} else {
res.redirect("/");
diff --git a/src/routes/web/user/delete_user.js b/src/routes/web/user/delete_user.js
index 2fc40be..6623ff2 100644
--- a/src/routes/web/user/delete_user.js
+++ b/src/routes/web/user/delete_user.js
@@ -1,22 +1,21 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const db = require("../../../database/database");
+const isAuthenticated = require("../../../passport/is_auth");
/* POST delete user. */
-router.post('/', isAuthenticated, function (req, res, next) {
- if (!(parseInt(req.user.Id) === parseInt(req.body.UserId))) {
- db.deleteUser(req.body.UserId).then((result) => {
- req.flash('info', 'Utente cancellato');
- res.redirect('/config/configuration');
- }).catch(
- (err) => {
- req.flash('info', 'Errore');
- res.redirect('/config/configuration');
- }
- )
-
+router.post("/", isAuthenticated, (req, res) => {
+ if (parseInt(req.user.Id) !== parseInt(req.body.UserId)) {
+ db.deleteUser(req.body.UserId).then(() => {
+ req.flash("info", "Utente cancellato");
+ res.redirect("/config/configuration");
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/config/configuration");
+ });
} else {
- req.flash('info', 'Impossibile cancellare l\'utente loggato');
- res.redirect('/config/configuration');
+ req.flash("info", "Impossibile cancellare l'utente loggato");
+ res.redirect("/config/configuration");
}
});
diff --git a/src/routes/web/user/login.js b/src/routes/web/user/login.js
index faa8d09..aac4ffb 100644
--- a/src/routes/web/user/login.js
+++ b/src/routes/web/user/login.js
@@ -1,35 +1,26 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const passport = require("passport");
-router.get("/", function (req, res) {
+router.get("/", (req, res) => {
if (req.isAuthenticated()) {
- res.redirect('/')
- }
- else {
- if (req.device.type === "phone") {
- res.render('mobile/m_login', {
- title: 'Meteo Server',
- logged_user: req.user,
- message: req.flash()
- });
- } else {
- res.render('login', {
- title: 'Meteo Server',
- logged_user: req.user,
- message: req.flash()
- });
- }
-
+ res.redirect("/");
+ } else {
+ res.render("login", {
+ title: "Meteo Server",
+ logged_user: req.user,
+ message: req.flash()
+ });
}
});
//Dati inviati per effettuare il login
-router.post('/',
- passport.authenticate('login', {
- successRedirect: '/',
- failureRedirect: '/login',
+router.post("/",
+ passport.authenticate("login", {
+ successRedirect: "/",
+ failureRedirect: "/login",
failureFlash: true
})
);
-module.exports = router;
\ No newline at end of file
+module.exports = router;
diff --git a/src/routes/web/user/logout.js b/src/routes/web/user/logout.js
index 577eb24..b50f1dd 100644
--- a/src/routes/web/user/logout.js
+++ b/src/routes/web/user/logout.js
@@ -1,9 +1,11 @@
-var express = require('express');
-var router = express.Router();
+const express = require("express");
+const router = express.Router();
+const isAuthenticated = require("../../../passport/is_auth");
-router.get("/", isAuthenticated, function (req, res) {
- req.logout();
- res.redirect("/");
+router.get("/", isAuthenticated, (req, res) => {
+ req.logout(() => {
+ res.redirect("/");
+ });
});
-module.exports = router;
\ No newline at end of file
+module.exports = router;
diff --git a/src/routes/web/user/modify_user.js b/src/routes/web/user/modify_user.js
index 5b800be..06f23de 100644
--- a/src/routes/web/user/modify_user.js
+++ b/src/routes/web/user/modify_user.js
@@ -1,48 +1,49 @@
-var express = require('express');
-var router = express.Router();
-
-const { check, validationResult } = require('express-validator/check');
-const { matchedData, sanitize } = require('express-validator/filter');
+const express = require("express");
+const router = express.Router();
+const crypto = require("crypto");
+const { check, validationResult } = require("express-validator");
+const db = require("../../../database/database");
+const isAuthenticated = require("../../../passport/is_auth");
/* POST modify user. */
-router.post('/', isAuthenticated, [
- check('ModifyUserEmail').exists().isEmail().withMessage('Inserisci una mail valida'),
- check('ModifyUserName').exists().withMessage('Inserisci un nome utente')
-], function (req, res, next) {
+router.post("/", isAuthenticated, [
+ check("ModifyUserEmail").exists().isEmail().withMessage("Inserisci una mail valida"),
+ check("ModifyUserName").exists().withMessage("Inserisci un nome utente")
+], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
- req.flash('info', errors.array()[0].msg);
- return res.redirect('/config/configuration');
+ req.flash("info", errors.array()[0].msg);
+ return res.redirect("/config/configuration");
}
- var admin_on = 'false';
- if (req.body.ModifyUserAdmin === 'on') {
- admin_on = 'true';
+ let admin_on = "false";
+ if (req.body.ModifyUserAdmin === "on") {
+ admin_on = "true";
}
if (req.body.ModifyUserPassword !== "") {
if (req.body.ModifyUserPassword === req.body.ModifyUserPasswordConfirm) {
- let hash = crypto.createHash('sha256');
- db.modifyUserPassword(req.body.ModifyUserEmail, req.body.ModifyUserName, admin_on, req.body.ModifyUserId, hash.update(req.body.ModifyUserPassword).digest('hex')).then((result) => {
- req.flash('info', 'Password Modificata');
- res.redirect('/config/configuration');
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/config/configuration');
- })
+ const hash = crypto.createHash("sha256");
+ db.modifyUserPassword(req.body.ModifyUserEmail, req.body.ModifyUserName, admin_on, req.body.ModifyUserId, hash.update(req.body.ModifyUserPassword).digest("hex")).then(() => {
+ req.flash("info", "Password Modificata");
+ res.redirect("/config/configuration");
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/config/configuration");
+ });
} else {
- req.flash('info', 'Le password non corrispondono');
- res.redirect('/config/configuration');
+ req.flash("info", "Le password non corrispondono");
+ res.redirect("/config/configuration");
}
} else {
- db.modifyUser(req.body.ModifyUserEmail, req.body.ModifyUserName, admin_on, req.body.ModifyUserId).then((res) => {
- req.flash('info', 'Utente Modificato');
- res.redirect('/config/configuration');
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/config/configuration');
- })
+ db.modifyUser(req.body.ModifyUserEmail, req.body.ModifyUserName, admin_on, req.body.ModifyUserId).then(() => {
+ req.flash("info", "Utente Modificato");
+ res.redirect("/config/configuration");
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/config/configuration");
+ });
}
});
diff --git a/src/routes/web/user/new_user.js b/src/routes/web/user/new_user.js
index 94215dd..5405d19 100644
--- a/src/routes/web/user/new_user.js
+++ b/src/routes/web/user/new_user.js
@@ -1,42 +1,40 @@
-var express = require('express');
-var router = express.Router();
-
-const { check, validationResult } = require('express-validator/check');
-const { matchedData, sanitize } = require('express-validator/filter');
-
+const express = require("express");
+const router = express.Router();
+const crypto = require("crypto");
+const { check, validationResult } = require("express-validator");
+const db = require("../../../database/database");
+const isAuthenticated = require("../../../passport/is_auth");
/* POST new user. */
-router.post('/', isAuthenticated, [
- check('Email').isEmail().withMessage('Inserisci una mail valida'),
- check('Name').exists(),
- check('Password').exists().isLength({ min: 5 }).withMessage('La password deve essere lunga almeno 5 caratteri')
-], function (req, res, next) {
+router.post("/", isAuthenticated, [
+ check("Email").isEmail().withMessage("Inserisci una mail valida"),
+ check("Name").exists(),
+ check("Password").exists().isLength({ min: 5 }).withMessage("La password deve essere lunga almeno 5 caratteri")
+], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
- req.flash('info', errors.array()[0].msg);
- return res.redirect('/config/configuration');
+ req.flash("info", errors.array()[0].msg);
+ return res.redirect("/config/configuration");
}
if (req.body.Password === req.body.PasswordConfirm) {
- var admin_on = 'false';
- if (req.body.Admin === 'on') {
- admin_on = 'true';
+ let admin_on = "false";
+ if (req.body.Admin === "on") {
+ admin_on = "true";
}
- let hash = crypto.createHash('sha256');
- db.createUser(req.body.Email, req.body.Name, hash.update(req.body.Password).digest('hex'), admin_on).then((result) => {
- req.flash('info', 'Utente creato');
- res.redirect('/config/configuration');
- }).catch((err) => {
- req.flash('info', 'Errore');
- res.redirect('/config/configuration');
- })
+ const hash = crypto.createHash("sha256");
+ db.createUser(req.body.Email, req.body.Name, hash.update(req.body.Password).digest("hex"), admin_on).then(() => {
+ req.flash("info", "Utente creato");
+ res.redirect("/config/configuration");
+ }).catch(() => {
+ req.flash("info", "Errore");
+ res.redirect("/config/configuration");
+ });
} else {
- req.flash('info', 'Le password non corrispondono');
- res.redirect('/config/configuration');
+ req.flash("info", "Le password non corrispondono");
+ res.redirect("/config/configuration");
}
+});
-}
-);
-
-module.exports = router;
\ No newline at end of file
+module.exports = router;
diff --git a/src/utils/date_convert.js b/src/utils/date_convert.js
index fa220f6..192c6f2 100644
--- a/src/utils/date_convert.js
+++ b/src/utils/date_convert.js
@@ -1,10 +1,9 @@
-var express = require('express');
+const moment = require("moment");
function checkOnline(d) {
- now = moment.utc()
- last_update = moment.utc(d, "D/M/Y H:mm")
- online = now.diff(last_update) <= 60 * 1000 * 60 * 2
- return online;
+ const now = moment.utc();
+ const last_update = moment.utc(d, "D/M/Y H:mm");
+ return now.diff(last_update) <= 60 * 1000 * 60 * 2;
}
module.exports.checkOnline = checkOnline;
diff --git a/src/utils/forecast.js b/src/utils/forecast.js
index 18823ad..24369d1 100644
--- a/src/utils/forecast.js
+++ b/src/utils/forecast.js
@@ -1,10 +1,8 @@
-express = require('express');
-
// ---- 'environment' variables ------------
-var z_where = 1; // Northern = 1 or Southern = 2 hemisphere
-var z_baro_top = 1050; // upper limits of your local 'weather window' (1050.0 hPa for UK)
-var z_baro_bottom = 950; // lower limits of your local 'weather window' (950.0 hPa for UK)
-let z_month = new Date().getMonth()
+let z_where = 1; // Northern = 1 or Southern = 2 hemisphere
+let z_baro_top = 1050; // upper limits of your local 'weather window' (1050.0 hPa for UK)
+let z_baro_bottom = 950; // lower limits of your local 'weather window' (950.0 hPa for UK)
+const z_month = new Date().getMonth();
// usage: forecast = forecast( z_hpa, z_month, z_wind, z_trend [, z_where] [, z_baro_top] [, z_baro_bottom])[0];
// z_hpa is Sea Level Adjusted (Relative) barometer in hPa or mB
@@ -20,124 +18,124 @@ let z_month = new Date().getMonth()
//Settled = stabile (sole) Unsettled = instabile (piogge)
-var z_forecast = new Array("Settled fine", "Fine weather", "Becoming fine", "Fine, becoming less settled", "Fine, possible showers", "Fairly fine, improving", "Fairly fine, possible showers early", "Fairly fine, showery later", "Showery early, improving", "Changeable, mending", "Fairly fine, showers likely", "Rather unsettled clearing later", "Unsettled, probably improving", "Showery, bright intervals", "Showery, becoming less settled", "Changeable, some rain", "Unsettled, short fine intervals", "Unsettled, rain later", "Unsettled, some rain", "Mostly very unsettled", "Occasional rain, worsening", "Rain at times, very unsettled", "Rain at frequent intervals", "Rain, very unsettled", "Stormy, may improve", "Stormy, much rain");
-var z_forecast_italian = new Array("Bel tempo stabile", "Bel tempo", "Bel tempo in arrivo", "Bel tempo, instabile", "Bel tempo, possibili piogge", "Abbastanza bello, in miglioramento", "Abbastanza bello, possibili piogge a breve", "Abbastanza bello, possibili piogge più tardi", "Piogge a breve, poi miglioramento", "Instabile", "Abbastanza bello, possibili piogge", "Piuttosto instabile, schiarite più tardi", "Instabile, possibile miglioramento", "Pioggia alternatata a schiarite", "Piogge, instabile", "Variabile, possibili piogge", "Instabile, brevi periodi di bel tempo", "Instabile, pioggia più tardi", "Instabile, possibili piogge", "Instabile", "Pioggia a tratti, in peggioramento", "Pioggia a tratti, molto instabile", "Pioggia a intervalli ravvicinati", "Pioggia, molto instabile", "Temporale, possibile miglioramento", "Temporale intenso");
+const z_forecast = ["Settled fine", "Fine weather", "Becoming fine", "Fine, becoming less settled", "Fine, possible showers", "Fairly fine, improving", "Fairly fine, possible showers early", "Fairly fine, showery later", "Showery early, improving", "Changeable, mending", "Fairly fine, showers likely", "Rather unsettled clearing later", "Unsettled, probably improving", "Showery, bright intervals", "Showery, becoming less settled", "Changeable, some rain", "Unsettled, short fine intervals", "Unsettled, rain later", "Unsettled, some rain", "Mostly very unsettled", "Occasional rain, worsening", "Rain at times, very unsettled", "Rain at frequent intervals", "Rain, very unsettled", "Stormy, may improve", "Stormy, much rain"];
+const z_forecast_italian = ["Bel tempo stabile", "Bel tempo", "Bel tempo in arrivo", "Bel tempo, instabile", "Bel tempo, possibili piogge", "Abbastanza bello, in miglioramento", "Abbastanza bello, possibili piogge a breve", "Abbastanza bello, possibili piogge più tardi", "Piogge a breve, poi miglioramento", "Instabile", "Abbastanza bello, possibili piogge", "Piuttosto instabile, schiarite più tardi", "Instabile, possibile miglioramento", "Pioggia alternatata a schiarite", "Piogge, instabile", "Variabile, possibili piogge", "Instabile, brevi periodi di bel tempo", "Instabile, pioggia più tardi", "Instabile, possibili piogge", "Instabile", "Pioggia a tratti, in peggioramento", "Pioggia a tratti, molto instabile", "Pioggia a intervalli ravvicinati", "Pioggia, molto instabile", "Temporale, possibile miglioramento", "Temporale intenso"];
// equivalents of Zambretti 'dial window' letters A - Z
-var rise_options = new Array(25, 25, 25, 24, 24, 19, 16, 12, 11, 9, 8, 6, 5, 2, 1, 1, 0, 0, 0, 0, 0, 0);
-var steady_options = new Array(25, 25, 25, 25, 25, 25, 23, 23, 22, 18, 15, 13, 10, 4, 1, 1, 0, 0, 0, 0, 0, 0);
-var fall_options = new Array(25, 25, 25, 25, 25, 25, 25, 25, 23, 23, 21, 20, 17, 14, 7, 3, 1, 1, 1, 0, 0, 0);
+const rise_options = [25, 25, 25, 24, 24, 19, 16, 12, 11, 9, 8, 6, 5, 2, 1, 1, 0, 0, 0, 0, 0, 0];
+const steady_options = [25, 25, 25, 25, 25, 25, 23, 23, 22, 18, 15, 13, 10, 4, 1, 1, 0, 0, 0, 0, 0, 0];
+const fall_options = [25, 25, 25, 25, 25, 25, 25, 25, 23, 23, 21, 20, 17, 14, 7, 3, 1, 1, 1, 0, 0, 0];
// ---- MAIN FUNCTION --------------------------------------------------
function forecast(z_hpa, z_wind, z_trend, z_hemisphere, z_upper, z_lower) {
- var z_test = {
+ const z_test = {
zambretti_number: -1,
forecast_phrase: "",
forecast_phrase_it: ""
- }
+ };
if (z_hemisphere) z_where = z_hemisphere; // used by input form
if (z_upper) z_baro_top = z_upper; // used by input form
if (z_lower) z_baro_bottom = z_lower; // used by input form
- z_range = z_baro_top - z_baro_bottom;
- z_constant = (z_range / 22).toFixed(3);
+ const z_range = z_baro_top - z_baro_bottom;
+ const z_constant = (z_range / 22).toFixed(3);
- z_season = (z_month >= 4 && z_month <= 9); // true if 'Summer'
- if (z_where == 1) { // North hemisphere
- if (z_wind == "N") {
+ const z_season = (z_month >= 4 && z_month <= 9); // true if 'Summer'
+ if (z_where === 1) { // North hemisphere
+ if (z_wind === "N") {
z_hpa += 6 / 100 * z_range;
- } else if (z_wind == "NNE") {
+ } else if (z_wind === "NNE") {
z_hpa += 5 / 100 * z_range;
- } else if (z_wind == "NE") {
- // z_hpa += 4 ;
+ } else if (z_wind === "NE") {
+ // z_hpa += 4 ;
z_hpa += 5 / 100 * z_range;
- } else if (z_wind == "ENE") {
+ } else if (z_wind === "ENE") {
z_hpa += 2 / 100 * z_range;
- } else if (z_wind == "E") {
+ } else if (z_wind === "E") {
z_hpa -= 0.5 / 100 * z_range;
- } else if (z_wind == "ESE") {
- // z_hpa -= 3 ;
+ } else if (z_wind === "ESE") {
+ // z_hpa -= 3 ;
z_hpa -= 2 / 100 * z_range;
- } else if (z_wind == "SE") {
+ } else if (z_wind === "SE") {
z_hpa -= 5 / 100 * z_range;
- } else if (z_wind == "SSE") {
+ } else if (z_wind === "SSE") {
z_hpa -= 8.5 / 100 * z_range;
- } else if (z_wind == "S") {
- // z_hpa -= 11 ;
+ } else if (z_wind === "S") {
+ // z_hpa -= 11 ;
z_hpa -= 12 / 100 * z_range;
- } else if (z_wind == "SSW") {
+ } else if (z_wind === "SSW") {
z_hpa -= 10 / 100 * z_range; //
- } else if (z_wind == "SW") {
+ } else if (z_wind === "SW") {
z_hpa -= 6 / 100 * z_range;
- } else if (z_wind == "WSW") {
+ } else if (z_wind === "WSW") {
z_hpa -= 4.5 / 100 * z_range; //
- } else if (z_wind == "W") {
+ } else if (z_wind === "W") {
z_hpa -= 3 / 100 * z_range;
- } else if (z_wind == "WNW") {
+ } else if (z_wind === "WNW") {
z_hpa -= 0.5 / 100 * z_range;
- } else if (z_wind == "NW") {
+ } else if (z_wind === "NW") {
z_hpa += 1.5 / 100 * z_range;
- } else if (z_wind == "NNW") {
+ } else if (z_wind === "NNW") {
z_hpa += 3 / 100 * z_range;
}
- if (z_season == 1) { // if Summer
- if (z_trend == 1) { // rising
+ if (z_season) { // if Summer
+ if (z_trend === 1) { // rising
z_hpa += 7 / 100 * z_range;
- } else if (z_trend == 2) { // falling
+ } else if (z_trend === 2) { // falling
z_hpa -= 7 / 100 * z_range;
}
}
} else { // must be South hemisphere
- if (z_wind == "S") {
+ if (z_wind === "S") {
z_hpa += 6 / 100 * z_range;
- } else if (z_wind == "SSW") {
+ } else if (z_wind === "SSW") {
z_hpa += 5 / 100 * z_range;
- } else if (z_wind == "SW") {
- // z_hpa += 4 ;
+ } else if (z_wind === "SW") {
+ // z_hpa += 4 ;
z_hpa += 5 / 100 * z_range;
- } else if (z_wind == "WSW") {
+ } else if (z_wind === "WSW") {
z_hpa += 2 / 100 * z_range;
- } else if (z_wind == "W") {
+ } else if (z_wind === "W") {
z_hpa -= 0.5 / 100 * z_range;
- } else if (z_wind == "WNW") {
- // z_hpa -= 3 ;
+ } else if (z_wind === "WNW") {
+ // z_hpa -= 3 ;
z_hpa -= 2 / 100 * z_range;
- } else if (z_wind == "NW") {
+ } else if (z_wind === "NW") {
z_hpa -= 5 / 100 * z_range;
- } else if (z_wind == "NNW") {
+ } else if (z_wind === "NNW") {
z_hpa -= 8.5 / 100 * z_range;
- } else if (z_wind == "N") {
- // z_hpa -= 11 ;
+ } else if (z_wind === "N") {
+ // z_hpa -= 11 ;
z_hpa -= 12 / 100 * z_range;
- } else if (z_wind == "NNE") {
+ } else if (z_wind === "NNE") {
z_hpa -= 10 / 100 * z_range; //
- } else if (z_wind == "NE") {
+ } else if (z_wind === "NE") {
z_hpa -= 6 / 100 * z_range;
- } else if (z_wind == "ENE") {
+ } else if (z_wind === "ENE") {
z_hpa -= 4.5 / 100 * z_range; //
- } else if (z_wind == "E") {
+ } else if (z_wind === "E") {
z_hpa -= 3 / 100 * z_range;
- } else if (z_wind == "ESE") {
+ } else if (z_wind === "ESE") {
z_hpa -= 0.5 / 100 * z_range;
- } else if (z_wind == "SE") {
+ } else if (z_wind === "SE") {
z_hpa += 1.5 / 100 * z_range;
- } else if (z_wind == "SSE") {
+ } else if (z_wind === "SSE") {
z_hpa += 3 / 100 * z_range;
}
- if (z_season == 0) { // if Winter
- if (z_trend == 1) { // rising
+ if (!z_season) { // if Winter
+ if (z_trend === 1) { // rising
z_hpa += 7 / 100 * z_range;
- } else if (z_trend == 2) { // falling
+ } else if (z_trend === 2) { // falling
z_hpa -= 7 / 100 * z_range;
}
}
} // END North / South
- if (z_hpa == z_baro_top) z_hpa = z_baro_top - 1;
- z_option = Math.floor((z_hpa - z_baro_bottom) / z_constant);
- z_output = "";
- z_output_it = ""
+ if (z_hpa === z_baro_top) z_hpa = z_baro_top - 1;
+ let z_option = Math.floor((z_hpa - z_baro_bottom) / z_constant);
+ let z_output = "";
+ let z_output_it = "";
if (z_option < 0) {
z_option = 0;
z_output = "Exceptional Weather, ";
@@ -149,24 +147,22 @@ function forecast(z_hpa, z_wind, z_trend, z_hemisphere, z_upper, z_lower) {
z_output_it = "Tempo eccezionale, ";
}
- if (z_trend == 1) { // rising
+ if (z_trend === 1) { // rising
z_output += z_forecast[rise_options[z_option]];
- z_output_it += z_forecast_italian[rise_options[z_option]]
+ z_output_it += z_forecast_italian[rise_options[z_option]];
z_test.zambretti_number = rise_options[z_option];
- } else if (z_trend == 2) { // falling
+ } else if (z_trend === 2) { // falling
z_output += z_forecast[fall_options[z_option]];
- z_output_it += z_forecast_italian[fall_options[z_option]]
+ z_output_it += z_forecast_italian[fall_options[z_option]];
z_test.zambretti_number = fall_options[z_option];
} else { // must be 'steady'
z_output += z_forecast[steady_options[z_option]];
- z_output_it += z_forecast_italian[steady_options[z_option]]
+ z_output_it += z_forecast_italian[steady_options[z_option]];
z_test.zambretti_number = steady_options[z_option];
}
- // return z_output ;
z_test.forecast_phrase = z_output;
z_test.forecast_phrase_it = z_output_it;
return z_test;
-} // END function
-
+} // END function
module.exports.forecast = forecast;
diff --git a/src/utils/logger.js b/src/utils/logger.js
index 6f9d5ab..bc82f3a 100644
--- a/src/utils/logger.js
+++ b/src/utils/logger.js
@@ -1,16 +1,16 @@
-const winston = require('winston');
+const winston = require("winston");
-logger = winston.createLogger({
- level: 'info',
+const logger = winston.createLogger({
+ level: "info",
format: winston.format.json(),
- defaultMeta: { service: 'user-service' },
+ defaultMeta: { service: "user-service" },
transports: [
//
// - Write all logs with level `error` and below to `error.log`
// - Write all logs with level `info` and below to `combined.log`
//
- new winston.transports.File({ filename: 'error.log', level: 'error', timestamp: true }),
- new winston.transports.File({ filename: 'combined.log', timestamp: true })
+ new winston.transports.File({ filename: "error.log", level: "error", timestamp: true }),
+ new winston.transports.File({ filename: "combined.log", timestamp: true })
]
});
@@ -21,4 +21,4 @@ logger.add(new winston.transports.Console({
colorized: true
}));
-module.exports = logger
\ No newline at end of file
+module.exports = logger;
\ No newline at end of file
diff --git a/src/utils/meteo_utils.js b/src/utils/meteo_utils.js
index 12af771..e992604 100644
--- a/src/utils/meteo_utils.js
+++ b/src/utils/meteo_utils.js
@@ -1,16 +1,4 @@
-express = require('express');
-forecast = require('./forecast');
-
-module.exports = Object.assign({},
- seaLevelPressure,
- dewPoint,
- humidex,
- windchill,
- degToCardinal,
- calcBarometerDifference,
- forecast);
-
-
+const forecast = require("./forecast");
function seaLevelPressure(pressure, altitude) {
return Math.round(pressure + (altitude / 8) * 100) / 100; //mbar/hpa
@@ -18,26 +6,26 @@ function seaLevelPressure(pressure, altitude) {
//Punto di Rugiada
function dewPoint(temperature, humidity) {
- let pres_vap_sat = 6.11 * Math.pow(10, (7.5 * temperature) / (237.7 + temperature));
- let pres_vap_eff = (humidity * pres_vap_sat) / 100;
- let dew_point = (-430.22 + 237.7 * Math.log(pres_vap_eff)) / (-Math.log(pres_vap_eff) + 19.08);
+ const pres_vap_sat = 6.11 * Math.pow(10, (7.5 * temperature) / (237.7 + temperature));
+ const pres_vap_eff = (humidity * pres_vap_sat) / 100;
+ const dew_point = (-430.22 + 237.7 * Math.log(pres_vap_eff)) / (-Math.log(pres_vap_eff) + 19.08);
return Math.round(dew_point * 10) / 10;
}
//Temperatura percepita
function humidex(temperature, humidity) {
if (temperature < 21 || humidity < 20) return temperature;
- let humidex = temperature + 0.5555 * (6.112 * humidity / 100 * Math.pow(10, ((7.5 * temperature) / (237.7 + temperature))) - 10);
- return Math.round(humidex * 10) / 10;
+ const humidex_val = temperature + 0.5555 * (6.112 * humidity / 100 * Math.pow(10, ((7.5 * temperature) / (237.7 + temperature))) - 10);
+ return Math.round(humidex_val * 10) / 10;
}
//Temperatura percepita a causa del vento
function windchill(temperature, wind) {
if (temperature > 10) return "N/A";
- wind *= 3.6; //Km/h -> m/s
- if (temperature <= 10 || !(wind <= 25 && wind >= 1.78)) return temperature;
- let windchill = (0.45 * Math.pow(wind, 0.5) + 0.47 - wind) * (temperature - 33) + 33;
- return Math.round(windchill * 10) / 10;
+ const wind_speed = wind * 3.6; //Km/h -> m/s
+ if (temperature <= 10 || !(wind_speed <= 25 && wind_speed >= 1.78)) return temperature;
+ const windchill_val = (0.45 * Math.pow(wind_speed, 0.5) + 0.47 - wind_speed) * (temperature - 33) + 33;
+ return Math.round(windchill_val * 10) / 10;
}
function degToCardinal(direction) {
@@ -60,13 +48,11 @@ function degToCardinal(direction) {
}
function calcBarometerDifference(val) {
- //if (!val.isArray()) return 0;
if (val.length === 1) return 0;
- let curr;
let prec = 0;
let difference = 0;
for (let i = 0; i < val.length; i++) {
- curr = val[i];
+ const curr = val[i];
if (i !== 0) {
difference += curr - prec;
}
@@ -76,8 +62,8 @@ function calcBarometerDifference(val) {
}
function iqa(pm25, pm10) {
- var iqa_pm25 = 0;
- var iqa_pm10 = 0;
+ let iqa_pm25 = 0;
+ let iqa_pm10 = 0;
if (pm25 >= 0 && pm25 < 10) {
iqa_pm25 = 4;
@@ -96,7 +82,7 @@ function iqa(pm25, pm10) {
}
if (pm10 >= 0 && pm10 < 20) {
- iqa_pm10 = 4; pm10
+ iqa_pm10 = 4;
}
if (pm10 >= 20 && pm10 < 35) {
iqa_pm10 = 3;
@@ -114,31 +100,13 @@ function iqa(pm25, pm10) {
return Math.min(iqa_pm10, iqa_pm25);
}
-module.exports.seaLevelPressure = seaLevelPressure;
-module.exports.dewPoint = dewPoint;
-module.exports.humidex = humidex;
-module.exports.windchill = windchill;
-module.exports.degToCardinal = degToCardinal;
-module.exports.calcBarometerDifference = calcBarometerDifference;
-module.exports.iqa = iqa;
-
-
-/*
-if (0 <= direction < 22.5) return "N";
- if (22.5 <= direction < 45) return "NNE";
- if (45 <= direction < 67.5) return "NE";
- if (67.5 <= direction < 90) return "ENE";
- if (90 <= direction < 112.5) return "E";
- if (112.5 <= direction < 135) return "ESE";
- if (135 <= direction < 157.5) return "SE";
- if (157.5 <= direction < 180) return "SSE";
- if (180 <= direction < 202.5) return "S";
- if (202.5 <= direction < 225) return "SSW";
- if (225 <= direction < 247.5) return "SW";
- if (247.5 <= direction < 270) return "WSW";
- if (270 <= direction < 292.5) return "W";
- if (292.5 <= direction < 315) return "WNW";
- if (315 <= direction < 337.5) return "NW";
- if (337.5 <= direction < 0) return "NNW";
- */
-
+module.exports = {
+ seaLevelPressure,
+ dewPoint,
+ humidex,
+ windchill,
+ degToCardinal,
+ calcBarometerDifference,
+ iqa,
+ forecast: forecast.forecast
+};
diff --git a/src/utils/paths.js b/src/utils/paths.js
new file mode 100644
index 0000000..686eb90
--- /dev/null
+++ b/src/utils/paths.js
@@ -0,0 +1,3 @@
+const path = require("path");
+
+module.exports.FIRMWARE_UPDATE_DIR = path.join(__dirname, "..", "firmware_update");
diff --git a/src/views/config/configuration.pug b/src/views/config/configuration.pug
index b9ae20e..d626376 100644
--- a/src/views/config/configuration.pug
+++ b/src/views/config/configuration.pug
@@ -1,8 +1,8 @@
extends ../layout
block content
- div.padding-base
- h1.text-center Configurazione
+ div.padding-base.padding-bottom
+ h1.text-center.little-padding-bottom Configurazione
ul.nav.nav-tabs(role='tablist')
li.nav-item
a.nav-link.active(data-toggle='tab' href='#stat') Stazioni
@@ -61,7 +61,7 @@ block content
td.align-middle#thAltitude=item.altitude
td.align-middle#thModel=item.model
td.align-middle#thFirmwareVersion=item.firmware_version
- td.align-middle=moment.utc(item.last_update).format("D/M/Y H:mm")
+ td.align-middle=item.last_update_formatted
td.align-middle#thToken=item.token
td
div
@@ -224,7 +224,7 @@ block content
td.align-middle=item.model
td.align-middle=item.version
td.align-middle.d-none=item.file_name
- td.align-middle=moment.utc(item.stamp).format("D/M/Y H:mm")
+ td.align-middle=item.stamp_formatted
td
div
form.form-inline.d-inline(method='POST' action='/config/firmware_update/delete_update')
diff --git a/src/views/history/chart.pug b/src/views/history/chart.pug
index 7b24cc2..421dc91 100644
--- a/src/views/history/chart.pug
+++ b/src/views/history/chart.pug
@@ -9,10 +9,10 @@ block data
window.open(dataURL, height=50, width=100)
}
- div.row
+ div.padding-base.padding-bottom.chart-grid
//TEMPERATURE
if(data.temperature !== 'N/A')
- canvas.col-6(id="TemperatureChart")
+ canvas(id="TemperatureChart")
script.
var ctx = document.getElementById("TemperatureChart").getContext('2d');
var myChart = new Chart(ctx, {
@@ -66,7 +66,7 @@ block data
//HUMIDITY
if(data.humidity !== 'N/A')
- canvas.col-6(id="HumidityChart")
+ canvas(id="HumidityChart")
script.
var ctx = document.getElementById("HumidityChart").getContext('2d');
var myChart = new Chart(ctx, {
@@ -122,7 +122,7 @@ block data
//PRESSURE
if(data.pressure !== 'N/A')
- canvas.col-6(id="PressureChart")
+ canvas(id="PressureChart")
script.
var ctx = document.getElementById("PressureChart").getContext('2d');
var myChart = new Chart(ctx, {
@@ -177,7 +177,7 @@ block data
//RAIN
if(data.rain !== 'N/A')
- canvas.col-6(id = "RainChart")
+ canvas(id="RainChart")
script.
var ctx = document.getElementById("RainChart").getContext('2d');
var myChart = new Chart(ctx, {
@@ -233,7 +233,7 @@ block data
//WIND
if(data.wind !== 'N/A')
- canvas.col-6(id = "WindChart")
+ canvas(id="WindChart")
script.
var ctx = document.getElementById("WindChart").getContext('2d');
var myChart = new Chart(ctx, {
@@ -316,7 +316,7 @@ block data
//Fulmini
if(data.lighting !== 'N/A')
- canvas.col-6(id = "LightingChart")
+ canvas(id="LightingChart")
script.
var ctx = document.getElementById("LightingChart").getContext('2d');
var myChart = new Chart(ctx, {
@@ -373,7 +373,7 @@ block data
//AIR QUALITY
if(data.air_quality !== 'N/A')
- canvas.col-6(id = "AirQualityChart")
+ canvas(id="AirQualityChart")
script.
var ctx = document.getElementById("AirQualityChart").getContext('2d');
var myChart = new Chart(ctx, {
diff --git a/src/views/history/history.pug b/src/views/history/history.pug
index 847cf77..94c3d36 100644
--- a/src/views/history/history.pug
+++ b/src/views/history/history.pug
@@ -1,34 +1,37 @@
extends ../layout
block content
- //h2.little-padding-bottom Data History
+ div.padding-base.padding-bottom
+ form.history-toolbar(method='GET' action='/history')
+ div.form-group-inline
+ label(for='station_id') Stazione
+ select.form-control(id='station_id' name='station_id')
+ if !data
+ option(value=0) Seleziona...
+ each item in station
+ if data && item.name === data.name
+ option(value=item.id selected) #{item.name} - #{item.location}
+ else
+ option(value=item.id) #{item.name} - #{item.location}
- div.padding-base
- form.form-inline.little-padding-bottom(method='GET' action='/history')
- label(for='station_id') Stazione:
- select.form-control.form-margin(id='station_id' name='station_id')
- if !data
- option(value=0) Seleziona...
- each item in station
- if data && item.name === data.name
- option(value=item.id selected) #{item.name} - #{item.location}
+ div.form-group-inline
+ label(for='date_start') Inizio
+ input.form-control(id='date_start' name='date_start' type='text' value=date_start)
+
+ div.form-group-inline
+ label(for='date_end') Fine
+ input.form-control(id='date_end' name='date_end' type='text' value=date_end)
+
+ div.form-group-inline
+ label(for='type') Vista
+ select.form-control(id='type' name='type')
+ if type === 1
+ option(value=0) Grafici
+ option(value=1 selected) Tabelle
else
- option(value=item.id) #{item.name} - #{item.location}
+ option(value=0 selected) Grafici
+ option(value=1) Tabelle
- label(for='date_start') Inizio:
- input.form-control.form-margin(id='date_start' name='date_start' type='text' value=date_start)
- label(for='date_end') Fine:
- input.form-control.form-margin(id='date_end' name='date_end' type='text' value=date_end)
- select.form-control.form-margin(id='type' name='type')
- if type === 0
- option(value=0 selected) Grafici
- option(value=1) Tabelle
- else if type === 1
- option(value=0) Grafici
- option(value=1 selected) Tabelle
- else
- option(value=0 selected) Grafici
- option(value=1) Tabelle
- button.btn.btn-m.btn-primary.form-margin(type='submit') OK
+ button.btn.btn-primary(type='submit') OK
- block data
\ No newline at end of file
+ block data
diff --git a/src/views/history/table.pug b/src/views/history/table.pug
index 52ce291..58c8b8b 100644
--- a/src/views/history/table.pug
+++ b/src/views/history/table.pug
@@ -3,7 +3,7 @@ extends history
block data
//Aggiungere un li per ogni tabella
- ul.nav.nav-tabs(role='tablist')
+ ul.nav.nav-tabs.margin-top(role='tablist')
if data.temperature !== 'N/A'
li.nav-index
a.nav-link(data-toggle='tab' href='#temp') TEMPERATURA
@@ -32,7 +32,7 @@ block data
li.nav-index
a.nav-link(data-toggle='tab' href='#air_quality') AIR QUALITY
- div.tab-content
+ div.tab-content.padding-bottom
//Temperatura
div.container.tab-pane(id='temp')
if data.temperature !== 'N/A'
diff --git a/src/views/index.pug b/src/views/index.pug
index b99a11c..fa5c2e3 100644
--- a/src/views/index.pug
+++ b/src/views/index.pug
@@ -1,42 +1,30 @@
extends layout
block content
- style.
- body {
- background-color: rgb(44, 47, 51);
- }
-
- h1 {
- color: White;
- }
-
- h1.padding-base.little-padding-bottom(align = "center") STAZIONI METEO
- each item in data
- div.row(style="width: 100vw; margin: 0; padding: 0; padding-bottom: 25px;")
- div.container.font-size.col-10
- table.table.table-dark.container
- if(dateConvert.checkOnline(item.last_update))
- thead.bg-success
- tr.text-center
- th(colspan='2').
- #{item.station} - #{item.location} - Altitudine: #{item.altitude} mslm -
- Ultimo Aggiornamento: #{item.last_update} ONLINE
- else
- thead.bg-danger
- tr.text-center
- th(colspan='2').
- #{item.station} - #{item.location} - Altitudine: #{item.altitude} mslm -
- Ultimo Aggiornamento: #{item.last_update} OFFLINE
-
- tbody
- if(item.temperature !== "N/A")
- tr
- th(colspan='2') Temperatura / Umidità
- tr
- td(style="width: 25%")
- i.wi.wi-thermometer.d-inline
- p(style="padding-right: 5px;").d-inline Temperatura: #{item.temperature}°C
-
+ div.padding-base.padding-bottom
+ h1.little-padding-bottom(align = "center") Stazioni Meteo
+
+ if !data.length
+ p.text-center.text-muted Nessuna stazione configurata.
+ else
+ div.station-grid
+ each item in data
+ div.station-card
+ div.station-card__header
+ div.station-card__title #{item.station} — #{item.location}
+ div.station-card__meta Altitudine: #{item.altitude} mslm · Ultimo aggiornamento: #{item.last_update}
+ if item.online
+ span.status-pill.status-pill--online Online
+ else
+ span.status-pill.status-pill--offline Offline
+
+ if item.temperature !== "N/A"
+ div.station-card__section-title Temperatura / Umidità
+ div.station-card__body
+ div.metric
+ i.wi.wi-thermometer
+ span.metric__label Temperatura
+ span.metric__value= item.temperature + "°C"
if(parseInt(item.temperature_trend) < -5)
i.wi.wi-direction-down.text-info
else if(parseInt(item.temperature_trend) < -1)
@@ -51,44 +39,44 @@ block content
i.wi.wi-direction-up.text-danger
if(item.humidity !== "N/A" && item.temperature > 10)
- td(style="width: 50%")
- i.wi.wi-thermometer.d-inline
- p.d-inline Percepita: #{item.humidex}°C
-
+ div.metric
+ i.wi.wi-thermometer
+ span.metric__label Percepita
+ span.metric__value= item.humidex + "°C"
else if (item.wind !== "N/A")
- td(style="width: 50%")
- i.wi.wi-thermometer.d-inline
- p.d-inline Percepita: #{item.windchill}°C
- tr
+ div.metric
+ i.wi.wi-thermometer
+ span.metric__label Percepita
+ span.metric__value= item.windchill + "°C"
+
if(item.min_temperature !== "N/A" && item.max_temperature !== "N/A")
- td(style="width: 50%").text-info
- i.wi.wi-thermometer.d-inline
- p.d-inline Minima: #{item.min_temperature}°C
- td(style="width: 50%").text-danger
- i.wi.wi-thermometer.d-inline
- p.d-inline Massima: #{item.max_temperature}°C
- else
- td(colspan='2')
- i.wi.wi-thermometer.d-inline
- p.d-inline Massime / Minime odierne non disponibili
+ div.metric
+ i.wi.wi-thermometer.text-info
+ span.metric__label Minima
+ span.metric__value= item.min_temperature + "°C"
+ div.metric
+ i.wi.wi-thermometer.text-danger
+ span.metric__label Massima
+ span.metric__value= item.max_temperature + "°C"
if(item.humidity !== "N/A")
- tr
- td(style="width: 50%")
- i.wi.wi-humidity.d-inline
- p.d-inline Umidità: #{item.humidity}%
- td(style="width: 50%")
- i.wi.wi-thermometer.d-inline
- p.d-inline Punto di Rugiada: #{item.dew_point}°C
+ div.station-card__body
+ div.metric
+ i.wi.wi-humidity
+ span.metric__label Umidità
+ span.metric__value= item.humidity + "%"
+ div.metric
+ i.wi.wi-thermometer
+ span.metric__label Punto di Rugiada
+ span.metric__value= item.dew_point + "°C"
if(item.pressure !== "N/A")
- tr
- th(colspan='2') Pressione Atmosferica
- tr
- td(style="width: 50%")
- i.wi.wi-barometer.d-inline
- p(style="padding-right: 5px;").d-inline Pressione: #{item.pressure} hPa
-
+ div.station-card__section-title Pressione Atmosferica
+ div.station-card__body
+ div.metric
+ i.wi.wi-barometer
+ span.metric__label Pressione
+ span.metric__value= item.pressure + " hPa"
if(parseInt(item.pressure_trend) < -2)
i.wi.wi-direction-down.text-info
else if(parseInt(item.pressure_trend) < -1)
@@ -101,92 +89,81 @@ block content
i.wi.wi-direction-up-right.text-danger
else
i.wi.wi-direction-up.text-danger
+ div.metric
+ i.wi.wi-barometer
+ span.metric__label Livello del Mare
+ span.metric__value= item.sea_level_pressure + " hPa"
- td(style="width: 50%")
- i.wi.wi-barometer.d-inline
- p.d-inline Livello del Mare: #{item.sea_level_pressure} hPa
-
- tr
- th(colspan='2') Previsione Meteo
- tr
- td
- p.d-inline #{item.forecast.forecast_phrase_it}
+ div.station-card__forecast= item.forecast.forecast_phrase_it
if(item.rain_last !== "N/A" && item.rain_sum !== "N/A")
- tr
- th(colspan='2') Pioggia
- tr
+ div.station-card__section-title Pioggia
+ div.station-card__body
if(item.rain_last === 0)
- td(style="width: 50%")
- i.wi.wi-day-sunny.d-inline
- p.d-inline Non Piove
+ div.metric
+ i.wi.wi-day-sunny
+ span.metric__value Non Piove
else
- td(style="width: 50%")
- i.wi.wi-showers.d-inline
+ div.metric
+ i.wi.wi-showers
if(item.rain_hour <= 1)
- p.d-inline Pioviggine: #{item.rain_hour} mm
+ span.metric__value= "Pioviggine: " + item.rain_hour + " mm"
else if(item.rain_hour <= 2)
- p.d-inline Pioggia Debole: #{item.rain_hour} mm
+ span.metric__value= "Pioggia Debole: " + item.rain_hour + " mm"
else if(item.rain_hour <= 5)
- p.d-inline Pioggia Moderata: #{item.rain_hour} mm
+ span.metric__value= "Pioggia Moderata: " + item.rain_hour + " mm"
else if(item.rain_hour <= 10)
- p.d-inline Pioggia Forte: #{item.rain_hour} mm
+ span.metric__value= "Pioggia Forte: " + item.rain_hour + " mm"
else if(item.rain_hour <= 30)
- p.d-inline Rovescio: #{item.rain_hour} mm
- else if(item.rain_hour > 30)
- p.d-inline Nubifragio:#{item.rain_hour} mm
+ span.metric__value= "Rovescio: " + item.rain_hour + " mm"
+ else
+ span.metric__value= "Nubifragio: " + item.rain_hour + " mm"
- td(style="width: 50%")
- i.wi.wi-showers.d-inline
- p.d-inline Ultime 24 Ore: #{item.rain_day} mm
+ div.metric
+ i.wi.wi-showers
+ span.metric__label Ultime 24 Ore
+ span.metric__value= item.rain_day + " mm"
if(item.wind !== "N/A")
- tr
- th(colspan='2') Vento
- tr
- td(style="width: 50%")
- i.wi.wi-strong-wind.d-inline
- p.d-inline Velocità: #{item.wind.speed} Km/h
- td(style="width: 50%")
- i.wi.wi-wind.towards-23-deg.d-inline
- p.d-inline Direzione: #{item.wind.cardinal_direction}
+ div.station-card__section-title Vento
+ div.station-card__body
+ div.metric
+ i.wi.wi-strong-wind
+ span.metric__label Velocità
+ span.metric__value= item.wind.speed + " Km/h"
+ div.metric
+ i.wi.wi-wind.towards-23-deg
+ span.metric__label Direzione
+ span.metric__value= item.wind.cardinal_direction
if(item.lighting !== "N/A")
- tr
- th(colspan='2') Ultimo Fulmine
- tr
- td(style="width: 50%")
- i.wi.wi-time-1.d-inline
- p.d-inline Ora: #{item.lighting.stamp}
- td(style="width: 50%")
- i.wi.wi-lightning.d-inline
- p.d-inline Distance: #{item.lighting.distance} Km
+ div.station-card__section-title Ultimo Fulmine
+ div.station-card__body
+ div.metric
+ i.wi.wi-time-1
+ span.metric__label Ora
+ span.metric__value= item.lighting.stamp
+ div.metric
+ i.wi.wi-lightning
+ span.metric__label Distanza
+ span.metric__value= item.lighting.distance + " Km"
if(item.air_quality !== "N/A")
- tr
- th(colspan='2') Qualità dell'Aria (Media Giornaliera)
- tr
- td(style="width: 50%")
- i.wi.wi-smog.d-inline
- p.d-inline PM 2.5: #{item.air_quality.PM25} ug/m^3 (Limite: 25 ug/m^3)
- td(style="width: 50%")
- i.wi.wi-smog.d-inline
- p.d-inline PM 10: #{item.air_quality.PM10} ug/m^3 (Limite: 50 ug/m^3)
- tr
+ div.station-card__section-title Qualità dell'Aria (Media Giornaliera)
+ div.station-card__body
+ div.metric
+ i.wi.wi-smog
+ span.metric__label PM 2.5
+ span.metric__value= item.air_quality.PM25 + " ug/m³ (limite 25)"
+ div.metric
+ i.wi.wi-smog
+ span.metric__label PM 10
+ span.metric__value= item.air_quality.PM10 + " ug/m³ (limite 50)"
+ div(style="padding: 0 20px 18px;")
- var iqa = item.air_quality.iqa
- if(iqa == 0)
- td(colspan='2')
- p.text-danger IQA: Molto Scarsa
- if(iqa == 1)
- td(colspan='2')
- p.text-danger IQA: Scarsa
- if(iqa == 2)
- td(colspan='2')
- p.text-warning IQA: Accettabile
- if(iqa == 3)
- td(colspan='2')
- p.text-success IQA: Buona
- if(iqa == 4)
- td(colspan='2')
- p.text-success IQA: Molto Buona
-
+ if(iqa <= 1)
+ span.iqa-badge.iqa-badge--bad IQA: #{iqa === 0 ? "Molto Scarsa" : "Scarsa"}
+ else if(iqa === 2)
+ span.iqa-badge.iqa-badge--ok IQA: Accettabile
+ else
+ span.iqa-badge.iqa-badge--good IQA: #{iqa === 3 ? "Buona" : "Molto Buona"}
diff --git a/src/views/layout.pug b/src/views/layout.pug
index 443609c..62b94e5 100644
--- a/src/views/layout.pug
+++ b/src/views/layout.pug
@@ -1,9 +1,13 @@
doctype html
html
head
+ meta(charset="utf-8")
+ meta(name="viewport" content="width=device-width, initial-scale=1.0")
title= title
- link(rel='stylesheet' href='/stylesheets/style.css')
+ link(rel="preconnect" href="https://fonts.googleapis.com")
+ link(rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap")
link(rel='stylesheet' href='/library/bootstrap/bootstrap.min.css')
+ link(rel='stylesheet' href='/stylesheets/style.css')
link(rel='stylesheet' href='/stylesheets/weather-icons.css')
link(rel='stylesheet' href='/stylesheets/weather-icons.min.css')
link(rel='stylesheet' href='/stylesheets/weather-icons-wind.css')
@@ -22,88 +26,80 @@ html
link(rel="icon" type="image/png" sizes="16x16" href="/icon/favicon-16x16.png")
link(rel="manifest" href="/icon/site.webmanifest")
link(rel="shortcut icon" href="/icon/favicon.ico")
- meta(name="msapplication-TileColor" content="#da532c")
+ meta(name="msapplication-TileColor" content="#0f172a")
meta(name="msapplication-config" content="/icon/browserconfig.xml")
- meta(name="theme-color" content="#ffffff")
+ meta(name="theme-color" content="#0f172a")
+ meta(name="apple-mobile-web-app-capable" content="yes")
+ meta(name="apple-mobile-web-app-status-bar-style" content="black-translucent")
body(onload="startTime()")
- nav.navbar.navbar-expand-sm.bg-success.navbar-dark.navbar-expand-sm.sticky-top
+ nav.navbar.navbar-expand-md.navbar-dark.sticky-top
div.container-fluid
- ul.nav.navbar-nav
- li.nav-item
- a(href='/')
- img.navbar-brand(src="/images/logo_navbar.png" onclick='window.location.replace(\'/\'' width=160)
- //a.navbar-brand(href='/') METEO SERVER
- if logged_user
- li.nav-item
- a.nav-link(href='/history') Dati
+ a.navbar-brand(href='/')
+ img(src="/images/logo_navbar.png" width=140 alt="MeteoServer")
+
+ button.navbar-toggler(type="button" data-toggle="collapse" data-target="#mainNav" aria-controls="mainNav" aria-expanded="false" aria-label="Toggle navigation")
+ span.navbar-toggler-icon
+
+ div.collapse.navbar-collapse(id="mainNav")
+ ul.navbar-nav.mr-auto
+ if logged_user
+ li.nav-item
+ a.nav-link(href='/history') Dati
+ li.nav-item
+ a.nav-link(href='/map') Mappa
+ if logged_user.admin === 'true'
+ li.nav-item
+ a.nav-link(href='/config/configuration') Configurazione
+
+ ul.navbar-nav.align-items-md-center
li.nav-item
- a.nav-link(href='/map') Mappa
- if logged_user
- if logged_user.admin === 'true'
+ span.nav-link(id="clock")
+ if logged_user
+ li.nav-item.dropdown
+ a.nav-link.dropdown-toggle(href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false")=logged_user.name
+ div.dropdown-menu.dropdown-menu-right(aria-labelledby="navbarDropdown")
+ if logged_user.admin === 'true'
+ h6.dropdown-header Amministratore
+ else
+ h6.dropdown-header Utente Standard
+ a.dropdown-item(href='/config/configuration') Opzioni
+ div.dropdown-divider
+ a.dropdown-item(href='/logout') Logout
+ else
li.nav-item
- a.nav-link(href='/config/configuration') Configurazione
+ a.nav-link(href="/login") Login
- ul.nav.navbar-nav.navbar-right
- li.nav-item.active
- a.nav-link(href='#' id="clock")
- if logged_user
- li.nav-item.dropdown
- a.nav-link.dropdown-toggle.active(href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false")=logged_user.name
- div.dropdown-menu.dropdown-menu-right(aria-labelledby="navbarDropdown")
- if logged_user.admin === 'true'
- h1.dropdown-header Amministratore
- else
- h1.dropdown-header Utente Standard
- a.dropdown-item(href='/config/configuration') Opzioni
- div.dropdown-divider
- a.dropdown-item(href='/logout') Logout
- else
- li
- a.nav-link.active(href="/login")
- span.glyphicon.glyphicon-log-in Login
- div
+ main
if message
if message.info
each mes in message.info
- div.col-4.offset-4.alert.alert-primary.padding-base=mes
+ div.col-10.offset-1.col-md-6.offset-md-3.alert.alert-primary.text-center.padding-base=mes
if message.error
each mes in message.error
- div.col-4.offset-4.alert.alert-primary.padding-base=mes
-
-
- script.
- function startTime() {
- var today = new Date();
- var day = today.getDate();
- var month = today.getMonth() + 1;
- var year = today.getFullYear();
- var h = addZero(today.getHours());
- var m = today.getMinutes();
- var s = today.getSeconds();
- m = checkTime(m);
- s = checkTime(s);
- document.getElementById('clock').innerHTML =
- day + "/" + month + "/" + year + " " + h + ":" + m;
- var t = setTimeout(startTime, 500);
- }
-
- function checkTime(i) {
- if (i < 10) {
- i = "0" + i
- }
- ; // add zero in front of numbers < 10
- return i;
- }
+ div.col-10.offset-1.col-md-6.offset-md-3.alert.alert-primary.text-center.padding-base=mes
- function addZero(d) {
- if (d.toString().length < 2) {
- return '0' + d;
- }
- else return d;
- }
+ block content
- block content
+ script.
+ function startTime() {
+ var today = new Date();
+ var day = today.getDate();
+ var month = today.getMonth() + 1;
+ var year = today.getFullYear();
+ var h = addZero(today.getHours());
+ var m = checkTime(today.getMinutes());
+ document.getElementById('clock').innerHTML =
+ day + "/" + month + "/" + year + " " + h + ":" + m;
+ setTimeout(startTime, 500);
+ }
+ function checkTime(i) {
+ if (i < 10) i = "0" + i;
+ return i;
+ }
+ function addZero(d) {
+ return d.toString().length < 2 ? '0' + d : d;
+ }
diff --git a/src/views/login.pug b/src/views/login.pug
index 9c04120..70350a5 100644
--- a/src/views/login.pug
+++ b/src/views/login.pug
@@ -1,20 +1,14 @@
extends layout
block content
- div.padding-base
- //h1.text-center.little-padding-bottom MeteoServer
- img.col-4.offset-4(src="/images/logo.png")
- div.container
- div.row
- div.col-4.offset-4
- form(action="/login" method="POST")
- div.form-group
- label(for='username') Email:
- input.form-control(id='username' type='email' name='username' placeholder='email@example.com')
- div.form-group
- label(for='password') Password:
- input.form-control(id='password' type='password' name='password' placeholder='password')
- div
- button.btn.btn-m.btn-primary(type='submit') LOGIN
-
-
+ div.auth-wrapper
+ div.auth-card
+ img(src="/images/logo.png" alt="MeteoServer")
+ form(action="/login" method="POST")
+ div.form-group
+ label(for='username') Email
+ input.form-control(id='username' type='email' name='username' placeholder='email@example.com' required)
+ div.form-group
+ label(for='password') Password
+ input.form-control(id='password' type='password' name='password' placeholder='password' required)
+ button.btn.btn-primary.btn-block(type='submit') Login
diff --git a/src/views/map.pug b/src/views/map.pug
index 24fe290..7ecd44a 100644
--- a/src/views/map.pug
+++ b/src/views/map.pug
@@ -1,31 +1,19 @@
extends layout
block content
- style.
- body {
- padding: 0;
- margin: 0;
- }
-
- html, body, #mapid {
- height: 93vh;
- width: 100vw;
- }
-
- div(id="mapid" style="")
+ div(id="mapid")
script.
var data = JSON.parse(!{"\'" + stations_data + "\'"});
- if (data !== []) {
+ if (data.length !== 0) {
var mymap = L.map('mapid').setView([data[0].latitude, data[0].longitude], 10);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox/streets-v11',
- accessToken: 'pk.eyJ1IjoibWF0dGVvZm9ybWVudGluIiwiYSI6ImNqbjh2eHpxMDBrd3IzdnBpbDhtbWdnd24ifQ.AzSp0irWfub5D1Y0ybFK2A'
+ accessToken: !{JSON.stringify(mapbox_token)}
}).addTo(mymap);
- var marker = [];
data.forEach(function (station) {
var m = L.marker([station.latitude, station.longitude]).addTo(mymap);
@@ -41,7 +29,7 @@ block content
html += "
";
m.bindPopup(html).openPopup();
- marker.push(m);
});
- } else document.getElementById('mapid').innerHTML = "Nessuna stazione presente"
-
+ } else {
+ document.getElementById('mapid').innerHTML = "Nessuna stazione presente";
+ }
diff --git a/src/views/mobile/history/m_chart.pug b/src/views/mobile/history/m_chart.pug
deleted file mode 100644
index 1cb1852..0000000
--- a/src/views/mobile/history/m_chart.pug
+++ /dev/null
@@ -1,462 +0,0 @@
-extends m_history
-
-block data
-
- // per esportare in png
- function ex(){
- var canvas = document.getElementById('TemperatureChart');
- var dataURL = canvas.toDataURL('image/png', 1.0);
- window.open(dataURL, height=50, width=100)
- }
-
- style.
- canvas {
- width: 80vw;
- }
-
- div.row
- //TEMPERATURE
- if(data.temperature !== 'N/A')
- canvas.col-6(id="TemperatureChart")
- script.
- var ctx = document.getElementById("TemperatureChart").getContext('2d');
- var myChart = new Chart(ctx, {
- type: 'line',
- data: {
- labels: !{JSON.stringify(data.temperature.stamp)},
- datasets: [{
- label: 'Valore (°C)',
- data: [#{data.temperature.val}],
- backgroundColor: [
- 'rgba(255, 99, 132, 0.2)'
- ],
- borderColor: [
- 'rgba(255,99,132,1)'
- ],
- borderWidth: 1
- }]
- },
- options: {
- title: {
- display: true,
- fontColor: 'black',
- fontSize: 18,
- text: 'TEMPERATURA'
- },
- legend: {
- display: true,
- labels: {
- fontColor: 'grey'
- }
- },
- scales: {
- yAxes: [{
- ticks: {
- fontColor: 'grey'
- },
- scaleLabel: {
- display: true,
- fontColor: 'grey',
- labelString: '°C'
- }
- }],
- xAxes: [{
- ticks: {
- fontColor: 'grey'
- }
- }]
- }
- }
- });
-
- //HUMIDITY
- if(data.humidity !== 'N/A')
- canvas.col-6(id="HumidityChart")
- script.
- var ctx = document.getElementById("HumidityChart").getContext('2d');
- var myChart = new Chart(ctx, {
- type: 'line',
- data: {
- labels: !{JSON.stringify(data.humidity.stamp)},
- datasets: [{
- label: 'Relativa (%)',
- data: [#{data.humidity.val}],
- backgroundColor: [
- 'rgba(255, 206, 86, 0.2)' //Giallo
- ],
- borderColor: [
- 'rgba(255, 206, 86, 1)' //Giallo
- ],
- borderWidth: 1
- }]
- },
- options: {
- title: {
- display: true,
- fontColor: 'black',
- fontSize: 18,
- text: 'UMIDITA\''
- },
- legend: {
- display: true,
- labels: {
- fontColor: 'grey'
- }
- },
- scales: {
- yAxes: [{
- ticks: {
- beginAtZero: true,
- fontColor: 'grey'
- },
- scaleLabel: {
- display: true,
- fontColor: 'grey',
- labelString: '%'
- }
- }],
- xAxes: [{
- ticks: {
- fontColor: 'grey'
- }
-
- }]
- }
- }
- });
-
- div.row
- //PRESSURE
- if(data.pressure !== 'N/A')
- canvas.col-6(id="PressureChart")
- script.
- var ctx = document.getElementById("PressureChart").getContext('2d');
- var myChart = new Chart(ctx, {
- type: 'line',
- data: {
- labels: !{JSON.stringify(data.pressure.stamp)},
- datasets: [{
- label: ' Sea Level (hPa / mbar)',
- data: [#{data.pressure.val}],
- backgroundColor: [
- 'rgba(75, 192, 192, 0.2)'
- ],
- borderColor: [
- 'rgba(75, 192, 192, 1)'
- ],
- borderWidth: 1
- }]
- },
- options: {
- title: {
- display: true,
- fontColor: 'black',
- fontSize: 18,
- text: 'PRESSIONE'
- },
- legend: {
- display: true,
- labels: {
- fontColor: 'grey'
- }
- },
- scales: {
- yAxes: [{
- ticks: {
- fontColor: 'grey'
- },
- scaleLabel: {
- display: true,
- fontColor: 'grey',
- labelString: 'hPa / mbar'
- }
- }],
- xAxes: [{
- ticks: {
- fontColor: 'grey'
- }
-
- }]
- }
- }
- });
-
- //RAIN
- if(data.rain !== 'N/A')
- canvas.col-6(id = "RainChart")
- script.
- var ctx = document.getElementById("RainChart").getContext('2d');
- var myChart = new Chart(ctx, {
- type: 'line',
- data: {
- labels: !{JSON.stringify(data.rain.stamp)},
- datasets: [{
- label: 'Pioggia (mm)',
- data: [#{data.rain.val}],
- backgroundColor: [
- 'rgba(54, 162, 235, 0.2)'
- ],
- borderColor: [
- 'rgba(54, 162, 235, 1)'
- ],
- borderWidth: 1
- }]
- },
- options: {
- title: {
- display: true,
- fontColor: 'black',
- fontSize: 18,
- text: 'PIOGGIA Tot Periodo: #{data.rain.total_rainfall} mm'
- },
- legend: {
- display: true,
- labels: {
- fontColor: 'grey'
- }
- },
- scales: {
- yAxes: [{
- ticks: {
- beginAtZero: true,
- fontColor: 'grey'
- },
- scaleLabel: {
- display: true,
- fontColor: 'grey',
- labelString: 'mm'
- }
- }],
- xAxes: [{
- ticks: {
- fontColor: 'grey'
- }
-
- }]
- }
- }
- });
-
- div.row
- //WIND
- if(data.wind !== 'N/A')
- canvas.col-6(id = "WindChart")
- script.
- var ctx = document.getElementById("WindChart").getContext('2d');
- var myChart = new Chart(ctx, {
- type: 'line',
- data: {
- labels: !{JSON.stringify(data.wind.stamp)},
- datasets: [{
- label: 'Velocità (Km/h)',
- data: [#{data.wind.speed}],
- backgroundColor: [
- 'rgba(153, 102, 255, 0.2)'
- ],
- borderColor: [
- 'rgba(153, 102, 255, 1)'
- ],
- borderWidth: 1,
- yAxisID: 'y-axis-1'
- },
- {
- label: 'Direzione (N°)',
- data: [#{data.wind.direction}],
- backgroundColor: [
- 'rgba(54, 102, 255, 0.2)'
- ],
- borderColor: [
- 'rgba(54, 102, 255, 1)'
- ],
- borderWidth: 1,
- yAxisID: 'y-axis-2',
- showLine: false
- }]
- },
- options: {
- title: {
- display: true,
- fontColor: 'black',
- fontSize: 18,
- text: 'VENTO'
- },
- legend: {
- display: true,
- labels: {
- fontColor: 'grey'
- }
- },
- scales: {
- yAxes: [{
- type: 'linear',
- display: true,
- position: 'left',
- id: 'y-axis-1',
- scaleLabel: {
- display: true,
- fontColor: 'grey',
- labelString: 'Km/h'
- }
- }, {
- type: 'linear',
- display: true,
- position: 'right',
- id: 'y-axis-2',
- scaleLabel: {
- display: true,
- fontColor: 'grey',
- labelString: 'N°'
- },
- gridLines: {
- drawOnChartArea: false
- }
- }],
- xAxes: [{
- ticks: {
- fontColor: 'grey'
- }
-
- }]
- }
- }
- });
-
- //Fulmini
- if(data.lighting !== 'N/A')
- canvas.col-6(id = "LightingChart")
- script.
- var ctx = document.getElementById("LightingChart").getContext('2d');
- var myChart = new Chart(ctx, {
- type: 'line',
- data: {
- labels: !{JSON.stringify(data.lighting.stamp)},
- datasets: [{
- label: 'Distanza (Km)',
- data: [#{data.lighting.distance}],
- backgroundColor: [
- 'rgba(249, 129, 54, 0.2)'
- ],
- borderColor: [
- 'rgba(249, 129, 54, 1)'
- ],
- borderWidth: 1,
- showLine: false
- }]
- },
- options: {
- title: {
- display: true,
- fontColor: 'black',
- fontSize: 18,
- text: 'FULMINI'
- },
- legend: {
- display: true,
- labels: {
- fontColor: 'grey'
- }
- },
- scales: {
- yAxes: [{
- ticks: {
- beginAtZero: true,
- fontColor: 'grey'
- },
- scaleLabel: {
- display: true,
- fontColor: 'grey',
- labelString: 'Km'
- }
- }],
- xAxes: [{
- ticks: {
- fontColor: 'grey'
- }
-
- }]
- }
- }
- });
-
- //AIR QUALITY
- if(data.air_quality !== 'N/A')
- canvas.col-6(id = "AirQualityChart")
- script.
- var ctx = document.getElementById("AirQualityChart").getContext('2d');
- var myChart = new Chart(ctx, {
- type: 'line',
- data: {
- labels: !{JSON.stringify(data.air_quality.stamp)},
- datasets: [{
- label: 'PM 2.5 (ug/m^3)',
- data: [#{data.air_quality.PM25}],
- backgroundColor: [
- 'rgba(153, 102, 255, 0.2)'
- ],
- borderColor: [
- 'rgba(153, 102, 255, 1)'
- ],
- borderWidth: 1,
- yAxisID: 'y-axis-1'
- },
- {
- label: 'PM 10 (ug/m^3)',
- data: [#{data.air_quality.PM10}],
- backgroundColor: [
- 'rgba(54, 102, 255, 0.2)'
- ],
- borderColor: [
- 'rgba(54, 102, 255, 1)'
- ],
- borderWidth: 1,
- yAxisID: 'y-axis-2'
- //showLine: false
- }]
- },
- options: {
- title: {
- display: true,
- fontColor: 'black',
- fontSize: 18,
- text: 'AIR QUALITY'
- },
- legend: {
- display: true,
- labels: {
- fontColor: 'grey'
- }
- },
- scales: {
- yAxes: [{
- type: 'linear',
- display: true,
- position: 'left',
- id: 'y-axis-1',
- scaleLabel: {
- display: true,
- fontColor: 'grey',
- labelString: 'ug/m^3'
- }
- }, {
- type: 'linear',
- display: true,
- position: 'right',
- id: 'y-axis-2',
- scaleLabel: {
- display: true,
- fontColor: 'grey',
- labelString: 'ug/m^3'
- },
- gridLines: {
- drawOnChartArea: false
- }
- }],
- xAxes: [{
- ticks: {
- fontColor: 'grey'
- }
-
- }]
- }
- }
- });
\ No newline at end of file
diff --git a/src/views/mobile/history/m_history.pug b/src/views/mobile/history/m_history.pug
deleted file mode 100644
index 5c4f898..0000000
--- a/src/views/mobile/history/m_history.pug
+++ /dev/null
@@ -1,74 +0,0 @@
-extends ../m_layout
-
-block content
- block content
- style.
- warning-message {
- display: none;
- }
-
- @media only screen and (orientation: portrait) {
-
- #wrapper {
- display: none;
- }
-
- #warning-message {
- display: block;
- }
-
- }
-
- @media only screen and (orientation: landscape) {
-
- #warning-message {
- display: none;
- }
-
- }
-
- #type {
- display: none;
- }
- div.padding-base.col-10.offset-2(id="warning-message")
- h4 GIRA LO SCHERMO!
-
- div(id="wrapper")
- div(id="accordion" role="tablist" aria-multiselectable="true" )
- div.bg-info
- div.card-header(role="tab" id="headingOne")
- h5.mb-0
- a.collapsed.text-white(data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne")
- h12 IMPOSTAZIONI...
-
- div.collapse.jumbotron.jumbotron-fluid(id="collapseOne" role="tabpanel" aria-labelledby="headingOne" style="padding-top: 20px; padding-bottom: 20px;")
- div.card-block.col-10.offset-1
- form(method='GET' action='/history')
- label(for='station_id') Stazione:
- select.form-control.form-margin(id='station_id' name='station_id')
- if !data
- option(value=0) Seleziona...
- each item in station
- if data && item.name === data.name
- option(value=item.id selected) #{item.name} - #{item.location}
- else
- option(value=item.id) #{item.name} - #{item.location}
-
- label.little-margin-top(for='date_start') Inizio:
- input.form-control.form-margin(id='date_start' name='date_start' type='text' value=date_start)
- label.little-margin-top(for='date_end') Fine:
- input.form-control.form-margin(id='date_end' name='date_end' type='text' value=date_end)
- select.form-control.form-margin.little-margin-top(id='type' name='type')
- if type === 0
- option(value=0 selected) Grafici
- option(value=1) Tabelle
-
- else if type === 1
- option(value=0) Grafici
- option(value=1 selected) Tabelle
- else
- option(value=0 selected) Grafici
- option(value=1) Tabelle
- button.btn.btn-m.btn-primary.form-margin.little-margin-top(type='submit' style="width: 100px;") OK
-
- block data
\ No newline at end of file
diff --git a/src/views/mobile/m_index.pug b/src/views/mobile/m_index.pug
deleted file mode 100644
index 5f1212e..0000000
--- a/src/views/mobile/m_index.pug
+++ /dev/null
@@ -1,191 +0,0 @@
-extends m_layout
-
-block content
- style.
- body {
- background-color: rgb(44, 47, 51);
- }
-
- h1 {
- color: White;
- font-size: 2em;
- }
-
- h1.padding-base.little-padding-bottom(align = "center") STAZIONI METEO
- each item in data
- div.row(style="width: 100vw; margin: 0; padding: 0; padding-bottom: 25px;")
- table.table.table-dark.container(style="font-size: 80%")
- if(dateConvert.checkOnline(item.last_update))
- thead.bg-success
- tr.text-center
- th(colspan='2').
- #{item.station} - #{item.location} - Altitudine: #{item.altitude} mslm -
- Agg.: #{item.last_update} ONLINE
- else
- thead.bg-danger
- tr.text-center
- th(colspan='2').
- #{item.station} - #{item.location} - Altitudine: #{item.altitude} mslm -
- Agg: #{item.last_update} OFFLINE
-
- tbody
- if(item.temperature !== "N/A")
- tr
- th(colspan='2') Temperatura / Umidità
- tr
- td(style="width: 50%")
- i.wi.wi-thermometer.d-inline
- p(style="padding-right: 5px;").d-inline Temperatura: #{item.temperature}°C
-
- if(parseInt(item.temperature_trend) < -5)
- i.wi.wi-direction-down.text-info
- else if(parseInt(item.temperature_trend) < -1)
- i.wi.wi-direction-down-right.text-info
- else if(parseInt(item.temperature_trend) < 0)
- i.wi.wi-direction-right.text-success
- else if(parseInt(item.temperature_trend) < 1)
- i.wi.wi-direction-right.text-success
- else if(parseInt(item.temperature_trend) < 5)
- i.wi.wi-direction-up-right.text-danger
- else
- i.wi.wi-direction-up.text-danger
-
- if(item.humidity !== "N/A" && item.temperature > 10)
- td(style="width: 50%")
- i.wi.wi-thermometer.d-inline
- p.d-inline Percepita: #{item.humidex}°C
-
- else if (item.wind !== "N/A")
- td(style="width: 50%")
- i.wi.wi-thermometer.d-inline
- p.d-inline Percepita: #{item.windchill}°C
- tr
- if(item.min_temperature !== "N/A" && item.max_temperature !== "N/A")
- td(style="width: 50%").text-info
- i.wi.wi-thermometer.d-inline
- p.d-inline Min: #{item.min_temperature}°C
- td(style="width: 50%").text-danger
- i.wi.wi-thermometer.d-inline
- p.d-inline Max: #{item.max_temperature}°C
- else
- td(colspan='2')
- i.wi.wi-thermometer.d-inline
- p.d-inline Massime / Minime odierne non disponibili
-
- if(item.humidity !== "N/A")
- tr
- td(style="width: 50%")
- i.wi.wi-humidity.d-inline
- p.d-inline Umidità: #{item.humidity}%
- td(style="width: 50%")
- i.wi.wi-thermometer.d-inline
- p.d-inline P. Rugiada: #{item.dew_point}°C
-
- if(item.pressure !== "N/A")
- tr
- th(colspan='2') Pressione Atmosferica
- tr
- td(style="width: 50%")
- i.wi.wi-barometer.d-inline
- p(style="padding-right: 5px;").d-inline Pres: #{item.pressure} hPa
-
- if(parseInt(item.pressure_diff) < -2)
- i.wi.wi-direction-down.text-info
- else if(parseInt(item.pressure_trend) < -1)
- i.wi.wi-direction-down-right.text-info
- else if(parseInt(item.pressure_trend) < 0)
- i.wi.wi-direction-right.text-success
- else if(parseInt(item.pressure_trend) < 1)
- i.wi.wi-direction-right.text-success
- else if(parseInt(item.pressure_trend) < 2)
- i.wi.wi-direction-up-right.text-danger
- else
- i.wi.wi-direction-up.text-danger
-
- td(style="width: 50%")
- i.wi.wi-barometer.d-inline
- p.d-inline S.L.M: #{item.sea_level_pressure} hPa
-
- tr
- th(colspan='2') Previsione Meteo
- tr
- td
- p.d-inline #{item.forecast.forecast_phrase_it}
-
- if(item.rain_last !== "N/A" && item.rain_sum !== "N/A")
- tr
- th(colspan='2') Pioggia
- tr
- if(item.rain_last === 0)
- td(style="width: 50%")
- i.wi.wi-day-sunny.d-inline
- p.d-inline Non Piove
- else
- td(style="width: 50%")
- i.wi.wi-showers.d-inline
- if(item.rain_hour <= 1)
- p.d-inline Pioviggine: #{item.rain_hour} mm
- else if(item.rain_hour <= 2)
- p.d-inline Pioggia Debole: #{item.rain_hour} mm
- else if(item.rain_hour <= 5)
- p.d-inline Pioggia Moderata: #{item.rain_hour} mm
- else if(item.rain_hour <= 10)
- p.d-inline Pioggia Forte: #{item.rain_hour} mm
- else if(item.rain_hour <= 30)
- p.d-inline Rovescio: #{item.rain_hour} mm
- else if(item.rain_hour > 30)
- p.d-inline Nubifragio:#{item.rain_hour} mm
-
- td(style="width: 50%")
- i.wi.wi-showers.d-inline
- p.d-inline Ultime 24 Ore: #{item.rain_day} mm
-
- if(item.wind !== "N/A")
- tr
- th(colspan='2') Vento
- tr
- td(style="width: 50%")
- i.wi.wi-strong-wind.d-inline
- p.d-inline Velocità: #{item.wind.speed} Km/h
- td(style="width: 50%")
- i.wi.wi-wind.towards-23-deg.d-inline
- p.d-inline Direzione: #{item.wind.cardinal_direction}
-
- if(item.lighting !== "N/A")
- tr
- th(colspan='2') Ultimo Fulmine
- tr
- td(style="width: 50%")
- i.wi.wi-time-1.d-inline
- p.d-inline Ora: #{item.lighting.stamp}
- td(style="width: 50%")
- i.wi.wi-lightning.d-inline
- p.d-inline Distance: #{item.lighting.distance} Km
-
- if(item.air_quality !== "N/A")
- tr
- th(colspan='2') Qualità dell'Aria (Media Giornaliera)
- tr
- td(style="width: 50%")
- i.wi.wi-smog.d-inline
- p.d-inline PM 2.5: #{item.air_quality.PM25} ug/m^3 (Limite: 25 ug/m^3)
- td(style="width: 50%")
- i.wi.wi-smog.d-inline
- p.d-inline PM 10: #{item.air_quality.PM10} ug/m^3 (Limite: 50 ug/m^3)
- tr
- - var iqa = item.air_quality.iqa
- if(iqa == 0)
- td(colspan='2')
- p.text-danger IQA: Molto Scarsa
- if(iqa == 1)
- td(colspan='2')
- p.text-danger IQA: Scarsa
- if(iqa == 2)
- td(colspan='2')
- p.text-warning IQA: Accettabile
- if(iqa == 3)
- td(colspan='2')
- p.text-success IQA: Buona
- if(iqa == 4)
- td(colspan='2')
- p.text-success IQA: Molto Buona
diff --git a/src/views/mobile/m_layout.pug b/src/views/mobile/m_layout.pug
deleted file mode 100644
index a534606..0000000
--- a/src/views/mobile/m_layout.pug
+++ /dev/null
@@ -1,80 +0,0 @@
-doctype html
-html
- head
- title= title
- link(rel='stylesheet', href='/stylesheets/style.css')
- link(rel='stylesheet', href='/library/bootstrap/bootstrap.min.css')
- link(rel='stylesheet', href='/stylesheets/weather-icons.css')
- link(rel='stylesheet', href='/stylesheets/weather-icons.min.css')
- link(rel='stylesheet', href='/stylesheets/weather-icons-wind.css')
- link(rel='stylesheet', href='/stylesheets/weather-icons-wind.min.css')
- link(rel='stylesheet', href='/library/leaflet/leaflet.css')
- script(src='https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js')
- script(src='https://unpkg.com/popper.js/dist/umd/popper.min.js')
- script(src='/library/bootstrap/bootstrap.min.js')
- script(src='/library/ChartJs/Chart.min.js')
- script(src='/library/leaflet/leaflet.js')
-
- link(rel="apple-touch-icon", sizes="180x180", href="/icon/apple-touch-icon.png")
- link(rel="icon", type="image/png", sizes="32x32", href="/icon/favicon-32x32.png")
- link(rel="icon", type="image/png", sizes="16x16", href="/icon/favicon-16x16.png")
- link(rel="manifest", href="/icon/site.webmanifest")
- link(rel="shortcut icon", href="/icon/favicon.ico")
- meta(name="msapplication-TileColor", content="#da532c")
- meta(name="msapplication-config", content="/icon/browserconfig.xml")
- meta(name="theme-color", content="#ffffff")
-
- meta(name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no")
- meta(name="apple-mobile-web-app-capable" content="yes")
- meta(name="apple-mobile-web-app-status-bar-style" content="black-translucent")
-
- style.
- nav {
- height: 10vh;
- }
-
- body(onload="startTime()")
-
- div.pos-f-t.sticky-top
- div.bg-success(class="collapse" id="navbarToggleExternalContent")
- div.bg-success.p-4
- if logged_user
- a.nav-link.text-center(href='#' style="")
- if logged_user.admin === 'true'
- h7.text-white=logged_user.name + " - Amministratore"
- else
- h7.text-white=logged_user.name + " - Utente Standard"
- div.dropdown-divider
- a.nav-link(href='/history')
- h5.text-white Dati
- a.nav-link(href='/map')
- h5.text-white Mappa
- if logged_user.admin === 'true'
- a.nav-link(href='/config/configuration')
- h5.text-white Configurazione
- a.nav-link(href='/logout')
- h5.text-white Logout
- else
- a.nav-link(href='/login')
- h5.text-white Login
-
- nav.navbar.navbar-dark.bg-success
- a.navbar-brand(href='/')
- img(src="/images/logo_navbar.png" onclick='window.location.replace(\'/\'' width=160)
- button.navbar-toggler(type="button" data-toggle="collapse" data-target="#navbarToggleExternalContent" aria-controls="navbarToggleExternalContent" aria-expanded="false" aria-label="Toggle navigation")
- span.navbar-toggler-icon
-
-
- div
- if message
- if message.info
- each mes in message.info
- div.text-center.col-10.offset-1.alert.alert-primary.padding-base=mes
-
- if message.error
- each mes in message.error
- div.text-center.col-10.offset-1.alert.alert-primary.padding-base=mes
-
- block content
-
-
diff --git a/src/views/mobile/m_login.pug b/src/views/mobile/m_login.pug
deleted file mode 100644
index 83238d6..0000000
--- a/src/views/mobile/m_login.pug
+++ /dev/null
@@ -1,19 +0,0 @@
-extends m_layout
-
-block content
- //h1.text-center.little-padding-bottom MeteoServer
- div.padding-base
- img.col-10.offset-1(src="/images/logo.png")
- div.container
- div.row
- div.col-10.offset-1
- form(action="/login" method="POST")
- div.form-group
- label(for='username') Email:
- input.form-control(id='username' type='email' name='username' placeholder='email@example.com')
- div.form-group
- label(for='password') Password:
- input.form-control(id='password' type='password' name='password' placeholder='password')
- div
- button.btn.btn-m.btn-primary(type='submit') LOGIN
-
diff --git a/src/views/mobile/m_map.pug b/src/views/mobile/m_map.pug
deleted file mode 100644
index 4097218..0000000
--- a/src/views/mobile/m_map.pug
+++ /dev/null
@@ -1,47 +0,0 @@
-extends m_layout
-
-block content
- style.
- body {
- padding: 0;
- margin: 0;
- }
-
- html, body, #mapid {
- height: 90vh;
- width: 100vw;
- }
-
- div(id="mapid")
- script.
- var data = JSON.parse(!{"\'" + stations_data + "\'"});
-
- if (data !== []) {
- var mymap = L.map('mapid').setView([data[0].latitude, data[0].longitude], 10);
- L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
- attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
- maxZoom: 18,
- id: 'mapbox/streets-v11',
- accessToken: 'pk.eyJ1IjoibWF0dGVvZm9ybWVudGluIiwiYSI6ImNqbjh2eHpxMDBrd3IzdnBpbDhtbWdnd24ifQ.AzSp0irWfub5D1Y0ybFK2A'
- }).addTo(mymap);
-
- var marker = [];
- data.forEach(function (station) {
- var m = L.marker([station.latitude, station.longitude]).addTo(mymap);
-
- var html = "" + station.station + " - " + station.altitude + " mslm
"
- if (station.temperature !== "N/A") html += " " + station.temperature + " °C
";
- if (station.humidity !== "N/A") html += " " + station.humidity + " %
";
- if (station.sea_level_pressure !== "N/A") html += " " + station.sea_level_pressure + " hPa
";
- if (station.rain_day !== "N/A") html += " " + station.rain_day + " mm
";
- if (station.wind !== "N/A") html += " " + station.wind.speed + " Km/h " + station.wind.cardinal_direction + "
";
- if (station.lighting !== "N/A") html += " " + station.lighting.distance + " Km " + station.lighting.stamp + "
";
- if (station.air_quality !== "N/A") html += " PM2.5:" + station.air_quality.PM25 + " ug/m^3 PM10" + station.air_quality.PM10 +" ug/m^3 " + "
";
-
- html += "
";
-
- m.bindPopup(html).openPopup();
- marker.push(m);
- });
- } else document.getElementById('mapid').innerHTML = "Nessuna stazione presente"
-
diff --git a/src/views/station.pug b/src/views/station.pug
index 61b9e42..dcdecb0 100644
--- a/src/views/station.pug
+++ b/src/views/station.pug
@@ -1,7 +1,8 @@
extends layout
block content
- div.padding-base
+ div.padding-base.padding-bottom
+ h1.text-center.little-padding-bottom= data.station + " — " + data.location
div.container
div.row.justify-content-md-center
div.col-sm