2 года назад передо мной встала задача реализовать удаленное управление обогревательными приборами в своем загородном доме. В данной статье я хочу поделиться моим вариантом автоматизации и удаленного управления, к которому я в итоге пришел. Постараюсь охватить весь процесс и подробности создания этого хобби-проекта и поделиться всеми сложностями, с которыми пришлось столкнуться. В процессе реализации, как видно из названия статьи, я использовал Noolite (о нем расскажу в статье), Telegram и совсем немного Python.


image

Введение


Данный проект берет свое начало в 2014 году, когда передо мной встала задача обеспечить удаленное управления обогревательными приборами в своем загородном доме. Дело в том, что практически каждые выходные мы с семьей проводим на даче. И если летом мы, задержавшись по тем или иным причинам в городе, приехав в дом могли сразу лечь спать, то зимой, когда температура опускается до -30 градусов, мне приходилось тратить по 3-4 часа на протопку дома. Я видел следующие пути решения данной проблемы:


  1. "Неумное решение" — можно оставлять включенными обогреватели со встроенными термостатами на минимальной температуре поддержания тепла. Собственно ничего "умного" в этом решении нет, но 24/7 работающие обогревательные приборы в деревянном загородном доме не внушают доверия. Хотелось хотя бы минимального контроля над их состоянием, автоматизации и какой-нибудь обратной связи;


  2. GSM-розетки — данным решением пользуются мои соседи по дачному участку. Если кто-то не знаком с ними, то это просто управляемый посредством SMS команд переходник, который включается в розетку, а сам обогреватель включается в него. Не самое бюджетное решение, если нужно обеспечить обогрев целого дома — ссылка на маркет. Я вижу его как самое простое и менее трудозатратное в реализации, но имеющее минусы в процессе эксплуатации, такие как: целый ворох сим карт и работы по поддержанию их положительного баланса, так как для каждой комнаты нужен минимум один обогреватель, ограниченность и неудобства их контроля по средствам SMS;


  3. "Умный дом" — собственно решения, построенные на реализации "умного дома".

Как наиболее перспективное решение мною был выбран третий вариант и следующим вопросом на повестке дня стал — "Какую платформу для реализации выбрать?".


Уже не помню сколько я потратил время на поиски подходящих вариантов, но в итоге из бюджетных и доступных в магазинах решений я нашел системы: NooLite и CoCo (сейчас уже переименовали в Trust). При их сравнении решающую роль для меня сыграло то, что у NooLite есть открытое и задокументированное API для управления любыми его блоками. На тот момент необходимости в нем не было, но я сразу отметил, какую гибкость в дальнейшем это может дать. Да и цена у NooLite была существенно ниже. В итоге я остановил свой выбор именно на NooLite.


Реализация 1 — автоматизация NooLite


Система NooLite состоит из силовых модулей (под разные типы нагрузок), датчиков (температура, влажность, движение) и управляющего ими оборудования: радио пульты, настенные выключателей, USB-адаптеров для компьютера или Ethernet-шлюза PR1132. Все это можно использовать в различных комбинациях, соединять их между собой напрямую или управлять через usb-адаптеры или шлюз, подробнее об этом можете почитать на официальном сайте производителя.


Для моей задачи центральным элементом умного дома я выбрал Ethernet-шлюза PR1132, который будет управлять силовыми блоками и получать информацию с датчиков. Для работы Ethernet-шлюза необходимо подключить его к сети кабелем, поддержки Wi-Fi в нем нет. На тот момент у меня в доме уже была организована сеть, состоящая из WiFi-маршрутизатора Asus rt-n16 и USB--модема для доступа к интернету. Поэтому весь монтаж NooLite для меня заключался лишь в том, чтобы подключить шлюз кабелем к маршрутизатору, расположить в доме радиодатчики температуры и смонтировать силовые блоки в центральном электрощитке.


У NooLite есть ряд силовых блоков для разной подключаемой нагрузки. Самый "мощный" блок может управлять нагрузкой до 5000 Вт. Если требуется управление большей нагрузкой, как в моем случае, то можно сделать подключение нагрузки через управляемое реле, которым, в свою очередь, будет управлять силовой блок NooLite.


image

Схема подключения


image

Ethernet-шлюза PR1132 и маршрутизатор Asus rt-n16


image

Беспроводной датчик температуры и влажности PT111


image

Электрощиток и силовой блок для наружного монтажа SR211 — в дальнейшем вместо этого блока я использовал блок для внутреннего монтажа и поместил его прямо в электрощитке


Ethernet-шлюз PR1132 имеет web-интерфейс через которой осуществляется привязка/отвязка силовых блоков, датчиков и управление ими. Сам интерфейс выполнен в довольно "топорном" минималистическом стиле, но этого вполне достаточно для доступа ко всему необходимому функционалу системы:


image

Настройки


image

Управление


image

Страница одной группы выключателей


Подробно о привязке и настройке всего этого — опять же на официальном сайте.


На тот момент я мог:


  • управлять обогревателями, находясь в локальной сети загородного дома, что было не очень-то и полезно, исходя из первоначальной задачи;
  • создавать таймеры включения/отключения по времени и дню недели.

Как раз таймеры автоматизации на какое-то время решили мою первоначальную задачу. В пятницу утром-днем обогреватели включались, и уже к вечеру мы приезжали в теплый дом. На случай, если наши планы изменятся, был поставлен второй таймер, который ближе к ночи отключал батареи.


Реализация 2 — удаленный доступ к умному дому


