Temperature monitoring and control system for Server Room

Student: Andrei-Alexandru Ulmamei
Master: ACES II
Git repository: https://gitlab.upb.ro/aulmamei/iot-project
Demo link: Demo
Presentation: Presentation

Project Description

This goal of this project is to create a temperature monitoring and control system, intended to be used in a server room, that consists of a Web Application, a microcontroller that communicates with the Web App, a sensor for monitoring temperature and an IR transmitter, used for controlling an air conditioning unit.

Hardware Description

The hardware components needed for the project are:

  • ESP32 WROOM V3 board – a very cost effective microcontroller which offers many features for IoT applications (such as WiFi connectivity, Bluetooth Low Energy). The project uses the ESP32 as the main data acquisition and control system, and it communicates to the web application via WiFI.
  • SSD1306 OLED I2C display – The OLED display is used for printing the actual temperature in the room, without the need of logging in to the application.
  • IR Receiver – The IR receiver was used to get the IR protocol from the remote to the air conditioning unit, in order to replicate them on the microcontroller.
  • IR Transmitter – The IR transmitter was used to control the A/C unit, by sending the appropriate commands, in order to turn on or off the A/C, to set the temperature and the fan speed.
  • DHT11 – This cost effective sensor was used to read the environment temperature
  • Jumper wires – Used for interconnecting the components presented above
  • Breadboard
  • A computer with Arduino IDE

The following electric schematic represents the project’s hardware.

