---
# System prepended metadata

title: Tutorial clothes recommender

---

# Tutorial Clothes Recommender

Created by Sandra Julin
sj223zn

## Overview

This project is designed to analyse temperature data and make recommendations on appropriate clothes to wear. LED lights on a Raspberry PI Pico W shows different colors depending on the current temperature, but the project also includes a web application where it is possible to view the current temperature, recommended clothes and temperature history data, but also to switch on and off the LED lights. A Grafana dashboard is also included in the project visualize temperature history data.

Around 8 hours is recommended to setup the TIG-stack (Telegraf, InfluxDB, Grafana) together with the Raspberry PI and Mosquitto broker if following this tutorial. Another 8 hours is recommended to develop the web application (React client and Express server) for collecting and displaying temperature data from the InfluxDB database.

## Objective

This project is designed to help my two sons, aged 11 and 8, choose appropriate clothing based on the current temperature. By measuring the temperature and showing different colors on the LED lights together with clothing recommendations in a web application, the kids will know if they should wear jacket, long-sleeves or shorts and t-shirt. They will also possible to view temperature history data in the web app and in a Grafana dashboard to get insights on how the temperature changes during the day and night and see how the temperature changes if the sun is shining, the wind is blowing or if it is raining. To save battery they can switch on and off the light from the web app.

## Platform and workflow

A Raspberry Pi Pico W was used in this project together with a thermistor sensor and a RGB LED module to analyse the temperature and show a red light if the temperature is 19 degrees or above, green if it is between 15 and 19 and blue if it is below 15 degrees. 

A mosquitto broker was used to send MQTT messages to and from the Pico over WiFi. I decided to use the Mosquitto broker since it is well-known and optimized for various cases. 

Telegraf was used for subscribing to the messages and sending data to the InfluxDB database. Grafana was used to collect data from the database and visualise it on a dashboard. The TIG-stack was chosen as Telegraf, InfluxDB and Grafana works well together and is a perfect setup for displaying temperature data.

A web application was created to be able to use the data for displaying cloth recommendations and to switch on and off the light. To create the web application a Node.js server was used as an API and connected with a client created with Javascript and React. The application displays temperature data in a graph and a table. It is also possible to view the current temperature together with pictures of appropiate clothes to wear. The application can also be used to switch on and off the led light on the Pico. 

At the moment everything is running locally on my computer, but to use it in a longer period all parts could be deployed, by using for examples free alternatives on Heroku or cloud services such as GCP, MA or AWS. 

## Material

I bought the Freenove Super Starter Kit for Raspberry i Pico W from Amazon. It included all material used in this project together with a lot of other kinds of material for future projects. It is probably possible to find cheaper alternatives for the parts used in this project, but I wanted to have more material that I can use in future projects. 

The Raspberry PI Pico W is a good option to use for this kind of project as it is possible to connect it with WiFi. 
    