Первая реализация позволила частично решить мою задачу, но все-таки хотелось онлайн управления домом и наличие обратной связи. Я начал искать варианты организации доступа к дачной сети из вне.


Как я упомянул в предыдущем разделе — дачная сеть имеет доступ к интернету через usb модем одного из мобильных операторов. По умолчанию мобильные модемы имеют серый ip адрес и без дополнительных ежемесячных трат белого фиксированного ip не получить. При таком сером IP не помогут и различные no-ip сервисы.


Единственный вариант, который мне удалось на тот момент придумать — VPN. На городском маршрутизаторе у меня был настроен VPN-сервер, которым я время от времени пользовался. Мне было необходимо настроить на дачном роутере VPN-клиент и прописать статические маршруты до дачной сети.


image

Схема подключения


В результате дачный роутер постоянно держал VPN соединение с городским роутером и для доступа к шлюзу NooLite мне нужно было с клиентского устройства (ноутбук, телефон) подключится по VPN к городскому маршрутизатору.


На этом этапе я мог:


  • получить доступ к умному дому из любого места;

В целом это практически на 100% покрывало первоначальную задачу. Однако я понимал, что данная реализация далека от оптимальной и удобной в использовании, так как каждый раз я должен был выполнять ряд дополнительных действий по подключению к VPN. Для меня это не было особой проблемой, однако для остальных членов семьи это было не очень удобно. Так же в этой реализации было очень много посредников, что сказывалось на отказоустойчивости всей системы в целом. Однако на некоторое время я остановился именно на этом варианте.


Реализация 3 — Telegram bot


С появлением ботов в Telegram я взял на заметку, что это смогло бы стать довольно удобным интерфейсом для управления умным домом и, как только у меня появилось достаточно свободного времени, я приступил к разработке на Python 3.


Бот должен был где-то находится и, как самое энергоэффективное решение, я выбрал Raspberry Pi. Хоть это и был мой первый опыт работы с ним, особых сложностей в его настройке не возникло. Образ на карту памяти, ethernet кабель в порт и по ssh — полноценный Linux.


Как я уже говорил — у NooLite есть задокументированное API, которое и пригодилось мне на данном этапе. Для начала я написал простенькую обертку для более удобного взаимодействия с API:


noolite_api.py
"""
NooLite API wrapper
"""

import requests
from requests.auth import HTTPBasicAuth
from requests.exceptions import ConnectTimeout, ConnectionError
import xml.etree.ElementTree as ET

class NooLiteSens:
    """Класс хранения и обработки информации, полученной с датчиков

    Пока как таковой обработки нет
    """
    def __init__(self, temperature, humidity, state):
        self.temperature = float(temperature.replace(',', '.')) if temperature != '-' else None
        self.humidity = int(humidity) if humidity != '-' else None
        self.state = state

class NooLiteApi:
    """Базовый враппер для общения с NooLite"""
    def __init__(self, login, password, base_api_url, request_timeout=10):
        self.login = login
        self.password = password
        self.base_api_url = base_api_url
        self.request_timeout = request_timeout

    def get_sens_data(self):
        """Получение и прасинг xml данных с датчиков

        :return: список NooLiteSens объектов для каждого датчика
        :rtype: list
        """
        response = self._send_request('{}/sens.xml'.format(self.base_api_url))
        sens_states = {
            0: 'Датчик привязан, ожидается обновление информации',
            1: 'Датчик не привязан',
            2: 'Нет сигнала с датчика',
            3: 'Необходимо заменить элемент питания в датчике'
        }
        response_xml_root = ET.fromstring(response.text)
        sens_list = []
        for sens_number in range(4):
            sens_list.append(NooLiteSens(
                response_xml_root.find('snst{}'.format(sens_number)).text,
                response_xml_root.find('snsh{}'.format(sens_number)).text,
                sens_states.get(int(response_xml_root.find('snt{}'.format(sens_number)).text))
            ))
        return sens_list

    def send_command_to_channel(self, data):
        """Отправка запроса к NooLite

        Отправляем запрос к NooLite с url параметрами из data
        :param data: url параметры
        :type data: dict
        :return: response
        """
        return self._send_request('{}/api.htm'.format(self.base_api_url), params=data)

    def _send_request(self, url, **kwargs):
        """Отправка запроса к NooLite и обработка возвращаемого ответа

        Отправка запроса к url с параметрами из kwargs
        :param url: url для запроса
        :type url: str
        :return: response от NooLite или исключение
        """

        try:
            response = requests.get(url, auth=HTTPBasicAuth(self.login, self.password),
                                    timeout=self.request_timeout, **kwargs)
        except ConnectTimeout as e:
            print(e)
            raise NooLiteConnectionTimeout('Connection timeout: {}'.format(self.request_timeout))
        except ConnectionError as e:
            print(e)
            raise NooLiteConnectionError('Connection timeout: {}'.format(self.request_timeout))

        if response.status_code != 200:
            raise NooLiteBadResponse('Bad response: {}'.format(response))
        else:
            return response

# Кастомные исключения
NooLiteConnectionTimeout = type('NooLiteConnectionTimeout', (Exception,), {})
NooLiteConnectionError = type('NooLiteConnectionError', (Exception,), {})
NooLiteBadResponse = type('NooLiteBadResponse', (Exception,), {})
NooLiteBadRequestMethod = type('NooLiteBadRequestMethod', (Exception,), {})

А дальше с использованием пакета python-telegram-bot был написан сам бот:


telegram_bot.py
import os
import logging
import functools