The schematic was realized using KiCad (https://www.kicad.org/).

The hardware with all the components connected can be seen below:


Software architecture

The code is composed of 4 elements: the embedded software, written in Arduino IDE for the ESP32 board, the Web Component, which was written in HTML and Javascript for the frontend functionality, the Firebase Realtime Database configuration and the Grafana dashboard configuration.

Embedded software

The code is written in Arduino IDE, which controls both the hardware components and the communication to the database. The code is divided into the following sections:

  • The define section: where important information is stored, such as the Wi-Fi SSID and password for the ESP32 node to connect to the network, the API_KEY, DATABASE_URL, USER_EMAIL, USER_PASSWORD needed to connect to the Firebase Realtime database, hardware information, such as which pins are connected to which external devices, information about the screen width and height, information about the A/C commands that need to be sent to control the unit
  • The init section: in this section the needed peripherals and systems are initialized, such as the Wi-Fi, the OLED display, the temperature sensor, the infrared sender, the connection to the database etc.
  • The loop section: in this section, 3 different steps are happening: the temperature read and print on the display, the temperature database logging and the database read for the control singals.

The temperature is read from the sensor and printed on the display every two seconds:

    if(millis() - writePrevDisplay > writeDisplayTimer || writePrevDisplay == 0) {  
        writePrevDisplay = millis();  

The temperature is written to the database. This is done by using a JSON that contains the timestamp (in epoch form) and the temperature, which is logged to the Realtime database each minute.

  if (Firebase.ready() && (millis() - sendDataPrevMillis > timerDelay || sendDataPrevMillis == 0)){
    sendDataPrevMillis = millis();

    //Get current timestamp
    timestamp = getTime();
    Serial.print ("time: ");
    Serial.println (timestamp);

    parentPath= databasePath + "/" + String(timestamp);
    json.set(tempPath.c_str(), String(dht.readTemperature()));
    json.set(timePath, String(timestamp));
    Serial.printf("Set json... %s\n", Firebase.RTDB.setJSON(&fbdo, parentPath.c_str(), &json) ? "ok" : fbdo.errorReason().c_str());

In the control section, control data (information about the state of the A/C unit, about which temperature should be set, about which fan speed should be set) is read from the database, and accordingly the needed IR command is sent. In this section, the previous A/C state is saved, so that commands will be sent to the A/C unit only in case of a change.

  if(millis() - prevDataQuery > dataQueryTimer || prevDataQuery == 0) {
    prevDataQuery = millis();

    String ac_status_path = controlPath + ac_status;
    String ac_temp_path = controlPath + ac_temp;
    String fan_speed_path = controlPath + fan_speed;
    int ac_status_val, ac_temp_val, fan_speed_val;

    bool s = Firebase.RTDB.getInt(&fbdo, ac_status_path.c_str(), &ac_status_val);
    s = Firebase.RTDB.getInt(&fbdo, ac_temp_path.c_str(), &ac_temp_val);
    s = Firebase.RTDB.getInt(&fbdo, fan_speed_path.c_str(), &fan_speed_val);
    if(prev_ac_temp == ac_temp_val && prev_ac_status == ac_status_val && prev_fan_speed == fan_speed_val) {
    } else {
      sendIRCmd(ac_status_val, ac_temp_val, fan_speed_val);
    prev_ac_temp = ac_temp_val;
    prev_ac_status = ac_status_val;
    prev_fan_speed = fan_speed_val;

For the embedded part, the remote control of the A/C unit was reverse engineered to get the set temperature commands, or set fan speed commands. The commands format is a 16 bit value, where the most significant 8 bits are the temperature setting and the least significant bits were the fan speed. The A/C can be turned on by using any temperature/fan speed command. The turn off command is done by sending 0x7DE command.

#define IR_ADDR      0xB24D
#define OFF_CMD      0x7DE
#define DEG_17_CMD   0x00
#define DEG_18_CMD   0x08
#define DEG_19_CMD   0x0C
#define DEG_20_CMD   0x04
#define DEG_21_CMD   0x06
#define DEG_22_CMD   0x0E
#define DEG_23_CMD   0x0A
#define DEG_24_CMD   0x02
#define DEG_25_CMD   0x03
#define FAN_1_CMD    0xF9
#define FAN_2_CMD    0xFA
#define FAN_3_CMD    0xFC
#define FAN_AUTO_CMD 0xFD

The flow chart of the embedded software can be below:

Web Application

The web application's purpose is to create a user friendly graphical user interface for analyzing the temperature samples taken from the ESP32 board, and for controlling the A/C unit inside the room. The Web Application is created based on a Firebase example that creates all the necessary configuration for the project to connect to the database. It even has a login module, which takes the credentials from the Firebase website authentication settings.

After logging in with the credentials, the data page is shown. In this page, one can see the real time updated Grafana dashboard temperature graph, the last read temperature and the possibility of seeing and deleting all the data written to the database.

On the upper navbar, the control button is shown, button which will change the page to the main control panel, where settings for the A/C state, A/C fan speed and A/C temperature control will be shown.

After selecting all the settings for the A/C a write is made to the database, in the control fields.

Database configuration

The database used is the Realtime Database from Firebase, with the following configuration:

The data is stored under the node UsersData, which has a child node named using the user id. After that, two children nodes, one for control and the other for readings is created. The control node contains three data: the ac_status (which indicates if the A/C unit has been requested to turn on/off), the ac_temp (which indicated the temperature the A/C system should be set to) and the fan_speed (the fan speed the A/C should be set to). The readings section contains multiple nodes, each node's name being the timestamp at which the data has been acquired. This node contains both the temperature and the timestamp of acquisition.

Grafana Dashboard

The Grafana Dashboard was used to create the temperature graph that is shown in the Web Application. Because the Grafana API doesn't support Firebase Realtime database connection, a further step was created using the Google Sheets API with Google Script. The Realtime database was connected to the Google Sheets API, and a Google Script was created which synchronizes the sheets document to the database. This was done by creating a trigger in the Google Scripts environment.

  var base = FirebaseApp.getDatabaseByUrl(firebaseUrl, secret);
  var dataSet = [base.getData()];
  var readings = dataSet[0]["UsersData"][db_uid]["readings"];
  var temps = [];
  var timestamps = [];
  for (var obj in readings) {
    var timestamp_str = readings[obj]["timestamp"];
    var timestamp_int = parseInt(timestamp_str);
    timestamps.push(new Date(timestamp_int * 1000).toLocaleString("en-US"));

  var rows = [];
  for(i = 0; i < temps.length; i++) {
    rows.push([timestamps[i], temps[i]]);

  dataRange = sheet.getRange(2, 1, rows.length, 2);


In conclusion, the ESP32 is a very suited hardware component for IoT applications, due to it's hardware integration of Wi-Fi and Bluetooth. The usage of Firebase was really facile, due to the multitude of internet examples.
The most difficult task while creating this project was to understand the infrared commands that were coming from the remote control of the A/C unit.


iothings/proiecte/2023/tempandmonitorsystem.txt · Last modified: 2024/01/08 14:57 by andrei.ulmamei
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0