Во время карантина появилось много времени, которое захотелось потратить с пользой и закрепить свои знания полученные из разных сфер, из этого получился небольшой проект, который с лёгкостью может повторить любой разработчик.

Я студент, живу в общежитии. В комнате всегда проблемы с микро-климатом: то жарко, то холодно, то воздуха не хватает, а для комфортной работы и учёбы хотелось жить в нормальных условиях.
Итак, приступим.
Необходимый минимум
В углу завалялся старый, но достаточно мощный вентилятор.

Также есть Arduino Uno, оставшаяся со школьных времен.

Дополнительно купил датчик температуры и влажности, реле-модули. Для проекта принято решение арендовать VPS на Centos 7.
Разработка
Пишем скетч для Arduino. Он умеет отправлять данные с датчика и принимать информацию с компьютера.
#include <Adafruit_GFX.h> #include <Adafruit_PCD8544.h> #include "DHT.h" #define DHTPIN 2 // номер пина, к которому подсоединен датчик int fanPin = 3; byte incomingByte; DHT dht(DHTPIN, DHT22); void setup() { pinMode(fanPin, OUTPUT); Serial.begin(9600); dht.begin(); } void loop() { // Задержка 2 секунды между измерениями delay(2000); //Считываем влажность float h = dht.readHumidity(); // Считываем температуру float t = dht.readTemperature(); // Проверка удачно прошло ли считывание. if (isnan(h) || isnan(t)) { Serial.println("Не удается считать показания"); return; } Serial.print(" "); Serial.print( h ); Serial.print(" "); Serial.print(t); Serial.print(" \n"); if (Serial.available() > 0) { incomingByte = Serial.read(); if(incomingByte == '0'){ digitalWrite(fanPin, HIGH); } else if (incomingByte == '1'){ digitalWrite(fanPin, LOW); } Serial.print("I received: "); Serial.println(incomingByte, DEC); } }
После этого пишем небольшую программу на ASP.Net Сore которая принимает данные с Arduino и пишет их в базу данных. А также читает данные из БД, включает / отключает реле-модули через Arduino.
public void Program() { weatherContext db = new weatherContext(); var serialPort = new SerialPort("COM3") { BaudRate = 9600, Parity = Parity.None, StopBits = StopBits.One, DataBits = 8, Handshake = Handshake.None }; serialPort.Open(); var reg = new Regex(@"[0-9]{2}\.[0-9]{2}\s[0-9]{2}\.[0-9]{2}"); List<DeviceDTO> deviceDTOs = new List<DeviceDTO>(); var userDevices = db.UserDevices.Where(d => d.UserId == 0); foreach (var userDevice in userDevices) { var device = db.Devices.Where(d => d.Id == userDevice.DeviceId).FirstOrDefault(); if (device != null) { DeviceDTO deviceDTO = new DeviceDTO() { Id = device.Id, Status = device.Status, Name = device.Name }; deviceDTOs.Add(deviceDTO); } } while (true) { DeviceActivator(serialPort, deviceDTOs); string message = serialPort.ReadExisting(); Console.WriteLine("message is: " + message); var match = reg.Match(message); IFormatProvider formatter = new NumberFormatInfo { NumberDecimalSeparator = "." }; if (match.Success) { string a = message.Substring(0, 5); double humidity = double.Parse(a, formatter); double temperature = double.Parse(message.Substring(6, 5), formatter); List<MeteringWriteDTO> meterings = new List<MeteringWriteDTO>(); var meteringTemperature = new MeteringWriteDTO() { Id = meteringCount + 1, Date = DateTime.UtcNow, Value = temperature, SensorId = 0, }; meterings.Add(meteringTemperature); var meteringHumidity = new MeteringWriteDTO() { Id = meteringCount + 1, Date = DateTime.UtcNow, Value = humidity, SensorId = 1, }; meterings.Add(meteringHumidity); SetSecondMetering(meterings); Console.WriteLine(message + DateTime.UtcNow + '\n'); System.Threading.Thread.Sleep(1000); } if (DateTime.UtcNow.Second == 0) { SetMinuteMetering(); } if (DateTime.UtcNow.Minute == 0 && DateTime.UtcNow.Second == 0) { SetHourMetering(); } if (DateTime.UtcNow.Hour == 0 && DateTime.UtcNow.Minute == 0 && DateTime.UtcNow.Second == 0) { AddDay(); } } }
На сервере развернулась небольшая база данных на PostgreSQL.
Таблица, куда пишутся данные с датчиков выглядит так:

Также есть таблица, хранящая информацию об устройствах:

И с этого момента началось создание клиент-серверного приложения на ASP.NET Core, которому предстояло попасть на сервер. Главная страница сейчас выглядит так:

Как видим, всё кратко и ёмко. Можно изменить статус устройства и посмотреть показания датчиков за определённый промежуток времени.
Итоги
Тестируем, что получилось:

Всё работает! Вентилятор запускается и выключается почти без задержек.
Планируется добавить графики с показаниями датчиков, систему авторизации, чтобы другие пользователи могли развернуть эту систему у себя дома. Можно легко настроить значения, при которых устройства будут включаться автоматически. Также количество датчиков и устройств предполагается увеличить.
Если заинтересовал проект, то могу сделать отдельные статьи по каждому шагу разработки.