import yaml
import requests
import telnetlib
from requests.exceptions import ConnectionError
from telegram import ReplyKeyboardMarkup, ParseMode
from telegram.ext import Updater, CommandHandler, Filters, MessageHandler, Job

from noolite_api import NooLiteApi, NooLiteConnectionTimeout,    NooLiteConnectionError, NooLiteBadResponse

# Получаем конфигурационные данные из файла
config = yaml.load(open('conf.yaml'))

# Базовые настройка логирования
logger = logging.getLogger()
logger.setLevel(logging.INFO)
formatter = logging.Formatter(
    '%(asctime)s - %(filename)s:%(lineno)s - %(levelname)s - %(message)s'
)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)

# Подключаемся к боту и NooLite
updater = Updater(config['telegtam']['token'])
noolite_api = NooLiteApi(
    config['noolite']['login'],
    config['noolite']['password'],
    config['noolite']['api_url']
)
job_queue = updater.job_queue

def auth_required(func):
    """Декоратор аутентификации"""
    @functools.wraps(func)
    def wrapped(bot, update):
        if update.message.chat_id not in config['telegtam']['authenticated_users']:
            bot.sendMessage(
                chat_id=update.message.chat_id,
                text="Вы неавторизованы.\nДля авторизации отправьте /auth password."
            )
        else:
            return func(bot, update)
    return wrapped

def log(func):
    """Декоратор логирования"""
    @functools.wraps(func)
    def wrapped(bot, update):
        logger.info('Received message: {}'.format(
            update.message.text if update.message else update.callback_query.data)
        )
        func(bot, update)
        logger.info('Response was sent')
    return wrapped

def start(bot, update):
    """Команда начала взаимодействия с ботом"""
    bot.sendMessage(
        chat_id=update.message.chat_id,
        text="Для начала работы нужно авторизоваться.\n"
             "Для авторизации отправьте /auth password."
    )

def auth(bot, update):
    """Аутентификация

    Если пароль указан верно, то в ответ приходит клавиатура управления умным домом
    """
    if config['telegtam']['password'] in update.message.text:
        if update.message.chat_id not in config['telegtam']['authenticated_users']:
            config['telegtam']['authenticated_users'].append(update.message.chat_id)
        custom_keyboard = [
            ['/Включить_обогреватели', '/Выключить_обогреватели'],
            ['/Включить_прожектор', '/Выключить_прожектор'],
            ['/Температура']
        ]
        reply_markup = ReplyKeyboardMarkup(custom_keyboard)
        bot.sendMessage(
            chat_id=update.message.chat_id,
            text="Вы авторизованы.",
            reply_markup=reply_markup
        )
    else:
        bot.sendMessage(chat_id=update.message.chat_id, text="Неправильный пароль.")

def send_command_to_noolite(command):
    """Обработка запросов в NooLite.

    Отправляем запрос. Если возращается ошибка, то посылаем пользователю ответ об этом.
    """
    try:
        logger.info('Send command to noolite: {}'.format(command))
        response = noolite_api.send_command_to_channel(command)

    except NooLiteConnectionTimeout as e:
        logger.info(e)
        return None, "*Дача недоступна!*\n`{}`".format(e)

    except NooLiteConnectionError as e:
        logger.info(e)
        return None, "*Ошибка!*\n`{}`".format(e)

    except NooLiteBadResponse as e:
        logger.info(e)
        return None, "*Не удалось сделать запрос!*\n`{}`".format(e)

    return response.text, None

# ========================== Commands ================================

@log
@auth_required
def outdoor_light_on(bot, update):
    """Включения уличного прожектора"""
    response, error = send_command_to_noolite({'ch': 2, 'cmd': 2})
    logger.info('Send message: {}'.format(response or error))
    bot.sendMessage(chat_id=update.message.chat_id, text="{}".format(response or error))

@log
@auth_required
def outdoor_light_off(bot, update):
    """Выключения уличного прожектора"""
    response, error = send_command_to_noolite({'ch': 2, 'cmd': 0})
    logger.info('Send message: {}'.format(response or error))
    bot.sendMessage(chat_id=update.message.chat_id, text="{}".format(response or error))

@log
@auth_required
def heaters_on(bot, update):
    """Включения обогревателей"""
    response, error = send_command_to_noolite({'ch': 0, 'cmd': 2})
    logger.info('Send message: {}'.format(response or error))
    bot.sendMessage(chat_id=update.message.chat_id, text="{}".format(response or error))

@log
@auth_required
def heaters_off(bot, update):
    """Выключения обогревателей"""
    response, error = send_command_to_noolite({'ch': 0, 'cmd': 0})
    logger.info('Send message: {}'.format(response or error))
    bot.sendMessage(chat_id=update.message.chat_id, text="{}".format(response or error))

@log
@auth_required
def send_temperature(bot, update):
    """Получаем информацию с датчиков"""
    try:
        sens_list = noolite_api.get_sens_data()
    except NooLiteConnectionTimeout as e:
        logger.info(e)
        bot.sendMessage(
            chat_id=update.message.chat_id,
            text="*Дача недоступна!*\n`{}`".format(e),
            parse_mode=ParseMode.MARKDOWN
        )
        return
    except NooLiteBadResponse as e:
        logger.info(e)
        bot.sendMessage(
            chat_id=update.message.chat_id,
            text="*Не удалось получить данные!*\n`{}`".format(e),
            parse_mode=ParseMode.MARKDOWN
        )
        return
    except NooLiteConnectionError as e:
        logger.info(e)
        bot.sendMessage(
            chat_id=update.message.chat_id,
            text="*Ошибка подключения к noolite!*\n`{}`".format(e),
            parse_mode=ParseMode.MARKDOWN
        )
        return

    if sens_list[0].temperature and sens_list[0].humidity:
        message = "Температура: *{}C*\nВлажность: *{}%*".format(
            sens_list[0].temperature, sens_list[0].humidity
        )
    else:
        message = "Не удалось получить данные: {}".format(sens_list[0].state)

    logger.info('Send message: {}'.format(message))
    bot.sendMessage(chat_id=update.message.chat_id,
                    text=message,
                    parse_mode=ParseMode.MARKDOWN)

