Во время карантина появилось много времени, которое захотелось потратить с пользой и закрепить свои знания полученные из разных сфер, из этого получился небольшой проект, который с лёгкостью может повторить любой разработчик.
Я студент, живу в общежитии. В комнате всегда проблемы с микро-климатом: то жарко, то холодно, то воздуха не хватает, а для комфортной работы и учёбы хотелось жить в нормальных условиях.
Итак, приступим.
Необходимый минимум
В углу завалялся старый, но достаточно мощный вентилятор.
Также есть 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, которому предстояло попасть на сервер. Главная страница сейчас выглядит так:
Как видим, всё кратко и ёмко. Можно изменить статус устройства и посмотреть показания датчиков за определённый промежуток времени.
Итоги
Тестируем, что получилось:
Всё работает! Вентилятор запускается и выключается почти без задержек.
Планируется добавить графики с показаниями датчиков, систему авторизации, чтобы другие пользователи могли развернуть эту систему у себя дома. Можно легко настроить значения, при которых устройства будут включаться автоматически. Также количество датчиков и устройств предполагается увеличить.
Если заинтересовал проект, то могу сделать отдельные статьи по каждому шагу разработки.