Умный дом, дача, коттедж. Мониторинг, наблюдение энергоснабжения, электроснабжения. Электричество. Отключение света. Уведомление SMS (СМС). GSM. Своими рукамиСистема мониторинга отключения света с SMS уведомлением своими руками (10+) Мониторинг наличия электропитания
Эта статья входит в сборник, посвященный умному дому. С самого начала постоянной жизни в загородном доме (но с поездками на работу и в гости с ночевкой в городе) передо мной встала задача удаленно следить за наличием электроснабжения. Особенно это важно зимой, когда отключение света в сильный мороз может привести к фатальному замерзанию всей системы жизнеобеспечения. Но и летом полезно знать о проблемах с электричеством, если Вы отъехали на несколько дней, так как холодильники могут протухнуть. Выбор подхода к системе мониторинга электроснабжения (наличия света)Я постарался решить проблему удаленного мониторинга максимально просто, дешево и надежно. Сначала я обратил внимание на GSM модули, которые имели нужный функционал. Они могут в случае пропадания электричества, позвонить Вам или написать SMS. Но эти модули оказались довольно дорогими и недостаточно гибкими в применении.
Компьютер (ноутбук) и GSM модем обошлись немного дешевле такого модуля. А если учесть, что этот ноутбук я впоследствии использовал и в других блоках своей системы умного дома, то выгода оказалась налицо. На ноутбук установил Windows XP. Эта система представляется мне вершиной творения Microsoft. Недаром именно эта система до сих пор стоит в большинстве корпораций. Дальше интеллектуальный потенциал микро-мягкого явно пошел на убыль. Компьютер включен постоянно и стабильно работает уже в течение пары лет. Идея и реализация наблюдения и СМС информированияОперационная система Windows позволяет узнать состояние электропитания, работает ли компьютер на батарейках или от сети. Нужно периодически запрашивать эту информацию у системы и отправлять SMS на телефон хозяина, когда статус электропитания меняется. Отправка SMS осуществляется через GPS модем, который я купил по акции сотового оператора за 1 рубль. Обязательно отключите на этом номере все услуги с абонентской платой (безлимитный интернет, рингтоны и т. д.), периодически проверяйте, не включил ли Вам оператор какую-то услугу (они это очень любят делать). Не забывайте оплачивать свой номер, который будет использоваться с этим модемом. Вот текст программы на Си. Если что-то непонятно или не работает, задавайте вопросы в обсуждении. #include <windows.h> #include <stdio.h> #include <string.h> // Сюда положим handle открытого порта HANDLE port; // Структура для хранения настроек порта DCB dcb; // Структура для timeouts порта COMMTIMEOUTS ct; // Буфер для чтения данных из модема #define RetBufLen 1024 char RetBuf[RetBufLen]; // Сообщение об ошибке void GlobError(char * s, int param){ static char o[256]; CloseHandle(port); CharToOemA(s,o); printf("%s (%d)", o, param); ExitProcess(1); } // Запись в порт с эхом на экран void SnWritePort(char * command, char * comment){ DWORD buf; static char o[256]; CharToOemA(comment,o); if(!WriteFile(port,command,strlen(command),&buf,NULL)) GlobError("Ошибка записи в порт",GetLastError()); printf("To Port: %s (%s)\n",command,o); } // Чтение из порта с эхом на экран // Из порта приходится читать кусочками, потом клеить void SnReadPort(char * ReadBuf, int ReadBufLen){ char buffer[256]; DWORD buf; int p = 0; do{ if(!ReadFile(port,buffer,256,&buf,NULL)) GlobError("Ошибка чтения из порта",GetLastError()); memcpy(ReadBuf + p, buffer, buf); p += buf; if(p >= ReadBufLen) GlobError("Переполнение внутреннего буфера чтения",GetLastError()); } while( buf > 0 && memcmp(buffer + buf - 4,"\015\012>\040", 4) && memcmp(buffer + buf - 6,"\015\012OK\015\012", 6) && memcmp(buffer + buf - 9,"\015\012ERROR\015\012", 9) ); ReadBuf[p] = '\0'; printf("From Port:\n %s\n",ReadBuf); } // Инициализация порта void SnInitPort(void){ // Открываем файл, соответствующий порту. // Вместо COM10 нужно написать номер порта, на который сел Ваш модем // Чтобы посмотреть номер этого порта, нужно кликнуть правой кнопкой // на 'Мой компьютер' -> Свойства -> Закладка 'Оборудование' // -> Кнопка 'Диспетчер устройств' -> В дереве пункт 'Модемы' // Найдите там Ваш модем. На нем правой кнопкой -> Свойства // -> Закладка 'Модем' -> Там написано сверху 'Порт:' Это и есть нужный порт port=CreateFile("\\\\.\\COM10",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); if(port == INVALID_HANDLE_VALUE) GlobError("Невозможно открыть последовательный порт",GetLastError()); // Устанавливаем настройки порта. Сначала читаем настройки, чтобы не поломать лишнего dcb.DCBlength = sizeof(DCB); if(!GetCommState(port, &dcb)) GlobError("Невозможно получить настройки порта",GetLastError()); // Потом задаем нужные и сохраняем в порт dcb.BaudRate = CBR_57600; dcb.Parity = NOPARITY; dcb.ByteSize = 8; dcb.StopBits =ONESTOPBIT; if(!SetCommState(port, &dcb)) GlobError("Невозможно задать настройки порта",GetLastError()); // Настраиваем буфер обмена. Некоторые модемы не позволяют изменять размер буфера // Тогда эта операция выдает ошибку. В этом случае нужно ппросто забить ее комментарием if(!SetupComm(port, 256, 256)) GlobError("Невозможно задать размер буферов обмена",GetLastError()); // Задаем timeouts порта. Приведенные значения подобраны экспериментально ct.ReadIntervalTimeout=100; ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant=100; ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant=100; if(!SetCommTimeouts(port,&ct)) GlobError("Невозможно задать таймауты",GetLastError());; // Задаем timeouts порта. Приведенные значения подобраны экспериментально if(!PurgeComm(port,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT)) GlobError("Не проходит сброс порта",GetLastError()); // Отключаем эхо SnWritePort("ate0\r","Отключаем эхо."); SnReadPort(RetBuf,RetBufLen); // Устанавливаем набор символов SnWritePort("at+cscs=\"GSM\"\r","Устанавливаем набор знаков GSM."); SnReadPort(RetBuf,RetBufLen); // Устанавливаем текстовый режим SnWritePort("at+cmgf=1\r","Устанавливаем текстовый режим."); SnReadPort(RetBuf,RetBufLen); } // Посылаем SMS со статусом питания void SnPowerInfo(int st){ // Порт держать открытоым не будем. Подключаемся, если нужно отправить SMS SnInitPort(); // Отправляем SMS на номер +XXXXXXXXXX (напишите здесь свой номер или сделайте настроечный файл) SnWritePort("at+cmgs=\"+XXXXXXXXXX\"\r","Посылаем СMC."); SnReadPort(RetBuf,RetBufLen); if(!st) SnWritePort("Power Off\032\r","'OK'."); else SnWritePort("Power On\032\r","'OK'."); SnReadPort(RetBuf,RetBufLen); // Закрываем порт CloseHandle(port); } SYSTEM_POWER_STATUS sps; int main(void){ // В эту переменную запомним текущее состояние питания. Для начала поставим 0 - питания нет // Тогда при запуске программы придет первое SMS о включении питания для проверки int old_st = 0; for(;;){ // Получим информацию о состоянии сети GetSystemPowerStatus(&sps); // Напечатаем ее printf("%d\n", sps.ACLineStatus); // Если состояние сети изменилось, то отправим сообщение if(sps.ACLineStatus != old_st){ SnPowerInfo(sps.ACLineStatus); old_st = sps.ACLineStatus; } // Подождем 10 секунд перед следующей проверкой Sleep(10000); // Мониторинг будет работать вечно. Предусмотрен только аварийный выход } return 0; }
К сожалению в статьях периодически встречаются ошибки, они исправляются, статьи дополняются, развиваются, готовятся новые. Подпишитесь, на новости, чтобы быть в курсе. Если что-то непонятно, обязательно спросите! Еще статьи Фотореле. Автоматическое управление освещением. Световое реле. Автомат... Бесперебойник своими руками. ИБП, UPS сделать самому. Синус, синусоида... Повышающий импульсный преобразователь напряжения, источник питания. Ко... Лабораторный импульсный автотрансформатор, латр. Схема, конструкция, у... Усилитель звука класса D (Д) большой мощности. Звуковой. УМЗЧ. УНЧ. Сх... Операционный усилитель, ОУ, операционник. Применение, типовые схемы.... Мостовой импульсный стабилизированный преобразователь напряжения, исто... Пушпульный импульсный источник питания. Онлайн расчет. Форма. Подавлен... |