@log
@auth_required
def send_log(bot, update):
    """Получение лога для отладки"""
    bot.sendDocument(
        chat_id=update.message.chat_id,
        document=open('/var/log/telegram_bot/err.log', 'rb')
    )

@log
def unknown(bot, update):
    """Неизвестная команда"""
    bot.sendMessage(chat_id=update.message.chat_id, text="Я не знаю такой команды")

def power_restore(bot, job):
    """Выполняется один раз при запуске бота"""
    for user_chat in config['telegtam']['authenticated_users']:
        bot.sendMessage(user_chat, 'Включение после перезагрузки')

def check_temperature(bot, job):
    """Периодическая проверка температуры с датчиков

    Eсли температура ниже, чем установленный минимум -
    посылаем уведомление зарегистрированным пользователям
    """
    try:
        sens_list = noolite_api.get_sens_data()
    except NooLiteConnectionTimeout as e:
        print(e)
        return
    except NooLiteConnectionError as e:
        print(e)
        return
    except NooLiteBadResponse as e:
        print(e)
        return
    if sens_list[0].temperature and                     sens_list[0].temperature < config['noolite']['temperature_alert']:
        for user_chat in config['telegtam']['authenticated_users']:
            bot.sendMessage(
                chat_id=user_chat,
                parse_mode=ParseMode.MARKDOWN,
                text='*Температура ниже {} градусов: {}!*'.format(
                    config['noolite']['temperature_alert'],
                    sens_list[0].temperature
                )
            )

def check_internet_connection(bot, job):
    """Периодическая проверка доступа в интернет

    Если доступа в интрнет нет и попытки его проверки исчерпаны -
    то посылаем по telnet команду роутеру для его перезапуска.
    Если доступ в интернет после этого не появился - перезагружаем Raspberry Pi
    """
    try:
        requests.get('http://ya.ru')
        config['noolite']['internet_connection_counter'] = 0
    except ConnectionError:
        if config['noolite']['internet_connection_counter'] == 2:
            tn = telnetlib.Telnet(config['router']['ip'])

            tn.read_until(b"login: ")
            tn.write(config['router']['login'].encode('ascii') + b"\n")

            tn.read_until(b"Password: ")
            tn.write(config['router']['password'].encode('ascii') + b"\n")

            tn.write(b"reboot\n")

        elif config['noolite']['internet_connection_counter'] == 4:
            os.system("sudo reboot")
        else:
            config['noolite']['internet_connection_counter'] += 1

dispatcher = updater.dispatcher

dispatcher.add_handler(CommandHandler('start', start))
dispatcher.add_handler(CommandHandler('auth', auth))
dispatcher.add_handler(CommandHandler('Температура', send_temperature))

dispatcher.add_handler(CommandHandler('Включить_обогреватели', heaters_on))
dispatcher.add_handler(CommandHandler('Выключить_обогреватели', heaters_off))
dispatcher.add_handler(CommandHandler('Включить_прожектор', outdoor_light_on))
dispatcher.add_handler(CommandHandler('Выключить_прожектор', outdoor_light_off))

dispatcher.add_handler(CommandHandler('log', send_log))
dispatcher.add_handler(MessageHandler([Filters.command], unknown))

job_queue.put(Job(check_internet_connection, 60*5), next_t=60*5)
job_queue.put(Job(check_temperature, 60*30), next_t=60*6)
job_queue.put(Job(power_restore, 60, repeat=False))

updater.start_polling(bootstrap_retries=-1)

Данный бот запускается на Raspberry Pi под Supervisor, который контролирует его состояние и запускает его при перезагрузке.


image

Схема работы бота


При запуске бот:


  • посылает зарегистрированным пользователям сообщение о том, что он включился и готов к работе;
  • мониторит подключение к интернету. В условии работы через мобильный интернет были случаи, когда он пропадал. Поэтому была добавлена периодическая проверка доступности подключения. Если заданное количество проверок заканчивается неудачей, то сначала скрипт перезагружает через telnet маршрутизатор, а потом, если это не помогло, и сам Raspberry Pi;
  • мониторит температуру внутри помещения и отправляет пользователю уведомление, если она опустилась ниже заданного порога;
  • выполняет команды от зарегистрированных пользователей.

Команды жестко прописаны в коде и включают в себя:


  • включение/выключение обогревателей;
  • включение/выключение уличного прожектора;
  • получение температуры с датчиков;
  • получение файла логов для дебага.

Пример общения с ботом:


image

В итоге я и все члены семьи получили довольно удобный интерфейс управления умным домом через Telegram. Все, что нужно сделать — установить телеграмм клиент на свое устройство и знать пароль для начала общения с ботом.


В итоге я могу:


  • управлять умным домом из любого места с любого устройства со своей учетной записью Telegram;
  • получать информацию с датчиков, расположенных в доме.

