Продолжаем разговор за бюджетный умный дом, в этой статье мы соберем простой модуль на Arduino Nano. Предыдущая статья, посвященная настройке кластера openHAB, находится тут.
Я выбрал Arduino Nano, потому что для него существует вот такой очень удобный шилд:
К такому шилду удобно подключать все что угодно при помощи кабельных наконечников НШВИ 0,5-8. А VCC и GND я подключаю через латунные шины, т.к. к ним надо подключать кучку проводов. Тоже получилось удобно. Собрал все в корпусе распределительной коробки. Вот так это в итоге выглядит:
Это пример модуля для кухни. К нему подключены два реле, для управления светом, сенсорный выключатель, датчик движения, датчик открытия окна (геркон), два датчика протечки, датчик газа MQ2 (т.к. присутствует и печное отопление, хочу знать CO), датчик температуры. Для связи модуля с MQTT-брокером используется Ethernet модуль enc28j60.
Вместо схемы подключения, предлагаю Вам такую таблицу, по-моему тут все предельно понятно:
Arduino Pin |
Module Pin |
Module |
D2 |
In |
Реле 1 |
GND |
GND |
|
VCC |
VCC |
|
D7 |
In |
Реле 2 |
GND |
GND |
|
VCC |
VCC |
|
D3 |
S |
Датчик протечки 1 |
GND |
- |
|
VCC |
+ |
|
D4 |
S |
Датчик протечки 2
|
GND |
- |
|
VCC |
+ |
|
D5 |
Желтый (DQ) |
Датчик температуры DS18b20 *нужен резистор на 4.7 кОм между DQ и VCC |
GND |
Черный |
|
VCC |
Красный |
|
D6 |
Out |
Инфракрасный датчик движения
|
GND |
GND |
|
VCC |
VCC |
|
D8 |
1 |
Датчик открытия |
GND |
2 |
|
D9 |
SIG |
Сенсорный Выключатель |
GND |
GND |
|
VCC |
VCC |
|
A0 |
Analog Out |
Датчик газа MQ2 *цифровой выход не использую |
GND |
GND |
|
VCC |
VCC |
|
3.3v |
VCC |
Модуль enc28j60 *для UNO пин CS нужно подключать к D8 |
GND |
GND |
|
D10 |
CS |
|
D11 |
SI |
|
D12 |
SO |
|
D13 |
SCK |
Примеры, модулей (хотел разместить в таблице справа. но не получилось):
Подобных модулей умного дома у меня будет около десятка, все оснащены разными датчиками и исполнительными механизмами, т.к. это ардуино, то все очень быстро переписывается под разные нужды.
Я использую последнюю на данный момент Arduino IDE 2.3.2.
Чтобы собрать скетч, нужно установить некоторые библиотеки. В Arduino IDE идем в Tools->Manage Libraries.
И тут устанавливаем:
OneWire 2.3.7;
UIPEthernet 2.0.12;
PubSubClient 2.7.0.
Целеком скетч можно посмотреть тут:
Hidden text
#include <avr/wdt.h>
#include <OneWire.h>
#include "PubSubClient.h"
#include <UIPEthernet.h>
#define DEBUG 1 // Debug output to serial console
const byte Relay1Pin = 2;
const byte w1Pin = 3;
const byte w2Pin = 4;
OneWire ds(5);
const byte md1Pin = 6;
const byte Relay2Pin = 7;
const byte Win1Pin = 8;
const byte Button1Pin = 9;
const byte MQ2pin = A0;
byte tmp = 0;
byte w1Value = 0;
byte w2Value = 0;
byte md1Value = 0;
byte win1Value = 0;
byte button1Value = 0;
byte l2Status = 0;
unsigned int gasValue = 0;
unsigned long mytime = 0;
const char* mqtt_server = "10.20.10.40";
const char* mqttUser = "arduino-kitchen-01";
const char* mqttPassword = "password123";
#define MACADDRESS 0x00, 0x01, 0x02, 0x03, 0x04, 0x05
#define MYIPADDR 10, 20, 10, 50
#define MYIPMASK 255, 255, 255, 0
#define MYDNS 10, 20, 10, 10
#define MYGW 10, 20, 10, 10
char buf[10]; // Buffer to store the sensor value
int updateInterval = 10000; // Interval in milliseconds
EthernetClient espClient;
PubSubClient client(espClient);
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
#ifdef DEBUG
Serial.print(F("MQTT connection..."));
#endif
wdt_disable();
// Attempt to connect
if (client.connect("arduino-KITCHEN-01", mqttUser, mqttPassword)) {
#ifdef DEBUG
Serial.println("connected");
#endif
w1Value = digitalRead(w1Pin);
pubw1();
w2Value = digitalRead(w2Pin);
pubw2();
md1Value = digitalRead(md1Pin);
pubmd1();
win1Value = digitalRead(Win1Pin);
pubwin1();
client.subscribe("oh/kitchen/l1");
client.subscribe("oh/kitchen/l2");
wdt_enable(WDTO_8S);
} else {
#ifdef DEBUG
Serial.print(F("failed, rc="));
Serial.print(client.state());
Serial.println(F(" try again in 5s"));
#endif
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void sensors() {
byte data_t[2];
ds.reset(); // Начинаем взаимодействие со сброса всех предыдущих команд и параметров
ds.write(0xCC); // Даем датчику DS18b20 команду пропустить поиск по адресу. В нашем случае только одно устрйоство
ds.write(0x44); // Даем датчику DS18b20 команду измерить температуру. Само значение температуры мы еще не получаем - датчик его положит во внутреннюю память
delay(1500);
ds.reset(); // Теперь готовимся получить значение измеренной температуры
ds.write(0xCC);
ds.write(0xBE); // Просим передать нам значение регистров со значением температуры
// Получаем и считываем ответ
data_t[0] = ds.read(); // Читаем младший байт значения температуры
data_t[1] = ds.read(); // А теперь старший
float temperature = ((data_t[1] << 8) | data_t[0]) * 0.0625;
dtostrf(temperature, 4, 1, buf);
#ifdef DEBUG
Serial.print("Temp: ");
Serial.println(buf);
#endif
client.publish("oh/kitchen/temp", buf);
gasValue = analogRead(MQ2pin);
dtostrf(gasValue, 4, 1, buf);
#ifdef DEBUG
Serial.print("gasValue: ");
Serial.println(buf);
#endif
client.publish("oh/kitchen/gas", buf);
}
void callback(char* topic, byte* message, unsigned int length) {
#ifdef DEBUG
Serial.print(F("Msg arrived on topic: "));
Serial.print(topic);
Serial.print(". Msg: ");
#endif
String messageTemp;
for (int i = 0; i < length; i++) {
#ifdef DEBUG
Serial.print((char)message[i]);
#endif
messageTemp += (char)message[i];
}
#ifdef DEBUG
Serial.println();
#endif
if (String(topic) == "oh/kitchen/l2") {
if (String(messageTemp) == "1") {
l2Status = 1;
digitalWrite(Relay1Pin, 0);
}
if (String(messageTemp) == "0") {
l2Status = 0;
digitalWrite(Relay1Pin, 1);
}
}
if (String(topic) == "oh/kitchen/l1") {
if (String(messageTemp) == "1") {
digitalWrite(Relay2Pin, 0);
}
if (String(messageTemp) == "0") {
digitalWrite(Relay2Pin, 1);
}
}
}
void setup() {
wdt_disable();
digitalWrite(Relay1Pin, 1);
digitalWrite(Relay2Pin, 1);
pinMode(Relay1Pin, OUTPUT);
pinMode(Relay2Pin, OUTPUT);
pinMode(w1Pin, INPUT_PULLUP);
pinMode(w2Pin, INPUT_PULLUP);
pinMode(md1Pin, INPUT_PULLUP);
pinMode(Win1Pin, INPUT_PULLUP);
pinMode(Button1Pin, INPUT_PULLUP);
#ifdef DEBUG
Serial.begin(9600);
#endif
uint8_t mac[6] = { MACADDRESS };
uint8_t myIP[4] = { MYIPADDR };
uint8_t myMASK[4] = { MYIPMASK };
uint8_t myDNS[4] = { MYDNS };
uint8_t myGW[4] = { MYGW };
Ethernet.begin(mac, myIP, myDNS, myGW, myMASK);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
#ifdef DEBUG
Serial.println(F("\nStart!"));
#endif
}
void pubw1() {
client.publish("oh/kitchen/w1", itoa(w1Value, buf, 2));
#ifdef DEBUG
Serial.print("W1: ");
Serial.println(w1Value);
#endif
}
void pubw2() {
client.publish("oh/kitchen/w2", itoa(w2Value, buf, 2));
#ifdef DEBUG
Serial.print("W2: ");
Serial.println(w2Value);
#endif
}
void pubmd1() {
client.publish("oh/kitchen/md1", itoa(md1Value, buf, 2));
#ifdef DEBUG
Serial.print("md1: ");
Serial.println(md1Value);
#endif
}
void pubwin1() {
client.publish("oh/kitchen/win1", itoa(win1Value, buf, 2));
#ifdef DEBUG
Serial.print("win1: ");
Serial.println(win1Value);
#endif
}
void loop() {
wdt_reset();
if (!client.connected()) { reconnect(); }
client.loop();
if (millis() - mytime > updateInterval) {
mytime = millis();
sensors();
}
tmp = digitalRead(w1Pin);
if (tmp != w1Value) {
w1Value = tmp;
pubw1();
}
tmp = digitalRead(w2Pin);
if (tmp != w2Value) {
w2Value = tmp;
pubw2();
}
tmp = digitalRead(md1Pin);
if (tmp != md1Value) {
md1Value = tmp;
pubmd1();
}
tmp = digitalRead(Win1Pin);
if (tmp != win1Value) {
win1Value = tmp;
pubwin1();
}
if (digitalRead(Button1Pin) == 0 && button1Value == 0) {
char* tmp = "0";
if (l2Status == 0) {
tmp = "1";
}
client.publish("oh/kitchen/l2", tmp);
button1Value = 1;
digitalWrite(Relay1Pin, 0);
} else if (digitalRead(Button1Pin) == 1) {
button1Value = 0;
}
}
Опишу подробнее, упустив однотипные куски кода и отладку.
Указываем пины ардуины для наших датчиков и реле:
const byte Relay1Pin = 2; //реле 1
const byte w1Pin = 3; //датчик протечки 1
const byte w2Pin = 4; //датчик протечки 2
OneWire ds(5); //датчик DS18b20
const byte md1Pin = 6; //датчик движения
const byte Relay2Pin = 7; //реле 2
const byte Win1Pin = 8; //датчик открытия окна
const byte Button1Pin = 9;//сенсорный ввыключатель
const byte MQ2pin = A0; //датчик газа
Укажим параметры соединения для MQTT:
const char* mqtt_server = "10.20.10.40";
const char* mqttUser = "arduino-kitchen-01";
const char* mqttPassword = "password123";
Так же укажем сетевые настройки:
#define MACADDRESS 0x00,0x01,0x02,0x03,0x04,0x05
#define MYIPADDR 10,20,10,50
#define MYIPMASK 255,255,255,0
#define MYDNS 10,20,10,10
#define MYGW 10,20,10,10
Не забывем менять MACADDRESS и MYIPADD для каждого подобного устройства. Инициализация:
void setup(){
//выключаем watchdog
wdt_disable();
//инициализируем GPIO, для входных линий указываем использовать подтягиваюший резистор (INPUT_PULLUP));
digitalWrite(Relay1Pin, 1);
pinMode(Relay1Pin, OUTPUT);
pinMode(w1Pin, INPUT_PULLUP);
//инициализация Ethernet
uint8_t mac[6] = {MACADDRESS};
uint8_t myIP[4] = {MYIPADDR};
uint8_t myMASK[4] = {MYIPMASK};
uint8_t myDNS[4] = {MYDNS};
uint8_t myGW[4] = {MYGW};
Ethernet.begin(mac,myIP,myDNS,myGW,myMASK);
//инициализация библиотеки MQTT
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
Тут “callback” это функция, которая вызывается если в топик, на который мы подписаны, прилетает какое-то значение. Вот эта функция (в сокращении):
void callback(char* topic, byte* message, unsigned int length) {
String messageTemp;
for (int i = 0; i < length; i++) {
messageTemp += (char)message[i];
}
if (String(topic) == "oh/kitchen/l2") {
if (String(messageTemp) == "1") {
l2Status = 1;
digitalWrite(Relay1Pin, 0);
}
if (String(messageTemp) == "0") {
l2Status = 0;
digitalWrite(Relay1Pin, 1);
}
}
}
т.е. тут мы из канала "oh/kitchen/l2" получаем или 0 или 1, тем самым включаем или выключаем реле. Периодически из основного цикла вызывается функция опроса датчиков:
void sensors() {
byte data_t[2];
ds.reset();
ds.write(0xCC);
ds.write(0x44);
delay (1500);
ds.reset();
ds.write(0xCC);
ds.write(0xBE);
data_t[0] = ds.read();
data_t[1] = ds.read();
float temperature = ((data_t[1] << 8) | data_t[0]) * 0.0625;
dtostrf(temperature,4, 1, buf);
client.publish("oh/kitchen/temp", buf);
gasValue = analogRead(MQ2pin);
dtostrf(gasValue,4, 1, buf);
client.publish("oh/kitchen/gas", buf);
}
Тут считываем температуру и содержание CO, после чего пишем в соответствующие каналы, предварительно преобразовав значения в строку. Основной цикл, тоже в сокращении:
void loop(){
wdt_reset(); //сбрасываем watchdog таймер
//если соединение c mqtt не установлено, то устанавливаем
if (!client.connected()) { reconnect(); }
client.loop();
//время от времени дергаем опрос датчиков
if (millis()-mytime>updateInterval){
mytime=millis();
sensors();
}
//обработаем сенсорную кнопку
if (digitalRead(Button1Pin) == 0 && button1Value == 0) {
char* tmp = "0";
if (l2Status == 0) {tmp = "1";}
client.publish("oh/kitchen/l2", tmp);
button1Value = 1;
digitalWrite(Relay1Pin, 0);
} else if (digitalRead(Button1Pin) == 1) {
button1Value = 0;
}
//остальные датчики
tmp = digitalRead(w1Pin);
if (tmp != w1Value) {
w1Value = tmp;
pubw1();
}
}
Прямо тут обрабатываются все простые датчики и пишутся в соответствующие каналы, но через определенную функцию, для примера тут pubw1(), сделано для экономии памяти, т.к. эта функция вызывается еще из reconnect(), для того чтобы при старте передать актуальные значения всех датчиков, вот эта функция:
void reconnect() {
while (!client.connected()) {
//выключаем watchdog, т.к. соединение может устанавливаться более 8 секунд, а либа его не сбрасывает
wdt_disable();
// Attempt to connect
if (client.connect("arduino-KITCHEN-01", mqttUser, mqttPassword)) {
w1Value = digitalRead(w1Pin);
pubw1();
w2Value = digitalRead(w2Pin);
pubw2();
md1Value = digitalRead(md1Pin);
pubmd1();
win1Value = digitalRead(Win1Pin);
pubwin1();
//тут же подписываемся на необходимые топики
client.subscribe("oh/kitchen/l2");
//и включаем watchdog
wdt_enable(WDTO_8S);
}
}
}
Вот и весь скетч. Приведу еще конфиг openHAB с моими item’ами:
[root@srv-oh-01 ~]# cat /etc/openhab/items/pleshki.items
Hidden text
Group Home "Плешки" <house> ["Building"]
Group GF "Первый этаж" <groundfloor> (Home) ["GroundFloor"]
Group OU "За домом" <garden> (Home) ["Outdoor"]
Group AT "Второй этаж" <attic> (Home) ["Attic"]
Group GF_FamilyRoom "Гостиная" <parents_2_4> (Home, GF) ["Room"]
Group GF_Kitchen "Кухня" <kitchen> (Home, GF) ["Kitchen"]
Group OU_Toilet "Туалет" <toilet> (Home, OU) ["Bathroom"]
Group AT_StorageRoom "Кладовка" <suitcase> (Home, AT) ["Room"]
Switch Security "Охрана" <security> (Home,house,GF_FamilyRoom) ["Security", "Switchable"]
Number OU_Temperature "Температура" <temperature> (OU, garden, gTemperature) ["Temperature"]
Number OU_Humidity "Влажность [%.2f]%unit%" <Humidity> (OU, garden, gHumidity) ["Humidity"]
Number OU_Pressure "Атмосферное давление [%.1f]%unit%" <Pressure> (OU, garden, gPressure) ["Pressure"]
Number OU_windDir_Num "Направление ветра [%s] градусы" <wind> (OU, garden, gWeather)
String OU_windDir "Направление ветра [%s]" <wind> (OU, garden, gWeather)
Dimmer GF_FamilyRoom_Light "Освещение" <light> (GF_FamilyRoom, gLight) ["Light"]
Rollershutter GF_FamilyRoom_Shutter_1 "Шторы 1" <rollershutter> (GF_FamilyRoom, gShutter) ["Rollershutter"]
Rollershutter GF_FamilyRoom_Shutter_2 "Шторы 2" <rollershutter> (GF_FamilyRoom, gShutter) ["Rollershutter"]
Rollershutter GF_FamilyRoom_Shutter_3 "Шторы 3" <rollershutter> (GF_FamilyRoom, gShutter) ["Rollershutter"]
Rollershutter GF_FamilyRoom_Shutter_4 "Шторы 4" <rollershutter> (GF_FamilyRoom, gShutter) ["Rollershutter"]
Number GF_FamilyRoom_Temperature "Температура" <temperature> (GF_FamilyRoom, gTemperature) ["Temperature"]
Contact GF_FamilyRoom_Motion "Датчик движения в гостиной" <motion> (GF_FamilyRoom, gMotion) ["MotionDetector", "Switchable"]
Number GF_FamilyRoom_Gas "Содержание CO [%.1f]%unit%" <gas> (GF_FamilyRoom, gGas) ["Gas"]
Number GF_FamilyRoom_Humidity "Влажность" <Humidity> (GF_FamilyRoom, gHumidity) ["Humidity"]
Switch GF_Kitchen_Light_1 "Освещение общее" <light> (GF_Kitchen, gLight) ["Light", "Switchable"]
Switch GF_Kitchen_Light_2 "Освещение рабочей зоны" <light> (GF_Kitchen, gLight) ["Light", "Switchable"]
Rollershutter GF_Kitchen_Shutter_1 "Шторы 1" <rollershutter> (GF_Kitchen, gShutter) ["Rollershutter"]
Rollershutter GF_Kitchen_Shutter_2 "Шторы 2" <rollershutter> (GF_Kitchen, gShutter) ["Rollershutter"]
Rollershutter GF_Kitchen_Shutter_3 "Шторы 3" <rollershutter> (GF_Kitchen, gShutter) ["Rollershutter"]
Number GF_Kitchen_Temperature "Температура" <temperature> (GF_Kitchen, gTemperature) ["Temperature"]
Number GF_Kitchen_Gas "Содержание CO [%.1f]%unit%" <gas> (GF_Kitchen, gGas) ["Gas"]
Contact GF_Kitchen_Water_1 "Датчик протечки - раковина" <water> (GF_Kitchen, gWater) ["Water"]
Contact GF_Kitchen_Water_2 "Датчик протечки - стиралка" <water> (GF_Kitchen, gWater) ["Water"]
Contact GF_Kitchen_Motion "Датчик движения на кухне" <motion> (GF_Kitchen, gMotion) ["MotionDetector"]
Switch OU_Toilet_Light "Освещение" <light> (OU_Toilet, gLight) ["Light", "Switchable"]
Contact AT_StorageRoom_Motion "Датчик движения" <motion> (AT_StorageRoom, gMotion) ["MotionDetector", "Switchable"]
Contact GF_Kitchen_Window_1 "Окно 1 на кухне" <window> (GF_Kitchen, gWindow) ["Window"]
Contact GF_Kitchen_Door_1 "Дверь 1 на кухне" <door> (GF_Kitchen, gDoor) ["Door"]
Contact GF_Kitchen_Button_1 "Кнопка у плиты" <switch> (GF_Kitchen, gButton) ["Button"]
Group:Switch:OR(ON, OFF) gLight "Освещение" <light> (Home) ["Light", "Switchable"]
Group:Rollershutter:OR(UP, DOWN) gShutter "Шторы" <rollershutter> (Home) ["Rollershutter"]
Group:Number:AVG gTemperature "Температура" <temperature> (Home) ["Temperature"]
Group:Number:AVG gGas "Содержание CO" <gas> (Home) ["Gas"]
Group:Number:AVG gHumidity "Влажность" <humidity> (Home) ["Humidity"]
Group:Contact:OR(OPEN, CLOSED) gMotion "Датчик движения" <motion> (Home) ["MotionDetector"]
Group:Contact:OR(OPEN, CLOSED) gWater "Датчик протечки" <water> (Home) ["Water"]
Group:Contact:OR(OPEN, CLOSED) gWindow "Окно" <window> (Home) ["Window"]
Group:Contact:OR(OPEN, CLOSED) gDoor "Дверь" <door> (Home) ["Door"]
DateTime Date "Дата [%1$td.%1$tm.%1$tY]" <calendar> { channel="ntp:ntp:ourhome:dateTime" }
DateTime CurTime "Время [%1$tR]" <clock> { channel="ntp:ntp:ourhome:dateTime" }
DateTime Sunrise_Time "Sunrise [%1$tH:%1$tM]" { channel="astro:sun:local:rise#start" }
DateTime Sunset_Time "Sunset [%1$tH:%1$tM]" { channel="astro:sun:local:set#start" }
Number Day "Day [%d]" <day> (Home)
String VoiceCommand
В интерфейсе openHAB это все выглядит так:
Автоматизация. В ночное время суток при активации датчика движения, будет включаться свет на кухне. Вот такое правило отрабатывает:
rule "Light on kitten work zone"
when
Item GF_Kitchen_Motion changed
then
if (Day.state == 0){
if (GF_Kitchen_Motion.state == OPEN){
if (GF_Kitchen_Light_2.state == OFF){
logInfo("pleshki.rules", "GF_Kitchen_Motion is: " + GF_Kitchen_Motion.state )
sendCommand(GF_Kitchen_Light_2, ON)
}
}
}
if (GF_Kitchen_Motion.state == CLOSED){
if (GF_Kitchen_Light_2.state == ON){
logInfo("pleshki.rules", "GF_Kitchen_Motion is: " + GF_Kitchen_Motion.state )
sendCommand(GF_Kitchen_Light_2, OFF)
}
}
end
На сегодня все. В следующий раз я напишу, как можно управлять рольшторами при помощи самодельного привода.
Комментарии (12)
pav18
09.04.2024 10:39Сразу скажу. Питалово заводите отдельно. У меня идет 12В от отдельного блока питания и перед каждым датчиком стоит стабилизатор на 5 или 3.3В Ардуина не потянет такие большие нагрузки.
suprimex
09.04.2024 10:39Очень хотелось бы услышать про надёжность всей этой солянки. Сколько недель.. месяцев она работает без отваливающихся компонентов...
Speccyfan Автор
09.04.2024 10:39Сам OpenHAB более года, а ардуины я постоянно что-то дергал и переделывал, поэтому более месяца аптайма нет.
Albert2009Zi
09.04.2024 10:39Меня больше смущает отстутсвие провода PE (заземляющего) во всей этой конструкции... Хотя автор делал все сам и для себя, соответственно априори выключит автомат в электрощитке перед тем, как лезть в своё изделие. А так за статью респект.
Vilos
09.04.2024 10:39В этом всём "умном" (или "полоумном" уж не знаю) доме всегда огорчает наличие кучи всяких проводов для релюшек, питания, передачи данных и прочее...присматривался ко всяким ZigBee и аналогам, однако питание все равно никуда не денешь, электричество пока только по проводам гуляет...а ковырять ремонт ради "сомнительного удобства", так себе...буду руками свет включать пока. Для академического интереса - да, можно побаловаться, поэкспериментировать...и дааа, как и 20 лет назад бОльшая часть задач решается обычными датчиками с проводами (реле времени, датчики света и проч), абсолютно без микроконтроллера; просто имея припой, паяльник и горстку компонентов. Пока не вижу ни одного, по-настоящему умного дома.
В моем понимании умный дом этот не только куча датчиков и исполнительных механизмов, умный он станет тогда, когда он сможет сам обучаться и делать сценарии; начиная от того что в пятницу хозяин приходит домой обычно позже (но не всегда), он смотрит положение моего телефона на карте и знает, что сейчас я ближайшие 2 часа дома не буду - а значит топить котел не нужно, однако увидев что я поехал домой он он понимает что нужно подготовить комфортную температуру дома. Либо другой кейс я ночью встаю в туалет и он понимает что яркий свет мне не нужен, и тихонечко плавно включает свет по мере моего перемещения по дому, однако если при этом же сценарии он видит что гуляет по дому не хозяин, а кот (собака/хомячок)..., то эти ребята и без света обойдутся. Третий кейс - ребенок не засыпает или плохо засыпает, дом включает тихонько шум дождя в его комнате, делает прохладной температуру и организм сам стремится под тепленькое уютное одеялко...Всех сценариев в жизни не предусмотришь, однако умный дом на то и умный, что бы понимать, что происходит и создавать скрипты как ему действовать в той или иной ситуации, а пока умных домов нет, есть дома с датчиками и механизмами...как и 20-30 лет назад.
Speccyfan Автор
09.04.2024 10:39Все это вполне реализуемо сейчас. Я постепенно к этому и иду. К модулям,
где не нужно 220В, тяну только витую пару, работает по PoE. Все беспроводное
только там, где слишком неудобно и далеко тянуть кабель, т.к. не
надежно. На реле времени, то что вы описали не построить, поэтому нужен
OpenHAB, Home Assistant, etc, который и будет логику всю выполнять, уже и
искусственный интеллект можно прикрутить, так что все будет.
ZK413
09.04.2024 10:39Я вот не как не пойму нескольких вещей:
Что мешает использовать переменный ток? 12-24 переменки, меньше просадок, а если "оборудование" понимает толь DC, есть диодный мост.
По какой причине не использовать КСВВнг(А)-LS (используется например в ОПС, САУЭ,..)? Он тонкий и дешевый, а главное безопасный.
Для чего тащить 100500 реле? Умный дом подразумевает отсутсвие распред.коробок. Тянем люстру и выключатель в щит. На люстру ВВГнг(А)-ls 3х1,5, на розетки ВВГнг(А)-ls 3x2,5, на все выключатели и датчики КСВВнг(А)-LS. Это безопасно, и не противоречит ПУЭ, ГОСТам, и СНИПам.
-
Что мешает использовать программируемое реле, промышленного типа (да ардуинка это программируемое реле, и не надо тешить себя фантазиями) например тот же овен пр200? Он имеет корпус, крепление на динрейку, и штатные расширения. Тот же ардуино, только со всеми разрешениями (им можно управлять шкафами автоматики энергоснабжения, пожаротушения, газовыми установками и т.д.), тестыми, гарантией на отказоустойчивость. В общем не хрень которая сегодня работает, завтра нет. А нормальное решение.
Вот зачем все эти превозмогания? По цене, дешевле не получается. Как правило, выходит либо также, либо дороже. И это при условии, что человек оценивает свое время в ноль рублей.
Я не спорю, ардуинка с али + десяток говнодатчиков, и того 1500 вместе с доставкой. Тот же пр200 стоит больше 10к. НО! Мы используем нано для управления подцветкой (адресная лента) и светосигналами в серверных шкафах. Больше года, живут 5 из 10. То есть, это лотырея. Мало того, нано это почти самая слабая из семейства. И на полноценное управление просто светом, на однушку студию, их надо десяток. С модулями, таже беда.
Как говорится - Можно сделать из говна конфету. Только конфета говняная будет...
Speccyfan Автор
09.04.2024 10:39Где в моем случае, Вы видите применение переменному току 12-24В ? Куда его тянуть? Все мои модули питаются или ~220 (внутри стоит БП на 5В), либо через PoE. Не представляю, зачем может понадобиться ~12В? Приведите пример.
Я вообще тут не описывал применяемые типы кабелей, но в целом я согласен с применением 2.5кв на розетки и 1.5кв на люстру (хотя и много по современным меркам). А вот КСВВнг(А)-LS хоть и очеь хорош, но дешевле витую пару протянуть, для сигналов тоже подходит.
Я не вижу смысла тянуть все лампочки, розетки, датчики и все остальное в шкаф, а тут дорогими контроллерами и реле отключать каждую розетку, это просто развод людей на деньги. В моем случае, две такие коробочки ставятся на комнату, все к ним подключено, все близко. А в шкафу только автоматы и может будут потом несколько серьезных реле для включения бойлера например.
Зачем превозмогания? Потому что это DIY, причем совсем не сложный уровень, поверьте времени было затрачено, чтобы сделать первый модуль, заставить работать MQTT, а все остальное под копирку. И дешевле такое решение на порядки. А если вдруг помрет эта ардуина, то она на панельке, вынул, другую вставил, все.
И на полноценное управление просто светом, на однушку студию, их надо десяток
Вы про 74HC595 слышали? Да 100 лампочек можно легко подключить на нее.
Speccyfan Автор
А на самом деле примерно так и есть, на фото в левом верхнем углу - БП, к нему подключены латунные шины, а от них к модулям. Где-то тоже ставлю стабилизатор LM2596S. Там, где надо получить опорное напряжение очень стабильное.
pav18
Грамотно. N.B. в электронике этого уровня опорное стабильное напряжение критично. Наводки, ошибки и т.д. Если есть возможность уходить от реле и ставить полевики(плавное включение выключение света) это важно и комфортно для умного дома... Если ночью дети у меня проснулись, им просто дорожку рисует до сортира/кухни не выжигая глаза. Плюс предсказание маршрута - начал движение, смотрит какие датчики сработали и заранее в возможных конечных точках включает свет слегка...если нет, то вырубает, если дошел и прям активность повышает яркость по протоколу...
Speccyfan Автор
Согласен, так здорово. Возможно, в будущем, тоже так сделаю