diff --git a/Documentation/mqtt_broker_setup.txt b/Documentation/mqtt_broker_setup.txt index 9fec0f3..9508179 100644 --- a/Documentation/mqtt_broker_setup.txt +++ b/Documentation/mqtt_broker_setup.txt @@ -23,3 +23,4 @@ log_type all log_facility 5 log_dest file /var/log/mosquitto/mosquitto.log +https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-the-mosquitto-mqtt-messaging-broker-on-ubuntu-18-04 \ No newline at end of file diff --git a/IoT-sensor/index.js b/IoT-sensor/index.js index e69de29..d5d0dd9 100644 --- a/IoT-sensor/index.js +++ b/IoT-sensor/index.js @@ -0,0 +1,34 @@ +const { iot_sensor_data } = require("./modules/IoT-sensor"); +const client = require("./modules/mqtt"); + +function publishData() { + let data = iot_sensor_data(); + + // MQTT logic + client.publish("iot-data", JSON.stringify(data), { qos: 1 }, (err) => { + if (err) { + console.error("Error publishing message:", err); + } else { + console.log("Message published"); + } + }); +} + +client.on("connect", () => { + console.log("Connected to MQTT broker"); + publishData(); +}); + +client.on("end", () => { + console.log("Disconnected from MQTT broker"); + client.reconnect = true; +}); + +client.on("error", (err) => { + console.error("Error:", err); + client.end(); +}); + +//every 15 minutes +//setInterval(publishData, 900000); +setInterval(publishData, 600); \ No newline at end of file diff --git a/IoT-sensor/modules/IoT-sensor.js b/IoT-sensor/modules/IoT-sensor.js index e6aae7c..5752b55 100644 --- a/IoT-sensor/modules/IoT-sensor.js +++ b/IoT-sensor/modules/IoT-sensor.js @@ -51,15 +51,9 @@ function getRandomValue(min, max) { return Math.random() * (max - min) + min; } -async function iot_sensor_data() { - //5 minutes - setInterval(() => { - var json = generateRandomData(); - console.log(json); - }, 600); //every 1 second +function iot_sensor_data() { + return generateRandomData(); } -iot_sensor_data() - -module.exports = { iot_sensor_data } +module.exports = { iot_sensor_data }; diff --git a/IoT-sensor/modules/mqtt.js b/IoT-sensor/modules/mqtt.js index 17375aa..fed75ad 100644 --- a/IoT-sensor/modules/mqtt.js +++ b/IoT-sensor/modules/mqtt.js @@ -3,43 +3,17 @@ const fs = require('fs'); const path = require('path') require('dotenv').config({ path: path.resolve(__dirname, '../../.env') }) -// Configuration const brokerUrl = 'mqtt://mqtt.teeseng.uk'; const options = { - port: 8883, // MQTT broker port with TLS + port: 8883, username: process.env.MQTT_USER, password: process.env.MQTT_PASS, - protocol: 'mqtts', // Use MQTT over TLS - key: fs.readFileSync(path.resolve(__dirname, '../../cert/privkey.pem')), // Private key for the client - cert: fs.readFileSync(path.resolve(__dirname, '../../cert/cert.pem')), // Client certificate + protocol: 'mqtts', + key: fs.readFileSync(path.resolve(__dirname, '../../cert/privkey.pem')), + cert: fs.readFileSync(path.resolve(__dirname, '../../cert/cert.pem')), }; -// Create MQTT client const client = mqtt.connect(brokerUrl, options); module.exports = client; -// Event handlers -client.on('connect', () => { - console.log('Connected to MQTT broker'); - client.subscribe('your-topic'); // Subscribe to a topic - // Publish a message - client.publish('your-topic', 'Hello MQTT with TLS!', { qos: 1 }, (err) => { - if (err) { - console.error('Error publishing message:', err); - } else { - console.log('Message published'); - } - client.end(); // Close the connection after publishing - }); -}); - -client.on('message', (topic, message) => { - console.log(`Received message on topic ${topic}: ${message}`); - client.end(); // Close the connection after receiving a message -}); - -client.on('error', (err) => { - console.error('Error:', err); - client.end(); // Close the connection in case of an error -}); diff --git a/Web-Server/functions/validateData.js b/Web-Server/functions/validateData.js index 5ce8f06..d26fcd4 100644 --- a/Web-Server/functions/validateData.js +++ b/Web-Server/functions/validateData.js @@ -1,16 +1,25 @@ -var validator = require('validator'); +// Regular expressions for data validation +const psiPattern = /^\d+$/; +const humidityPattern = /^\d+%$/; +const concentrationPattern = /^\d+ppm$/; +const temperaturePattern = /^-?\d+°C$/; +const windspeedPattern = /^\d+km\/h$/; +const timePattern = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/; +const regionPattern = /^[a-zA-Z-]+$/; -function isNumber(data) { - if (validator.isNumeric(data)) - { - console.log(data); - } - else - { - console.log("Invalid data"); - } +function validateData(data) { + return ( + psiPattern.test(data.psi) && + humidityPattern.test(data.humidity) && + concentrationPattern.test(data.o3) && + concentrationPattern.test(data.no2) && + concentrationPattern.test(data.so2) && + concentrationPattern.test(data.co) && + temperaturePattern.test(data.temperature) && + windspeedPattern.test(data.windspeed) && + timePattern.test(data.time) && + regionPattern.test(data.region) + ); +} - - } - - module.exports = { isNumber } \ No newline at end of file +module.exports = { validateData }; diff --git a/Web-Server/index.js b/Web-Server/index.js index f07b75d..dc14c47 100644 --- a/Web-Server/index.js +++ b/Web-Server/index.js @@ -1,7 +1,17 @@ -//load paho mqtt subscriber -//load express server - const { app } = require("./modules/express.js"); +const client = require("./modules/mqtt"); + +/* +1) validate data from IoT sensor +2) upload data to database +3) add more routes to api +4) add swagger documentation +5) add middleware for authentication + + + +*/ + diff --git a/Web-Server/middleware/ApiKey.js b/Web-Server/middleware/ApiKey.js new file mode 100644 index 0000000..a3f6313 --- /dev/null +++ b/Web-Server/middleware/ApiKey.js @@ -0,0 +1,17 @@ +function apiKeyMiddleware(req, res, next) { + const apiKey = req.headers['x-api-key']; + + if (!apiKey) { + return res.status(401).json({ error: 'API key is missing' }); + } + + //logic to check db? + if (apiKey !== 'YOUR_API_KEY') { + return res.status(403).json({ error: 'Invalid API key' }); + } + + // API key is valid, continue to the next middleware or route handler + next(); +} + +module.exports = apiKeyMiddleware; diff --git a/Web-Server/middleware/ApiLogger.js b/Web-Server/middleware/ApiLogger.js new file mode 100644 index 0000000..59967a1 --- /dev/null +++ b/Web-Server/middleware/ApiLogger.js @@ -0,0 +1,22 @@ +//middleware + + +/* +const myLogger = function (req, res, next) { + console.log('LOGGED') + next() +} + +// Apply the middleware to a specific route +app.use('/special-route', myLogger)); + +*/ + +const APIlogger = (req, res, next) => { + + +} + + + +module.exports = { } \ No newline at end of file diff --git a/Web-Server/modules/express.js b/Web-Server/modules/express.js index 8907549..db91cb3 100644 --- a/Web-Server/modules/express.js +++ b/Web-Server/modules/express.js @@ -4,8 +4,8 @@ */ const express = require("express"); const helmet = require('helmet') -app.use(helmet()) const app = express(); +app.use(helmet()) const port = 80; //disable x-powered-by header for security reasons diff --git a/Web-Server/modules/mqtt.js b/Web-Server/modules/mqtt.js index 33135cc..fdb284c 100644 --- a/Web-Server/modules/mqtt.js +++ b/Web-Server/modules/mqtt.js @@ -2,36 +2,47 @@ const mqtt = require('mqtt'); const fs = require('fs'); const path = require('path') require('dotenv').config({ path: path.resolve(__dirname, '../../.env') }) +const { validateData } = require("../functions/validateData.js"); -// Configuration const brokerUrl = 'mqtt://mqtt.teeseng.uk'; const options = { - port: 8883, // MQTT broker port with TLS + port: 8883, username: process.env.MQTT_USER, password: process.env.MQTT_PASS, protocol: 'mqtts', // Use MQTT over TLS - key: fs.readFileSync(path.resolve(__dirname, '../../cert/privkey.pem')), // Private key for the client - cert: fs.readFileSync(path.resolve(__dirname, '../../cert/cert.pem')), // Client certificate + key: fs.readFileSync(path.resolve(__dirname, '../../cert/privkey.pem')), + cert: fs.readFileSync(path.resolve(__dirname, '../../cert/cert.pem')), }; -// Create MQTT client const client = mqtt.connect(brokerUrl, options); -module.exports = client; // Event handlers client.on('connect', () => { console.log('Connected to MQTT broker'); - client.subscribe('your-topic'); // Subscribe to a topic + client.subscribe('iot-data'); }); client.on('message', (topic, message) => { - console.log(`Received message on topic ${topic}: ${message}`); - // Additional processing for received message + //console.log(`Received message on topic ${topic}: ${message}`); + let data = JSON.parse(message); + if (validateData(data)) { + //upload to db logic here + } + else { + console.log("Data is invalid"); + } }); client.on('error', (err) => { console.error('Error:', err); - client.end(); // Close the connection in case of an error + client.end(); }); + +client.on('end', () => { + console.log('Disconnected from MQTT broker'); + client.reconnect = true; +} +); +