Данная реализация на все 100% решила первоначальную задачу, была удобной и интуитивно понятной в использовании.


Заключение


Бюджет (по текущим ценам):


  • NooLite Ethernet-шлюз — 6.000 рублей
  • NooLite силовой датчик для управления нагрузкой — 1.500 рублей
  • NooLite датчик температуры и влажности — 3.000 рублей (без влажности дешевле)
  • Raspberry Pi — 4.000 рублей

На выходе у меня получилось довольно гибкая бюджетная система, которую можно легко расширять по мере необходимости (NooLite шлюз поддерживает до 32 каналов). Я и члены семьи могут с легкостью пользоваться ей без необходимости выполнять какие-то дополнительные действия: зашел в телеграмм — проверил температуру — включил обогреватели.


На самом деле данная реализация не последняя. Буквально неделю назад я подключил всю эту систему к Apple HomeKit, что позволило добавить управление через приложение для iOS "Дом" и соответствующую интеграцию с Siri для голосового управления. Но процесс реализации тянет на отдельную статью. Если сообществу будет интересна данная тема, то готов в ближайшее время подготовить еще одну статью.


UPD: вторая статья про интеграцию с HomeKit


Ссылки по теме:


Поделиться с друзьями
-->

Комментарии (48)


  1. arturos
    11.10.2016 19:42

    Почему бы не упростить конструкцию до одного роутера, где в прошивку добавить телегу, и в роутер свисток на 433 мгц? ИМХО слишком много компонентов… точек отказа все больше и больше…
    Кстати, ноолайт обзавёлся обратной связью?


    1. AlekseevAV
      11.10.2016 19:52

      Согласен, действительно много точек отказа. Но предложенный Вами вариант лично для меня был бы очень сложен в реализации. Я старался использовать те технологии, с которыми работал.


      Кстати, ноолайт обзавёлся обратной связью?

      Нет, пока обратной связи не появилось. Как раз интеграция с Apple HomeKit частично решает данную проблему, так как то устройство, которое выполняет роль хаба умного дома (Apple TV или iPad), хранит состояние переключателей и синхронизирует его между всеми пользователями. Подробнее расскажу об этом в следующей статье.


      1. arturos
        11.10.2016 19:57

        Да, но использую дома устройства noolite не раз убедился что это затея плохая… попросту могут устройства не отработать и все… (не важно по какой причине… помехи радиоэфира, плохое питание и т.п.) — и получается что хранить такой статус… обманчиво.


        1. AlekseevAV
          11.10.2016 20:18

          За все время использования не сталкивался с таким. Может дело в том, что шлюз располагается довольно близко к щитку, где находятся силовые блоки. Да и самих блоков у меня пока всего 3 + датчик тепла и влажности. Возможно помехи возникнут при увеличении их количества.


          Но в любом случае главной задачей NooLite в моем доме является обогрев. Поэтому с момента первых реализаций факт включения обогревателей контролирую по росту температуры.


  1. LumberJack
    11.10.2016 20:28
    +2

    Иногда мне становится страшно от мысли, что Телеграм может «упасть».


    1. AlekseevAV
      11.10.2016 22:59

      Тут уж, как говорится, нужно надеяться на лучшее, но готовиться к худшему.


      В моем случае параллельно телеграм работает Apple HomeKit на базе Apple TV. На самом деле сейчас умный дом от Apple используется как основная система, а телеграм — вспомогательная.


      И как последний рубеж — таймеры автоматизации в самом NooLite, на случай если дача останется оффлайн.


      1. Artemiy117
        12.10.2016 10:52

        Apple HomeKit вроде работает когда устройства в одной сети. А как управляете удаленно? Или удаленно только Telegram?


        1. AlekseevAV
          12.10.2016 11:05

          Для удаленной работы в локальной сети должен находится HomeKit хаб, роль которого может выполнять Apple TV или iPad с iOS 10. Настраивать абсолютно ничего не нужно, просто зайти по своей учеткой.


    1. Source
      12.10.2016 00:31

      Тут может слегка помочь переход к декларативным командам. Команду «включи обогреватели» заменить на «хочу 25 градусов по Цельсию»… А «умный дом» пусть сам разбирается, что ему для этого надо сделать для этого, обогреватели включить или кондиционер… на то ведь он и умный :-)


      1. AlekseevAV
        12.10.2016 00:51
        +1

        Я не упомянул в самой статье, но обогреватели в каждой комнате подключены через термостаты. Соответственно, после включения они нагоняют выставленную температуру и поддерживают ее. К сожалению, сами термостаты "глупые" и не управляются из вне.


        Как вариант, я размышлял над тем, что бы пойти еще дальше — реализовать команды: "Будем на даче к 20:00". Умный дом, зная какая температура на улице и какая в доме + обладая статистикой о том, насколько быстро он может прогреть дом, сам принимает решение когда ему включать обогреватели. Но тут далеко можно уйти)


        термостат

        image


        1. Source
          12.10.2016 01:01

          Как вариант, я размышлял над тем, что бы пойти еще дальше — реализовать команды: «Будем на даче к 20:00».
          А что, тоже довольно интересный вариант!


        1. GrakovNe
          12.10.2016 12:29

          такой подход снижает количество вариантов и вносит сумятицу. Одно дело — я приехал на дачу на ночь и хочу тепло, светло и сухо. Другое — я приехал на 15 минут, рассаду выкопать обратно, потому что передумал и хочу просто светло и сухо. Надо либо вернуться к императивным командам более высокого уровня абстракции вроде «Комфортный режим», либо городить огород и начинать объяснять дому зачем именно вы будете на даче к 20:00.
          P.S. Я бы просто визуализировал все датчики на манер SKADA — систем и вместо телеграма использовал бы отдельное приложение с отдельным же тонким сервером. Минус один (реально удаленный) узел, минус потребность в целостности интернета в мире, минус зависимость от работы телеграма вообще.


      1. Pinkerton42
        12.10.2016 19:41

        Главное не забыть разделить кондиционеры и обогреватели, а то получится как с той лампочкой у подъезда.


        1. Source
          12.10.2016 22:46

          А что за история с лампочкой у подъезда?


          1. Pinkerton42
            12.10.2016 23:33

            Когда повесили «умную» лампочку, которая сама включается при недостаточной освещенности (типа, вечером), а при наступлении утра (достаточная освещенность) она выключается. Дальше продолжать или догадаетесь?


            1. Source
              13.10.2016 00:56

              Выключалась от своего же света?


              1. Pinkerton42
                13.10.2016 01:03

                Ага. А потом опять включалась. Так и изобрели стробоскоп.


  1. dimarikpro
    11.10.2016 22:40

    Есть у меня ubiquiti mPort, надо тоже прикрутить его к своему телеграмботу, т.к. только нагуглил что для mFi розетки уже есть гемчик на любимых рубях. Спасибо.


  1. s493599
    11.10.2016 23:15

    Большое спасибо за статью! Очень интересно почитать про связку с хомкитом


    1. AlekseevAV
      11.10.2016 23:25

      Не за что. Планирую на выходных подготовить материал и уже в начале недели оформить статью.


      1. GruBBy
        12.10.2016 12:26

        Да, статья отличная. Очень жду про HomeKit.


  1. CyberBot
    11.10.2016 23:16

    У NooLite не очень современный дизайн, вот если бы Вы прикрутили выключатель Livolo к CyberWrt


    1. lewstav
      11.10.2016 23:20
      +1

      Да, если добавить такой дизайн, будет выглядеть красиво на фоне дерева.


    1. AlekseevAV
      12.10.2016 00:01

      Согласен, над дизайном сенсорных выключателей им нужно еще поработать. Но лично мне больше нравятся обычные кнопочные выключатели. Если бы делал проводку с нуля, то использовал бы именно их. Это позволило бы вести кабель напрямую к управляемому потребителю (светильнику, обогревателю), не делая лишних зигзагов до выключателя. Сам же выключатель можно повесить куда угодно и перевешивать хоть каждый день. И еще одна очень полезная возможность — подключить сразу 2/3/4… выключателя к одному светильнику. На одном конце коридора вешаем один, на втором — другой. Включили свет одним выключателем, прошли коридор, выключили свет другим выключателем. Плюс все это дело параллельно через шлюз управляется. Красота!


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


      По поводу CyberWrt — не пользовался, но выглядит интересно. В следующей статье расскажу про свой опыт работы с OpenHab. Если в OpenHab есть готовый binding для Livolo, то интегрировать их в умный дом и HomeKit будет совсем просто. Скорее всего нет и тут уже нужно смотреть каким образом ими вообще можно управлять из linux. Как только будет решение — написание обертки для взаимодействия с OpenHab дело техники.


  1. lewstav
    11.10.2016 23:19

    del


  1. ecl
    12.10.2016 06:45

    Розетки — выключатели по $19 (1200 руб) за штуку — Broadlink Sp3
    Датчик температуры \ влажности \ шума и тд — $40 (2500 руб) — Broadlink А1

    Софт в маркетах для ios и android, время настройки — 1 час. Плюс возможность настраивать сценарии вида «если температура стала такой-то — включить\выключить такую-то розетку»


    1. ecl
      12.10.2016 06:51

      Забыл главное — розетки с обратной связью. Это критично важно потому что не зная состояние включено-выключено только добавляет паники, вместо того, чтобы делать дом умным.


      1. habrauser007
        12.10.2016 15:48

        не знаете, есть ли возможность управлять такими розетками напрямую, без смартфона? Через встроенный веб-интерфейс, например. Wi-fi розеток много, но вот управление либо только приложением, либо ещё через какое-то мутное облако.


  1. memtew
    12.10.2016 08:45
    +1

    А зачем у вас слэши в подписях к кнопкам? Можно ведь и без них+добавить индикацию при помощи эмодзи:

    У меня так


    1. AlekseevAV
      12.10.2016 09:04

      Не знал, что телеграм может команду с пробелами понимать. Спасибо, изучу.


      У меня была идея сделать похожую механику работы, как у вас на скриншоте:


      1. Выбираем где нам нужно произвести действие — кухня, крыльцо и т.д.
      2. Выбираем какое действие нужно произвести с выбранным блоком — включить/выключить.

      Но после первого прототипа по отзывам пользователей было решено, что легче выполнить нужное действие путем нажатия одной кнопки, чем нескольких. Так что отложил эту задумку до момента, когда управляемых устройств станет больше и они уже не будут влезать, а пока вся моя клавиатура управления умещается в 5 кнопок.


  1. Adamantium
    12.10.2016 09:51

    А насколько стабильно работает Ваша связка usb модем + роутер? Или уровень сигнала на даче достаточный для всех хотелок?
    И ещё, у нас сейчас у всех мобильных операторов, представленных в Московском регионе, невозможно пользоваться сервисами типа dyndns? Или всё же не все выдают «серые» адреса? Все эти танцы с впн, телеграмом, и т.д. и т.п. несколько напрягают… Как минимум, это «ещё один из бесконечного ряда мессенджеров» на телефоне. Может есть ещё какие-то варианты?


    1. AlekseevAV
      12.10.2016 10:37

      А насколько стабильно работает Ваша связка usb модем + роутер?

      За все время только один раз столкнулся с ситуацией, когда нужно было перевоткнуть его в роутер, но это по моей вине — кончился трафик. Больше проблем с ним не было. Однако, для пущей уверенности, добавил в скрипт телеграм бота периодическую проверку доступности интернета. Через n количество неудачный попыток он по telnet перезагружает роутер. Затем ждет и пробует еще n попыток, если опять неудача — перезагружает уже сам себя (RaspberryPi).
      По-моему в Zyxel маршрутизаторах похожий механизм проверки доступности интернета из коробки есть. Он сам usb устройство переподключает, если в интернет не выйти. Возможно есть и у других производителей/прошивок, не изучал.


      Или уровень сигнала на даче достаточный для всех хотелок?

      Удаленность от города — 60 км. USB-модем уверенно ловит 3G, на которых выдает около 8-10 Мбит. Бывало, что и до 20 разгонялся. У соседа с другим мобильным оператором так вообще LTE ловит, но по скорости сопоставимо с моим 3G. Но это, кончено, от конкретного места зависит.
      Я рассматривал вариант использования маршрутизаторов со встроенной sim картой — по идеи должны лучше работать, так как антена больше. Для себя рассматривал:


      1. huawei e5170 — стоит у соседа. Все круто: можно докупить внешнюю батарею, 3G/4G. Но только один ethernet порт и мне показалось, что функционал несколько ограничен.
      2. Zyxel LTE — тут все хорошо с функциональной частью, но он только LTE, что тоже не подходит.

      Пока все нормально работает — отложил этот вопрос.


      невозможно пользоваться сервисами типа dyndns

      У меня та же проблема. Даже платно я не нашел как у моего оператора "отбелить" ip адрес, возможно это доступно только для бизнеса. Да я и не особо долго искал.


      Все эти танцы с впн, телеграмом, и т.д. и т.п. несколько напрягают… Может есть ещё какие-то варианты?

      Как я уже упомянал выше — в следующей статье я опишу вариант интеграции с Apple HomeKit. Все, что нужно — настроить работу HomeKit с парком умных устройств (в моем случае через OpenHab), все остально Apple делает сама: доступ к умному дому из любой точки без всяких VPN, сценарии автоматизации (по времени и геопозиции доверенных устройств), частичное решение проблемы для силовых блоков без обратной связи (запоминает их состояние), голосовое управление через Siri + готовое приложение для работы с умным домом. Но это все только под iOS.


      1. Adamantium
        12.10.2016 10:54

        Спасибо за развернутый ответ, почерпнул много полезного, будем ждать дальнейшего описания тогда!


  1. NLO
    12.10.2016 10:46

    НЛО прилетело и опубликовало эту надпись здесь


    1. AlekseevAV
      12.10.2016 10:56

      Пока из противопожарных мер я использую:


      • когда мы в доме — пожарные извещатели, которые просто пищат от дыма и огня;
      • когда нас нет — как-то мне достались несколько противопожарных самосрабатывающих огнетушителей. Конечно, не панацея, но лучше чем ничего.


      1. NLO
        12.10.2016 11:12

        НЛО прилетело и опубликовало эту надпись здесь


        1. AlekseevAV
          12.10.2016 12:12

          Думал об этом. Уже давно присматриваюсь к видеонаблюдению, но пока дороговато выходит.


  1. AndrF
    12.10.2016 11:42

    В доме, как я понял, электроотопление. Есть неплохие готовые решения, причем российского происхождения:

    MCS 350 — терморегулятор с управлением по WiFi — стоит где-то от 6500 руб.
    Терморегуляторы Zont (сайт zont-online.ru) — более интересные, но несколько дороже. Варианты с доступом как по WiFi, так и GSM.

    У меня дома газовый котел — использую старый MSC-300 с небольшой переделкой, которая была сделана для того чтобы он мог управлять газовым котлом…


    1. AlekseevAV
      12.10.2016 12:05

      Спасибо за наводку.
      Да, электроотопление с помощью потолочных ИК батарей для каждой комнаты.
      MCS 350 — понравился, но он встраиваемый. Опять же ограничения для деревянных домов по скрытой проводке.


      1. AndrF
        12.10.2016 12:23

        Встраиваемость, если это нужно, легко обходится внешней коробкой.

        Мне больше Zont-овские терморегуляторы нравятся — они же позволяют легко и охрану создать. Кроме того — можете глянуть у них другие разделы продукции. Те же автосигнализации управляемые по GSP и с GPS модулями довольно интересны, но пока малоизвестны — сам наткнулся случайно когда искал себе взамен сдохшей…

        Или их домашние сигнализации — на них можно сделать кучу всего, подключая камеры, управление воротами и прочее…

        И вся их продукция управляется с обычного смартфона. В общем, очень хорошо ребята за дело взялись.


      1. AndrF
        12.10.2016 12:31

        И еще — гляньте ZONT L-1000 — он вроде в стадии выпуска, но наворочен для сложных систем, и реализован как раз на Raspberry Pi…


  1. 2PAE
    12.10.2016 12:53
    +1

    Большинство из того что называется «Умным домом» на поверку лишь исполнительный.
    Ум — это совокупность способностей к восприятию, запоминанию, обобщению, оценке и принятию решения.

    Действительно умный дом, сам должен принять решение, на основании полученных сведений. Решение задачи «Будем на даче к 20:00» уже будет чуть ближе к умному дому. Хотя скорее всего, лишь чуть чуть более сложная цепочка «исполнительного» дома…

    Вообще я конечно согласен с идей, что «Умных нам не треба, нам верные (исполнительные) нужны» но зачем тогда лукавить? Так и пишите, «Исполнительный дом».


    1. AndrF
      12.10.2016 13:29

      Ну, в принципе да. Позвонил по телефону, сказал во сколько будешь, приезжаешь — уже тепло, кушать подано и жена встречает на пороге ;)


      1. NLO
        12.10.2016 13:36

        НЛО прилетело и опубликовало эту надпись здесь


  1. yagbul
    12.10.2016 15:32

    Люди, вы совсем забыли про систему Кситал! Почитайте в интернете.
    Туда можно и любой аккумулятор подключить 12В, сам будет заряжать. Состоит из 2 модулей GSM, взаиморезервируемых. Много сухих контактов, много релешек, можно подключить кучу термометров. Может вам позвонить и сказать, что нарушение охраны, или упала температура, сработал пожарный сигнализатор. Температурой управляет сам, по своим датчикам. Можно привязать управление на любой датчик температуры… Есть приложение, где уже готовые шаблоны запроса, включения, выключения устройств. Хоть датчик протечки включит, и через реле перекрой кран.


    1. AlekseevAV
      12.10.2016 17:12

      Отличное решение, если функционал устройства покрывает задачу на 100% и дальнейшего развития не предвидится. У нас недавно в серверную поставили как раз Кситал. Но я бы не хотел такое решение в дом:


      1. Нужно тянуть провода. Может для кого-то это не проблема, но мне проще без этого, так как схемы подключения у меня часто меняются и перенести беспроводной блок несомненно легче, чем вскрывать весь кабель канал. Опять же если проектировать один раз и на века — это не проблема.
      2. Нет пультов-выключателей (возможно ошибаюсь). У NooLite помимо управления через шлюз, можно прилепить к стене внешне обычный выключатель, который и будет работать как обычный. Тут вопрос с обратной связью, но они обещают в ближайшее время выпустить новые силовые блоки уже с ней.
      3. Лично мне управление через SMS совершенно не нравится. Думаю, что и большинству конечных пользователей при прочих равных, не беря в расчет тонкости внутренней реализации, интерфейс в любом виде, будь то веб или приложение, понравится больше, чем SMS. В следующей статье я приведу скриншоты из приложения "Дом" для iOS — все очень красиво и удобно сделано.


      1. yagbul
        13.10.2016 09:50

        1) В вашем случае нужно тянуть кабель UTP для Ethernet, с питанием проблемы (каждый датчик как вы собираетесь зарезервировать? придется тянуть, двойная работа. А батарейки быстро разряжаются). Кстати у кситал тоже есть беспроводной блок и можно подключить беспроводные датчики.
        2) Пульт включения-выключения есть, можно снимать/ставить на охрану, и вроде можно запрограммировать для других целей.
        3) Говорю же, у них приложение есть, смски самому строчить не нужно, работаешь так же через меню, каждая кнопка это шаблон.
        4) Резервировать вам нужно будет и первый роутер, и второй, и комп у вас в городе на котором поднят впн сервер. Придется и интернет и на даче и дома резервировать (а у кситал два модуля — две симки. Резервирование одного устройства и по питанию и связи сразу).
        5) Стоимость кситала 8т.р.
        6) Работает на рынке уже десятилетиями, проверенное временем надежное устройство. Делай что хочешь, можно подключить чего угодно, любые датчики, любые механизмы.
        7) Когда питание пропадает, кситал сам оповещает, что отсутствует питание и что котел отключился, есть проблемы с обмораживанием труб. (без аккумулятора здесь не обойтись, так как нужно оповестить после отключения питания)

        Конечно же он параметры не может прислать всякие (напряжения, тока, итд а только через сухие контакты), но этого достаточно бывает. На сухой контакт повесил датчик загазованности комнаты и пару датчиков дыма, охранные датчики, вывел провод на сирену.

        Умный дом — это будущее, но на сегодняшний день мало оптимальных, надежных и дешевых систем.


  1. Mishha
    13.10.2016 21:29

    Друзья, здесь столько спецов смотрю собралось, может кто-то мне подскажет решение моей проблемы. У меня теплые водяные полы, отапливается газовым настенным котлом Vaillant. Также установлены термостаты(механические, которые надо крутить рукой) и сервоприводы. Термостаты — контролирующие и управляющие устройства, сервоприводы — исполнительные. Сервоприводы устанавливаются в каждый контур на гребенке подачи теплоносителя. Погода независимой автоматики нет. Термостаты ловят температуру воздуха в каждой комнате и уменьшают или увеличивают количество теплоносителя, поступающего в отопительный контур. Таким образом поддерживается заданная температура в каждой комнате отдельно. Котел у меня не как не программируется.Можно только погоду независимою автоматику повесить, как я понимаю. Задача: например зимой на буднях выставить температуру так, что бы в комнатах она была к примеру 15 градусов, а к выходным, нагревала до 23 градусов или то же самое, но по каким то удаленным команда это делать самостоятельно. Это то что я хотел бы, но пока не понимаю как этого достичь с механическими термостатами. Как думаете что можно сделать?