## IoT-Driven Real-Time Energy Consumption Prediction with machine learning
**Ahmad Abdou, aa224rg**
### Short project overview
This project employs IOT sensors to precisely measure and estimate electrical power consumption by analyzing environmental variables such as temperature, humidity, and wind speed, in addition to utilizing various machine learning techniques.
### Estimated Time
To build this project without re-collecting data then it may take up to 2-3 hours.
# Objective
The purpose of this project is to show the impact of different weather conditions on the electrical power consumption and enhance the efficiency of electrical power consumption by leveraging IOT technology and machine learning. According to a [paper](https://ieeexplore-ieee-org.proxy.lnu.se/document/8703007) published in IEEE, there is a significant relationship between electrical power consumption and various weather conditions, such as temperature, humidity, and wind speed. These factors can influence power usage in meaningful ways.
By placing IOT devices to monitor these weather conditions, we can collect real-time data on power consumption patterns. Machine learning algorithms can then analyze this data to identify patterns and predict power usage more accurately. This approach allows us to make data-driven decisions about power management, potentially leading to substantial energy savings and improved sustainability.
> #### NOTE:
> The power consumption data was collected from Supervisory Control and Data Acquisition System (SCADA) of Amendis which is a public service operator and in charge of the distribution of drinking water and electricity since 2002.
> The data which is used in this study was the historical data of power consumption which was collected every 10 minutes for the period between 2017-01-01: 00:00:00 and 2017-12- 31: 23:50:00 **[1]**.
---
# Material
| Name | Cost | Seller |Image|
| -------- | -------- | -------- | -------- |
| [Kopplingsdäck med kopplingstråd](https://www.electrokit.com/kopplingsdack-med-kopplingstrad)|69 SEK| Electrokit|
| [Raspberry Pi Pico WH](https://www.electrokit.com/raspberry-pi-pico-wh)|109 SEK| Electrokit|
| [Digital temperatur- och fuktsensor DHT11](https://www.electrokit.com/digital-temperatur-och-fuktsensor-dht11)|49 SEK|Electrokit|
| [USB-kabel A-hane - miniB hane 1.8m](https://www.electrokit.com/usb-kabel-a-hane-mini-b-hane-5p-1.8m)|35 SEK|Electrokit|
| [LED 5mm grön diffus 80mcd](https://www.electrokit.com/led-5mm-gron-diffus-80mcd)|5 SEK| Electrokit|
| [LED 5mm gul diffus 1500mcd](https://www.electrokit.com/led-5mm-gul-diffus-1500mcd)|5 SEK| Electrokit|
| [LED 5mm röd diffus 1500mcd](https://www.electrokit.com/led-5mm-rod-diffus-1500mcd)|5 SEK| Electrokit|
| [Motstånd kolfilm 0.25W 330ohm (330R)](https://www.electrokit.com/motstand-kolfilm-0.25w-330ohm-330r)|3 SEK| Electrokit|
The Pico WH is used to gather data from various sensors, process this data with the help of machine learning models, and then represent the results visually.
The DHT11 sensor collects real-time temperature and humidity data from the environment.
Different LEDs are employed to indicate power consumption levels. If the consumption exceeds a specified threshold, a red LED will turn on. Other LEDs represent different levels of power consumption, with green indicating the lowest level and yellow indicating medium level.
Resistors are used to limit the current flowing through the circuit to prevent damage to the LEDs.
# Computer setup
I am using Windows 11 to run this project, The programs I used are the following:
I used 2 IDE's [Thonny](https://thonny.org/) to run my pico and [Vscode](https://code.visualstudio.com/download) for running the server and display the visualisation.
There are many dependencies that you need to install such as:
* dash
* dash-bootstrap-components
* pandas
* plotly
* scikit-learn
***> you can download them by using pip command.***
# Putting everything together
To connect your Pico with your machine, you need to follow these steps:
1. download the latest version of Raspberry Pi Pico W firmware from this [link](https://micropython.org/download/RPI_PICO_W/).
2. While holding the bootsel button, you can connect your Pico with your machine.
3. After connecting the Pico, a Popup window will apear, in here you need to drag and drop the frimware file that you have downloaded recently.
4. Open the Thonny IDE and head to the navigation bar.
5. Select Tools => Options => Interpreter and select MicroPython interpreter for Raspberry Pi Pico.
6. You can press the green circle to run the program.
## Wiring
To set up the circuit with three LEDs, three 330Ω resistors, and a DHT11 sensor, begin by preparing your breadboard. Place two jumper wires across the breadboard's rails: one for the positive (+) rail and one for the negative (-) rail. This setup provides a common power supply and ground connection throughout the breadboard, simplifying connections for various components. For each LED, identify the anode (the longer leg) and the cathode (the shorter leg). Connect each LED's anode to a 330Ω resistor, and then connect the other end of the resistor to one of the GPIO pins on the Raspberry Pi Pico, in my case I used (GPIO 13, 14, and 15). Connect the cathode of each LED directly to the negative (-) rail on the breadboard. This arrangement ensures that each LED is properly connected and controlled through the designated GPIO pins.

Regarding the DHT11 sensor, it should be placed on the breadboard as shown in the images below. Connect the sensor’s pins as follows: the ground pin (GND) is connected to the rightmost pin on the sensor, the positive pin (VCC) is connected to the middle pin, and the data pin (which connects to GPIO 21) is connected to the leftmost pin on the sensor.

### The final result should look like this

### This is how it looks like on reality

## Electrical calculations
**Raspberry Pi Pico WH**
Operating voltage: **3.3V**
Typical current consumption: ~20mA (idle) to ~100mA (active)
Let's assume an average of **60mA.**
**3 LEDs**
Typical forward voltage: **~2V**
Current through each LED with 330Ω resistor: (3.3V - 2V) / 330Ω ≈ **3.9mA**
Total for 3 LEDs: 3 * 3.9mA = **11.7mA**
**DHT11 sensor**
Operating voltage: **3.3V**
Typical current consumption: **~0.3mA**
**Power consumption:**
| Pico | LEDs | DHT11 | Total Power Consumption|
| -------- | -------- | -------- | ---------|
| 3.3V * 60mA| 3.3V * 11.7mA| 3.3V * 0.3mA |~237.6mW or 0.2376W
**Energy consumption per day:**
0.2376W * 24 hours = **5.7024** Wh per day
**Energy consumption per year:**
5.7024 Wh/day * 365 days = **2081.376 Wh or ~2.08** kWh per year
**Lifespan:**
The lifespan of this setup would primarily depend on the LEDs and the DHT11 sensor, as the Pico WH itself has a very long lifespan.
LEDs typically last 50,000 to 100,000 hours (5.7 to 11.4 years of continuous operation)
DHT11 sensors usually have a lifespan of 1-2 years with continuous use
Therefore, if kept running 24/7, you could expect this setup to run for about 1-2 years before the DHT11 sensor might need replacement. The LEDs would likely last longer.
## Platform
For this project, I decided to build my own web application using Dash (*which is a framework for building analytical web applications using Python*). Data is sent in real-time from the Pico to the server via HTTP requests, which are managed using the urequests library on the Pico. Additionally, the server is set up to fetch wind speed data from the **OpenWeatherMap API**.
The choice of platform for this IoT project was driven by a combination of functionality, cost-effectiveness, and educational value. On the software side, the use of Random Forest for machine learning enables accurate power consumption predictions based on environmental factors. Dash and Plotly were chosen for their ability to create interactive, real-time data visualizations with minimal setup, while CSV file storage offers a simple yet effective data management solution without the need for a complex database system. This platform created a balance between simplicity and functionality, allowing for the creation of a sophisticated IoT system that collects real-time environmental data, predicts power consumption, and visualizes results, all while serving as an excellent educational tool covering various aspects of modern technology, from sensor integration to machine learning applications.
## The Code
### The Machine learning code:
First the data set from the paper was used to train and evaluate different models. The reason behind that is to see which model is the most accurate for prediction.
```
# Define models to evaluate
models = {
'DecisionTree': DecisionTreeRegressor(),
'RandomForest': RandomForestRegressor(),
'LinearRegression': LinearRegression()
}
results = []
for name, model in models.items():
# Train the model
model.fit(X_train_scaled, y_train)
# Make predictions on the test set
y_pred = model.predict(X_test_scaled)
# Evaluate the model
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
results.append({
'Model': name,
'MSE': mse,
'R2': r2
})
print(f"{name} - Mean Squared Error: {mse}, R-squared Score: {r2}")
```
The result of the evalutation was
```
Model,MSE,R2
DecisionTree,18516443.709086623,0.07638518103314718
RandomForest,11071635.5450494,0.4477380851167668
LinearRegression,18615778.354137745,0.07143029057753514
```
Which shows that the Random Forst was the best.
Then the random forest was used to make the prediction for the power consumption by utilizing the data that are fetched from the pico in real time.
```
# Model parameters
model_params = {
'coefficients': [0.1, 0.2, 0.3],
'intercept': 1.0,
'means': [20, 50, 5],
'stds': [5, 10, 2]
}
def scale_features(features):
return [(x - m) / s for x, m, s in zip(features, model_params['means'], model_params['stds'])]
def predict(features):
scaled = scale_features(features)
return sum(c * x for c, x in zip(model_params['coefficients'], scaled)) + model_params['intercept']
```
The data that are predicted are also appended to a CSV file instead of a database. The CSV file is used by the server to read the data and display it on the web page.
### OpenWeather API:
Since I was not able to get Anemometer (wind speed sensor). The other option I had is to fetch it from the OpenWeather API.
The code for fetching the wind speed is down below
```
weather_url = 'https://api.openweathermap.org/data/2.5/weather?lat=56.8777&lon=14.8091&appid={api}'
def get_wind_speed():
try:
response = urequests.get(weather_url)
if response.status_code == 200:
data = response.json()
wind_speed = data['wind']['speed']
else:
wind_speed = None
response.close()
return wind_speed
except:
return None
```
The latitude and longitude are both hardcoded to Växjö.
With this all the data (whether collected from the Pico with the sensors) along with the wind speed and predicted power consumption are all saved and sent to the server to get display.
## The Server Code
This is the end point from the server in which the pico is using to communicate with it .
```
@server.route('/receive_data', methods=['POST'])
def receive_data():
global df
try:
data = request.json
print(f"Received data: {data}")
new_row = pd.DataFrame([data])
df = pd.concat([df, new_row], ignore_index=True)
# Save the updated DataFrame to CSV
df.to_csv(CSV_FILE_PATH, index=False)
return jsonify({"status": "success"}), 200
except Exception as e:
print(f"Error in receive_data: {e}")
return jsonify({"status": "error", "message": str(e)}), 500
```
With this implementation there was no need to shutdown the server in order to save the latest data to the CSV file, so, now all the data are appended to the CSV file and information that are dispalyed on the web page are updated accordingly.
## Transmitting the data / connectivity
The connection was done by using Wifi, and the data is fetched every 5 seconds, of course you can control the time, but since the data depends on the weather I don't see it as a good option to lower the time.
The server is running on port 5000.
```
app.run_server(debug=True, host='0.0.0.0', port=5000)
```
And inside your Pico , you need to write your IP address in the url along with the port that your server is using.
```
def send_data_to_server(data):
SERVER_URL = "{YOUR_IP_ADDRESS}:5000/receive_data"
try:
response = urequests.post(SERVER_URL, json=data)
if response.status_code == 200:
print("Data sent successfully")
else:
print(f"Failed to send data. Status code: {response.status_code}")
response.close()
except Exception as e:
print(f"Error sending data: {e}")
```
If you are unsure about the IP address you are using, you can open CMD and run: `ipconfig`, Based on your connection if it is Ethernet or Wirless.
In my case I am using Wifi so you can get your IP address from here:

Which is displayed beside **IPv4 Address**.
### the design choices regarding data transmission and wireless protocols
In my IoT project, I chose to use Wi-Fi for data transmission. This decision was primarily based on the wide availability of Wi-Fi networks and the Pico WH's built-in Wi-Fi capabilities.
Wi-Fi typically offers a range of 30-50 meters indoors, which is sufficient for my application of monitoring indoor environmental conditions. However, this range can be affected by obstacles and interference.
In terms of power consumption, Wi-Fi generally consumes more power compared to protocols like BLE or LoRa. This impacts the battery life of the device. To optimize power consumption, I implemented sleep modes between transmissions, allowing the device to conserve energy when not actively sending data. Additionally, not all data will be sent to the server. According to the code, when the Pico fetches new data, it compares it with the most recent data collected. New data will only be sent to the server if it differs from the latest data.
## Presenting the data
In this project there was no database used. since it is based oncollecting the weather conditions on real time, however there is still a CSV file used to save the all the historical data.

On this page you will see details about each feature that is being used to predict the power consumption and how much it impacts.
**The dashboard explanation**
The data was displayed by using plotly library.
The data on top are updated to match the data fetched from the Pico on real time.
Each figure represent something different, as you can see, the first two from the top are showing the temperature (the one on the left) and the other one is for humidity.
The ones on the middle shows the wind speed and feature importance.
The feature importance is generated from machine learning and its purpose is to show how much each of the features are impacting the power consumption. So based on the Bar chart, the humidity had the most impact on power consumption in contrast to the other two, and the temperature is the lowest.
Last 2 figures shows the time span of the power consumption and also a different presentation of the feature impact on the power.
The red line shows the humidity and as we can see the average of power consumption is above 1.3 kw/h when the humidity was in between 40% to > ~80%
The green represent the wind and the blue is for temperature.
Now if you pressed on the **Switch view** button, you will see the data all together displayed in 3D.
**The quality is low due to being exported as a GIF.**

Each plot shows a combination of all measurement.
The color represent the power consumption where the highest consumption are the ones that has yellow color and lowest are the dark blue ones.
On vscode:
The console will show something like this:
**The Pico**
> Data sent: 2024-08-11 12:33:26 - Temp: 25°C, Humidity: 42%, Wind Speed: 7.2 km/h, Predicted Power: 1.27
**The Server**
> Received data: {'timestamp': '2024-08-11 12:32:26', 'predicted_power': 1.27, 'wind_speed': 7.2, 'humidity': 42, 'temperature': 25}
## Finalizing the design
Before wrapping up, I would like to mention some failure attempts to expand the project and measure the performance as well.
In here as you can see trying to cook 2 raspberry pi to show the impact of the heat to the performance of the Raspberry pi. But it didn't end up well.. 🙂

So I had to stick with the Power consumption only to avoid unpleasant situations.
Overall, The project went well, I spent too much time doing different things and beside experimenting and analyzing the result. It took me more time due to the lack of equipment, beside the complexity of implementing machine learning and building the server along with displaying the data in a good way.
### Video presentation
Video 1: Showing the graphs and the interaction with the plots.
https://www.youtube.com/watch?v=GjMfH6RqKVk
Video 2 : Showing the Pico
https://www.youtube.com/watch?v=e2hrklB0s8Q
## References:
[1] A. Salam and Abdelaaziz El Hibaoui, “Comparison of Machine Learning Algorithms for the Power Consumption Prediction : - Case Study of Tetouan city –,” Dec. 2018, doi: https://doi.org/10.1109/irsec.2018.8703007.