| Units | Product                                                                  | Picture | Description                                                                                   |
|-------|--------------------------------------------------------------------------|---------|----------------------------------------------------------------------------------------------|
| 1     | Raspberry Pi Pico WH                                  |   ![raspberry](https://hackmd.io/_uploads/SJaDz-XBel.png)| Microcontroller                                                 |
| 1     | Thermistor                                          |![thermistor](https://hackmd.io/_uploads/r1ommWQHex.png)| Temperature sensitive resistor. The resistance of the themistor changes when it senses a change in temperature.                                            |
| 1     | Resistor 10kΩ                      | ![resistor](https://hackmd.io/_uploads/r1UkQ-QBgx.png)| An electrical component that limits or regulates the flow of current in an electronic circuit.                                                                 |                                      |
| 1     | Breadboard                                            |  ![breadboard](https://hackmd.io/_uploads/ryMZd-7Sel.png)| Board to connect devices to the microcontroller.                                          |
| 5     | Jumpers                                           |![jumper](https://hackmd.io/_uploads/Sy0cjZ7Hlx.png)| Wires used to connect devices on the breadboard              |
| 3     | Jumpers                                             | ![jumper2](https://hackmd.io/_uploads/H1AijbmSge.png)| Wires used to connect devices on the breadboard                                   |
| 1     | Freenove 8 RGB LED Module                                         |![led](https://hackmd.io/_uploads/B1B_9-QBex.png)| LED module with 8 led lights that can change color                                       |
| 1     | USB cable                                         |![usb](https://hackmd.io/_uploads/SyBXiZ7Bge.png)| Connects the Raspberry Pi Pico WH to the computer or the power device.       |
|    | Freenove Super Starter Kit for Raspberry i Pico W|![PartsList](https://hackmd.io/_uploads/HJRIJGXSel.jpg)| Kit containing all the above pcs from Freenove. The price is 499 SEK on Amazon.


## Computer setup

I used Visual studio code for programming the web app and the mosquitto.conf and telegraf.conf files. The code in main.py was uploaded to the Pico using Thonny. Freenove provided example code that has been used as starting code and modified for this project to flash the firmware, light up LED lights, connect to WiFi and read temperature data.
[https://freenove.com/fnk0063](https://freenove.com/fnk0063)

### Thonny
Thonny was downloaded from: https://thonny.org
To birn the firmware the Micropython firmware was downloaded from https://www.raspberrypi.com/documentation/microcontrollers/ and the following steps were followed: 
1. Connect a USB cable to your computer.
2. Long press BOOTSEL button on Raspberry Pi Pico and connect it to your computer with the USB cable.
3. Copy the file(rp2-pico-20210618-v1.16.uf2) to RPI-RP2 and wait for it to finish, just like copy file to a U disk
4. When the firmware finishes programming, Raspberry Pi Pico will reboot automatically.
5. Select “USB-SERIAL (COMx)”，The number x of COMx may vary among different computers. You only need to make sure selecting USB-SERIAL (COMx).

### Mosquitto 

Mosquitto was downloaded from https://mosquitto.org/ and started with the command mosquitto.exe -c mosquitto.conf -v from a bash terminal. 

### Telegraf

Telegraf was downloaded and a telegraf.conf file was created to configure Telegraf to subscribe to the MQTT topic (data/temp) to collect data from the broker. Telegraf was started with the command ".\telegraf.exe --config telegraf.conf" from a PowerShell terminal. [telegraf.conf](telegraf.conf)

### InfluxDB

InfluxDB was installed and started with the command ".\influxdb.exe". Once InfluxDB was running, the web interface was available at [http://localhost:8086](http://localhost:8086). After logging in - a bucket called "weatherbucket" and an API key was created and stored in the telegraf.conf file together with organization name "student" to make it possible to store data in the database.

### Grafana

Grafana was used for visualising the data by accessing the link http://localhost:3000. InfluxDB was added as data source, Flux as query language, URL http://localhost:8086, student as organization, the API token from InfluxDB and weatherbucket as default bucket. 

### Node.js server

Node.js was downloaded from this page and an API was created with Express. :
[https://nodejs.org/en/download](https://nodejs.org/en/download)
An API was created with Express to connect to the InfluxDB database and collect/send temperature data and controll the lights. The server code can be found here: 
[https://github.com/SanJulin/clothes-recommender](https://github.com/SanJulin/clothes-recommender)

### React 

A React Vite frontend app was created to visualize data by collecting it from the API and to provide a button to controll the lights. The app can be created with the following command: 
```npm create vite@latest my-react-app -- --template react```
The client code can be found here:
[https://github.com/SanJulin/clothes-recommender](https://github.com/SanJulin/clothes-recommender)

## Putting everything together

The below picture shows how the wires and the devices were connected. A USB cable was used to connect the Pico to a power bank. This solution works well for development, but for production, it could be better to use a power solution that doesn´t need to charge often. To save battery it would also be possible to use only one LED light instead of eight. 

![connections3](https://hackmd.io/_uploads/H1zZDGXHxg.png)

The below circuit diagrams and calculations are from the Freenove tutorial ([https://freenove.com/fnk0063](https://freenove.com/fnk0063)): 

Thermistor circuit diagram and calculations:
![circuit1](https://hackmd.io/_uploads/rymPy14Ble.png)

The relationship between resistance value and temperature of a thermistor is:
![thermistor_calc1](https://hackmd.io/_uploads/SJjexJESgl.png)
Where:
Rt is the thermistor resistance under T2 temperature;
R is the nominal resistance of thermistor under T1 temperature;
EXP[n] is nth power of e;
B is for thermal index;
T1, T2 is Kelvin temperature (absolute temperature). Kelvin temperature=273.15 + Celsius temperature.
(B=3950, R=10kΩ, T1=25℃ were used as parameters).
The value measured by the ADC converter can be used to obtain the resistance value of Thermistor, and then the formula can be used to obtain the temperature value.
The temperature formula can be derived as:
![thermistor_calc2](https://hackmd.io/_uploads/SkJRZyESge.png)

Freenove 8 RGB LED Module circuit diagram, LED module backside and pin description:
![circuit2](https://hackmd.io/_uploads/B1FoXkNrxe.png)
![module](https://hackmd.io/_uploads/Byc2V1VBxe.png)
![pin](https://hackmd.io/_uploads/rJ-lSyNrex.png)

## The code

The setup parts of the code in main.py running on the Pico contains parts for setting up WiFi and MQTT broker connections, and specifing sensor and LED on the Pico together with available LED colors and LED light status. The main program calls functions to connect to the WiFi and broker, checking incoming mqtt messages to see if the lights should be switched and functions to read and send temperature data. It also triggers the internal light on the Pico to light up every 

Example of code running on the Pico:

```python=
# Changes the color of the led lights depending on the temperature
def set_color_by_temperature(temp):
    if led_on:
        if temp >= 19:
            color = red
        elif temp >= 15:
            color = green
        else:
            color = blue
    else:
        color = off
    np.fill(*color)
    np.show()
```

Example of code in the telegraf.conf file used to subscribe to the data/temp topic and send data to the database:
```python=

# Configuration to send data to the InfluxDB database
[[outputs.influxdb_v2]]
  urls = ["http://localhost:8086"]
  token = "U2elNiqUJ_******Example*API*Token***gH0fGO3-g=="
  organization = "***"
  bucket = "weatherbucket"

#Configuration for subscribing to the data/temp topic to get updates
[[inputs.mqtt_consumer]]
  servers = ["tcp://localhost:1883"]
  topics = ["data/temp"]
  username = "iotproject"
  password = "******"
  qos = 0
  connection_timeout = "30s"
  persistent_session = false
  client_id = "telegraf_client"

  data_format = "json"
  json_string_fields = []
  tag_keys = ["sensor", "location"]
  name_override = "iot_temp_data"
```

Example of server code for switching on and off the lights by publishing mqtt messages: 

```python=
import mqtt from 'mqtt'

const MQTT_BROKER_URL = 'mqtt://***IP*address**:1883'
const MQTT_TOPIC = 'data/led'

export class LightsRepository {
  static #ledState = false
  static #mqttClient
    
    
#Changes the lights by sending a MQTT message
  async setLightsState (state) {
    LightsRepository.#ledState = state

    if (LightsRepository.#mqttClient?.connected) {
      const message = state ? 'on' : 'off'
      LightsRepository.#mqttClient.publish(MQTT_TOPIC, message)
    } else {
      console.warn('[MQTT] Client not connected')
    }
    return { state }
  }
```

Example of client code showing the temperature history page: 

```python=
 #Temperature page showing the latest sensor data with temperature readings.
export default function Temperature() {
      const [temperatures, setTemperatures] = useState([])

  useEffect(() => {
    const getTemperatures = async () => {
    const response = await axios.get('/sensor-data/temperatures')
    setTemperatures(response.data)
    }
    getTemperatures()
  }, [])


    return (
        <>
        <Navbar />
        <div className="sensordata-overview">
            <h2>Temperaturhistorik</h2>
            <hr />
            <p>Här kan du se historiken för temperaturmätningar från sensorerna.</p>
            <p>Temperaturerna är i Celsius och uppdateras var 10:e sekund.</p>
            <hr />
            <TemperatureChart temperatures={temperatures} />
            <hr />
            <List sensorData={temperatures} />
        </div>
        </>
    )
}
```

## Transmitting the data / connectivity
  
For this experiment a Raspberry PI Pico WH was used as hardware together with a thermistor as temperature  sensor and a module with 8 LED lights. Thonny was used as IDE and code logic was written in MicroPython. The Pico connected to the house WiFi and Mosquitto sent sensor temperature values every 10th second to the MQTT broker at "mqtt://192.168.68.60:1883". Telegraf subscribed to the topic "data/temp" to collect temperature data in real time in JSON-format, and forwarding it to InfluxDB for storage in the "weatherbucket". Grafana collected the time series data from InfluxDB and displayed it on the dashboard using Flux queries. "AggregateWindow(every: 10s, fn: mean)" in Grafana queries was used to reduce the number of data points.
    
![flow](https://hackmd.io/_uploads/ryrPUOLrll.png)

## Presenting the data in Grafana

The temperature data is saved in the database every 10 seconds. 

Then the Weather-dashboard in Grafana was created with visualisations of the temperature data using the below query:

from(bucket: "weatherbucket")
  |> range(start: -24h)
  |> filter(fn: (r) => r["_measurement"] == "iot_temp_data")
  |> filter(fn: (r) => r["_field"] == "temperature")
  |> filter(fn: (r) => r["topic"] == "data/temp")
  |> aggregateWindow(every: 10s, fn: mean, createEmpty: false)
  |> yield(name: "mean")

The temperature data is saved in the database every 10 seconds. 

  Included in the Grafana dashboard:
- 3 Line chart panels for Temperature data with different colors and layout effects displaying current temperature and history data
- Temperature history bar chart
- Bar gauge with current temperature
- Temperature history table
- Each panel uses Flux queries with aggregation every 10s
- Thresholds added with different colors depending on the levels
- Dashboard is set to auto-refresh every 10s

![grafana1](https://hackmd.io/_uploads/Sykx1AQrlg.png)
![grafana2](https://hackmd.io/_uploads/BkDxJ0QBlx.png)

## Presenting the data in the web app

The data is also presented in the web app. Three menu options are available.

The starting page displays the current weather temperature and clothes recommendations (shorts and T-shirt / longsleeves / jacket):
![current_temp](https://hackmd.io/_uploads/Hyf8SCQrel.png)

The lights page provides a button to switch on and off the lights on the Pico:
![switch_lights](https://hackmd.io/_uploads/S1s8r0XBxg.png)

The temperature history page provides temperature history in a time series line chart and a table:
![temp_history](https://hackmd.io/_uploads/H1VPHR7Sel.png)

![temp_table](https://hackmd.io/_uploads/ryeoSAmrxl.png)

## Finalizing the design

It has been fun to work with this project. The biggest challenge has been to connect everything to be able to send and collect data. 

The below pictures show the Pico when the temp is between 14 - 18,99 degrees (green lights) and above 19 degrees (red lights).
![IMG_2454](https://hackmd.io/_uploads/B172IUHrxl.jpg)
![IMG_2453](https://hackmd.io/_uploads/H12s8ISBxe.jpg)
![IMG_2463](https://hackmd.io/_uploads/rySbxgKSxx.jpg)


To further improve the application a lot of features could be added that was not used in this project due to time constraints. 

1. Usage of weather API forecast. The web application could collect data from a weather API to show appropriate clothes to wear later during the day. 
2. Usage of weather API history data. The web application could save data from a weather API and compare with the actual data recorded from the Pico.
3. Add more sensors to monitor humidity, wind and light to make cloth recommendations based on temperature, rain, wind and sun. 
4. Create a mobile app to get easier access to clothing recommendations and activate notifications if a change of clothes is needed. 


