Умный дом, дача, коттедж. Мониторинг, наблюдение энергоснабжения, электроснабжения. Электричество. Отключение света. Уведомление SMS (СМС). GSM. Своими руками

Система мониторинга отключения света с SMS уведомлением своими руками (10+)

Мониторинг наличия электропитания

 1  2 

Оглавление :: ПоискТехника безопасности :: Помощь

Эта статья входит в сборник, посвященный умному дому. С самого начала постоянной жизни в загородном доме (но с поездками на работу и в гости с ночевкой в городе) передо мной встала задача удаленно следить за наличием электроснабжения. Особенно это важно зимой, когда отключение света в сильный мороз может привести к фатальному замерзанию всей системы жизнеобеспечения. Но и летом полезно знать о проблемах с электричеством, если Вы отъехали на несколько дней, так как холодильники могут протухнуть.

Выбор подхода к системе мониторинга электроснабжения (наличия света)

Я постарался решить проблему удаленного мониторинга максимально просто, дешево и надежно. Сначала я обратил внимание на 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;
}

(читать дальше...) :: (в начало статьи)

 1  2 

Оглавление :: ПоискТехника безопасности :: Помощь

 

К сожалению в статьях периодически встречаются ошибки, они исправляются, статьи дополняются, развиваются, готовятся новые. Подпишитесь, на новости, чтобы быть в курсе.

Если что-то непонятно, обязательно спросите!
Задать вопрос. Обсуждение статьи.

Еще статьи

Фотореле. Автоматическое управление освещением. Световое реле. Автомат...
Автоматическое управление освещением. Включение вручную или при снижении освещен...

Бесперебойник своими руками. ИБП, UPS сделать самому. Синус, синусоида...
Как сделать бесперебойник самому? Чисто синусоидальное напряжение на выходе, при...

Транзисторы КТ502, 2Т502. Справочник, справочные данные, параметры, цо...
Характеристики и применение биполярных транзисторов КТ502 (КТ502А, КТ502Б, КТ502...

Датчик уровня жидкости. Реле. Автоматическое включение / выключение на...
Автомат наполнения емкости с водой включает и выключает насос в зависимости от у...

Диод универсальный маломощный КД510, 2Д510. Справочник, справочные дан...
Характеристики и применение маломощных кремниевых диодов КД510А (2Д510А)...

Транзисторы КТ503, 2Т503. Справочник, справочные данные, параметры, цо...
Характеристики и применение биполярных транзисторов КТ503 (КТ503А, КТ503Б, КТ503...

Электронный цифровой термометр своими руками. Схема, конструкция, опис...
Как сделать простой цифровой измеритель температуры...

Практика проектирования электронных схем. Самоучитель электроники....
Искусство разработки устройств. Элементная база радиоэлектроники. Типовые схемы....