CCU.IO + DashUI

Обсуждение статей, технологий домашней автоматизации, программных и аппаратных решений
Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

CCU.IO + DashUI

Сообщение Bluefox » 16 июн 2014, 18:20

Добрый день!
Хочу представить платформу автоматизации для дома на базе NodeJS.


Немного истории:
Я с детства (14 лет) увлекаюсь автоматизацией и моя актуальная профессия отражает мои увлечения. Представленная система - это уже третья итерация системы автоматизации в моем жилище.

Первая была X10 + HTTP Requests,
вторая HomeMatic + PHP/MySQL (про них можно почитать на хабре http://habrahabr.ru/post/149716/ )
и вот третья HomeMatic + NodeJS / JavaScript.

Разработка системы началась в январе 2013, хотя активный рост начался в мае 2013 и сейчас над системой регулярно (каждый день) работают 3 разработчика и рук на всё уже не хватает.
У некоторых возникнет, вполне уместный вопрос: зачем мне (нам) рассказывать о своей системе?

Ответ: я вижу с какими половинчатыми решениями живут энтузиасты автоматизации домов и хочу предложить более менее законченное решения для комплексного программного обеспечения автоматизации дома. От драйверов до скриптов и визуализации. Все компоненты системы имеют лицензию либо MIT либо CC NC BY. Что значит, для не коммерческого использования абсолютно бесплатно, хотя система включает в себя 3 человека-"хобби"-лет разработки. Я сам инвестировал в систему 1 год разработки по 2 часа в день (каждый день, включая выходные).



Структуру компонентов можно представить таким образом:
MainScheme.png
MainScheme.png (66.61 КБ) 30483 просмотра
Компоненты системы:

1. CCU.IO - ядро системы. Название CCU пришло из HomeMatic, где CCU это центральный контроллер и gateway для связи по ethernet.
В данный момент ядро переписывается, что бы уйти от архитектуры HomeMatic и т. к. уже в сегодняшнем виде система поддерживает и другие системы автоматизации, то новая будет называться ioBroker.
Ядро написано на NodeJS/JavaScript и может быть запущено на почти любой платформе, для которой есть NodeJS бинарники. В настоящий момент высокая степень интеграции создана для Raspberry PI. Известно точно, что пользователи запустили систему на Windows, OSX, QNAP (ARM/Intell) Synology, Cubietrack, BananaPI, Odroid, Ubuntu (x86) und Debian.
CCU.IO является только связующим звеном между компонентами. Из него же происходит запуск драйверов (adapters) с указанными параметрами.

GitHub: https://github.com/hobbyquaker/ccu.io

2. Драйвера (адаптеры)
Драйвер это JavaScript файл, запускающийся в отдельном NodeJS процессе и обслуживающий одно устройство или службу. На данный момент созданы следующие драйвера:

- email - для отправки сообщений по электронной почте
- pushover - для отправки сообщений на мобильные клиенты (http://pushover.net)
- mysql - пересылка событий в базу данных
- graphite - пересылка событий в graphite (http://graphite.wikidot.com/screen-shots). Группировка данных в мыслимых и немыслимых формах и их отображение в виде графиков.
- ical - Google и Apple iCloud календари
- geofency - поддержка Apple системы геолокации geofency
- growl - сообщения на Apple Growl App
- currency - курсы валют с европейского центрального банка. (Есть EUR-RUB и USD-RUB)

- telnet - управление приборами по telnet протоколу
- ping - пингует IP устройства в сети

- lirc - для управления приборами и принятия команд по инфракрасному порту (требуется дополнительное железо)
- irtrans - поддержка IRTrans инфракрасной системы (http://www.irtrans.de/en/)

- hue - управление PhilipsHUE лампами
- lgtv - управление LG телевизорами по сети
- denon - управление DENON ресиверами
- onkyo - управление ONKYO ресиверами
- yamaha - управление YAMAHA ресиверами
- sonos - управление SONOS системой звука
- dream - управление DreamBOX спутниковыми ресиверами (http://ru.wikipedia.org/wiki/Dreambox)
- owfs - One Wire File System (http://owfs.org/) - сбор данных с датчиков Dallas/Maxim по 1-Wire
- B-control Energy Manager - мониториг расхода электроэнергии http://www.b-control.com/energiemanagement.html (нет описания на английском)
- all3418v2 - ALLNET ALL3418v2 / IP Thermometer LAN / WLAN - беспроводной термометр - http://www.allnet.de/en/allnet-brand/pr ... r-lanwlan/
- homepilot - управление системой автоматизации Rademacher.
- homematic - управление системой автоматизации HomeMatic (встроено в CCU.IO).
- rego - мониторинг котлов Junkers TM75, IVT Rego 634

- rpi - мониторинг основных параметров (CPU, Mem, Temperature) RaspberryPI. Поддержка 1-Wire интерфейса и PiFace.
- cubie - мониторинг основных параметров (CPU, Mem, Temperature, Battery) Cubietruck.

- sayit - голосовые сообщения (text2speech или wav) на системе(Linux, Windows, OsX) или android планшете (через Home24 Mediaplayer - https://play.google.com/store/apps/deta ... ayer&hl=ru).

- owm - OpenWeatherMap (http://openweathermap.org/) - погода по всему миру
- yr - погода с норвежского сервера http://www.yr.no/
- dwd - официальные предупреждения о штормах в Германии

- fritzBox - отображение списка звонивших для fritzBox
- speedport - отображение списка звонивших для speedport

- sun_and_time - время захода и восхода солнца, а также праздничные дни для Германии
- muell_stuttgart - время вывоза мусора в Штутгарте

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

3. Script Engine
Сценарии реакций на события (Собственно - автоматизация)
Script Engine тоже запускается в собственном процессе, как драйвер и служит для выполнения пользовательских скриптов на JavaScript. Все скрипты лежащие в папке ccu.io/scripts будут запущены. Управление происходит следующим образом:

Код: Выделить всё

// Простые события
var swicthID = 79111; // Адрес кнопки
var actorID  = 80187; // Адрес силового реле

// подписываемся на нажатие кнопки
subscribe(swicthID, function (obj) {
        // передаем состояние на реле
	setState(actorID, obj.newState.value);
});

// Можно так
subscribe(79111, function (obj) {setState(80187, obj.newState.value)});

 
Вот пример посложнее:

Код: Выделить всё

var postboxTimer;
var postboxSensorID = 11222; // Id для сенсора на дверце почтового ящика
var postboxStateID = 100015; // Собственная переменная в CCU.IO для отображения числа открытия дверцы почтового ящика

// Подписываемся на открытие/закрытие дверцы
subscribe(postboxSensorID, function (obj) {

	// Если таймер ещё не запущен
    if (!postboxTimer) {

		// Стартуем таймер на 30 секунд, что бы отбросить быстрые открытия/закрытия
        postboxTimer = setTimeout(function () {
            postboxTimer = null;
        }, 30000);

		// Увеличиваем счетчик
        setState(postboxStateID, 1 + getState(postboxStateID ));
    }
});

// При старте создаем собственную переменную в CCU.IO
setObject(postboxStateID , {
    Name: "Postbox.State",
    TypeName: "VARDP"
}, function () {
    setState(postboxStateID , 0);
});
Если возникнет интерес я переведу документацию с немецкого.


Для SctiprEngine написана визуальная система создания скриптов, где всё программирование происходит с drug&drop. Недостаток: интерфейс на немецком и перевод запланирован в версии 0.9 (сейчас 0.6). Но я могу либо перевести сам, либо подтолкнуть товарища, что бы он перевел.

https://www.youtube.com/watch?v=xeBXTDa ... AVPXPychU7
ScriptGUI.png
ScriptGUI.png (386.1 КБ) 30483 просмотра
Из за ограничения на 5 картинок в посте, продолжение следует...
Последний раз редактировалось Bluefox 20 июн 2014, 12:55, всего редактировалось 4 раза.

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

DashUI

Сообщение Bluefox » 16 июн 2014, 18:21

4. Дополнение DashUI (Читается Дэш-ЮАЙ)
Система визуализации для умного дома.
Вот примеры интерфейсов созданных с помощью DashUI:
user8.png
user8.png (49.09 КБ) 30482 просмотра
user0.png
user0.png (78.52 КБ) 30482 просмотра
user2.png
user2.png (57.84 КБ) 30482 просмотра
user5.png
user5.png (74.13 КБ) 30482 просмотра
user6.png
user6.png (38.97 КБ) 30482 просмотра
Последний раз редактировалось Bluefox 16 июн 2014, 18:37, всего редактировалось 1 раз.

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

DashUI

Сообщение Bluefox » 16 июн 2014, 18:24

user6.png
user6.png (38.97 КБ) 30482 просмотра
metro.png
metro.png (43.62 КБ) 30482 просмотра
По адресу http://DashUI.ccu.io их можно потыкать и посмотреть на скорость. Хочу заметить, что отображение графиков и таблиц не работает в оффлайн режиме, так что не удивляйтесь, если некоторые страницы окажутся пустыми.

При презентации системы со мной случился казус: один человек ответил, что ему не нравиться Metro-Дизайн и поэтому он не будет использовать DashUI. Я был огорошен: из 10 разных примеров и способов создавать страницы только один в стиле Metro. Хоть стой, хоть падай. :)

Я же хотел показать, сколько различных вариантов оформления можно сделать. Есть даже такие (в стиле Star Trek):
file.png
file.png (42.55 КБ) 30482 просмотра
file(1).png
file(1).png (31.7 КБ) 30482 просмотра
Кстати, разработчик, который создал Metro-элементы, не использует их сам, комментируя, что элементы слишком громоздки и что он написал элементы (widgets), только, что бы создать разнообразие интерфейсов. Я же нахожу интерфейс очень привлекательным и скоро нарисую себе интерфейс для android телефона с MetroUI.

Есть видео создания простенького интерфейса с чистого листа:
https://www.youtube.com/watch?v=SztQvWVttnM
Вот ещё несколько видео:
https://www.youtube.com/watch?v=viE5y8Y ... 3Mj-ZU4Cp4
https://www.youtube.com/watch?v=gS-O5OKjQhk
https://www.youtube.com/watch?v=xjr2nE98Fkg

Недостатки дополнения в том, что интерфейс не масштабируется автоматически под экран. Но с другой стороны можно нарисовать 2 интерфейса: для таблета / десктопа и для телефона. Как многие и делают.

GitHub: https://github.com/hobbyquaker/DashUI
Последний раз редактировалось Bluefox 16 июн 2014, 18:57, всего редактировалось 2 раза.

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

MobileUI, SimpleAPI

Сообщение Bluefox » 16 июн 2014, 18:28

5. Дополнение MobileUI
В данный момент называется Yet another home user interface - yahui. Но мне название режет ухо и мы скоро переименуем его в MobileUI.
Этот интерфейс выглядит в виде списка устройств. Можно назначить каждому устройству или комнате собственные картинки или переименовать. На этом конфигурация системы закончена.
yahui5.png
yahui5.png (350.81 КБ) 30482 просмотра
yahui4.png
yahui4.png (193.7 КБ) 30482 просмотра
Это дополнение (Add-on) использует jQuery Mobile и автоматически изменяется, в зависимости от устройства, где вызвана страница.
yahui1.png
yahui1.png (119.46 КБ) 30482 просмотра
6. Интерфейс SlimUI
Система веб визуализации на "Vanilla" Javasript для очень старых браузеров и слабых устройств. Никакие библиотеки (jQuery или подобные) не используются. Данные опрашиваются по таймеру (polling), а команды отдаются через RestAPI (SimpleAPI).

GitHub: https://github.com/hobbyquaker/SlimUI

7. SimpleAPI
Интерфейс основанный на HTTP-GET запросах вида:

Код: Выделить всё

http://ccu-io-host:ccu.io-port/api/get/950
где 950 - это адрес переменной.

Ответ отдается в JSON формате или просто значение, как текст.
Управление выглядит вот так:

Код: Выделить всё

http://ccu-io-host:ccu.io-port/api/set/950/?value=1
http://ccu-io-host:ccu.io-port/api/set/Свет-кухня/LEVEL/?value=0.7
Используется для коммуникации CCU.IO с внешними программами, такими как Trigger или Tasker. Я, например, использую интерфейс для открытия замка двери по NFC тэгу, через Trigger.
Последний раз редактировалось Bluefox 16 июн 2014, 18:38, всего редактировалось 1 раз.

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

CCU.IO-Highcharts, CCU.IO-Eventlist, Graphite

Сообщение Bluefox » 16 июн 2014, 18:32

8. Дополнение CCU.IO-Highcharts.
Рисование графиков используя исторические данные, сохраненные CCU.IO.
saved_resource(2).png
saved_resource(2).png (177.13 КБ) 30482 просмотра
GitHub: https://github.com/hobbyquaker/CCU-IO-Highcharts

9. Дополнение CCU.IO-Eventlist.
Используется для отображения событий записанных CCU.IO
saved_resource(3).png
saved_resource(3).png (82.98 КБ) 30482 просмотра
10. Адаптер Graphite.
Мощный инструмент визуализации данных, созданный другой командой. Может складывать графики и производить манипуляции с данными. Например, посчитать: сколько времени за последний месяц горели лампы в зале.
file(2).png
file(2).png (87.74 КБ) 30482 просмотра
Но я сам его не использую, т.к. для нормальной работы требуется что-то по-мощнее RaspberryPi, а еще из-за жуткой нехватки времени.

http://graphite.wikidot.com/screen-shots
https://github.com/graphite-project/graphite-web
Последний раз редактировалось Bluefox 16 июн 2014, 18:49, всего редактировалось 2 раза.

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

Инсталляция

Сообщение Bluefox » 16 июн 2014, 18:36

11. Инсталляция.
Требования: для платформы нужен работающий бинарный файл Node.js с версией больше 0.8. Скачать можно либо с официального сайта http://nodejs.org/download/ или здесь http://ccu.io/download.html.

Инсталляция под Windows:
- Скачать http://dashui.ccu.io/download/ccu.ioIns ... 1.0.39.exe и запустить (Node.js дополнительно не нужен)

Инсталляция в ручном режиме:
- скачать и распаковать файл с CCU.IO https://github.com/hobbyquaker/ccu.io/a ... master.zip
- перейти в распакованную папку
- запустить CCU.IO сервер: node ccu.io-server.js start или под windows: node.exe ccu.io-server.js start
- вызвать веб интерфейс для настроек: http://hostname:8080/ccu.io
- настроить язык (русский в основном присутствует), настроить адаптеры и перезапустить ccu.io в CCU.IO -> Контроль -> Перезапуск CCU.IO
saved_resource(4).png
saved_resource(4).png (33.32 КБ) 30482 просмотра
Остается необходимость автоматического запуска сервера при старте компьютера/системы, но это решаемо.

Инсталляция Debian-пакета (RaspberyPI):
Войти в консоль raspberry под именем "pi" и для инсталляции Node.js и CCU.IO выполнить:

wget http://ccu.io.mainskater.de/nodejs_0.10.22-1_armhf.deb
wget http://ccu.io.mainskater.de/ccu.io_1.0.29.deb
sudo dpkg -i nodejs_0.10.22-1_armhf.deb
sudo dpkg -i ccu.io_1.0.29.deb

- вызвать веб интерфейс для настроек: http://hostname:8080/ccu.io
- настроить язык (русский в основном присутствует), настроить адаптеры и перезапустить ccu.io в CCU.IO -> Контроль -> Перезапуск CCU.IO

Протестированные платформы:
- Raspbian (RaspberryPi)
- Cubian (Cubieboard/Cubietruck)
- RCU (CCU2 Firmware auf RaspberryPi)
- Homematic CCU2
- Mac OS X
- Windows
- x86 und amd64 Linux
- QNAP TS-469 Pro (vermutlich auch auf allen anderen x86-basierten QNAP NAS)
- QNAP TS-419II (vermutlich auch auf anderen ARM-basierten QNAP NAS)
- Synology DS212, DS214play, DS412+, DS413j (vermutlich auf den meisten ARM- und Atom-basierten Synolgy)
- Western Digital My Cloud
- Odroid with Debian.
- BananaPi with Raspbian

Из конфигурационной страницы CCU.IO можно установить и обновить все другие дополнения:
saved_resource(5).png
saved_resource(5).png (45.79 КБ) 30482 просмотра
Кроме graphite.

На данный момент один человек без глубоких знаний JavaScript написал драйвер для zwave. Мне ещё надо посмотреть самому на драйвер, перед тем, как его выложить.
Я думаю, что можно создать драйвера для NooLite (http://www.noo.com.by/sistema-noolite.html), для обсуждаемого здесь Мега девайса и закончить адаптер для ZWave, для яндекс погоды и для всего, что вам придет в голову :)
Насчет Мега девайса есть открытый вопрос: какая система установлена в нем и можно ли запустить на ней Node.js?

Я не нашел других обитаемых сайтов по автоматизации, а на этом есть даже 1000 человек :)
С удовольствием отвечу на все ваши вопросы, если вообще кому нибудь будет интересно.

P.S Статья писалась с прицелом на хабр, по этому не удивляйтесь, если некоторые отрывки потом появятся там.
Последний раз редактировалось Bluefox 20 июн 2014, 11:23, всего редактировалось 1 раз.

plusQ
Сообщения: 115
Зарегистрирован: 01 фев 2013, 15:29
Контактная информация:

Re: CCU.IO + DashUI

Сообщение plusQ » 16 июн 2014, 21:34

интерфейс понравился... попытаюсь написать что то под Мегу
как я понял там объектно оринтированное програмирование, нужно вникать

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

Создание адаптера для CCU.IO

Сообщение Bluefox » 17 июн 2014, 02:01

Если вы решили написать свой драйвер, то не пугайтесь - это не сложно. Не нужно знаний в ООП, а также не нужно глубоких знаний в JavaScript.

Начать стоит с того, что бы решить, как драйвер будет называться. Возьмем gismeteo.

Создаем папку gismeteo в ccu.io/adapter.
Копируем файл ccu.io / adapter / skeleton-socket.io.js в ccu.io/adapter/gismeteo и переименовываем в gismeteo.js. Как вы уже догадались, исполняемый файл должен называться так же, как и драйвер.
Берем файл настроек ccu.io / adapter / currency / settings.json (https://github.com/GermanBluefox/ccu.io ... tings.json - так как на момент написания топика, он еще не merged с основным кодом) и копируем тоже в ccu.io/adapter/gismeteo

Содержание файла settings.json:

Код: Выделить всё

{
    "enabled": false,
    "settings": {
        "firstId":    73500,
        "pollIntervalHours": 6
    }
}

Нужно сделать две вещи:
- Согласовать адресное пространство с другими адаптерами. Для этого нужно найти свободное пространство адресов в файле adapter_ids.txt (https://github.com/hobbyquaker/ccu.io/b ... er_ids.txt). Например, возьмем 71300-71350.
- Продумать, какие настройки нужны для нашего драйвера. В нашем случае: частота обновления в часах и ID города.

Изменяем settings.json, согласно нашим данным:

Код: Выделить всё

{
    "enabled": true,
    "settings": {
        "firstId":    71300,
        "cityId":      28722,
        "pollIntervalHours": 6
    }
}
ID для города можно получить здесь: http://informer.gismeteo.com/getcode/xml.php?id=27612


Открываем файл gismeteo.js в любимом редакторе. Я пол-года пользовался notepad++, потом купил WebStrorm, который, надо сказать, вгоняет мой ноутбук iCore7 в ступор. Кстати, для OpenSource проектов WebStorm можно заказать совершенно бесплатно, что я и сделал через год истечения моей купленной подписки.
Итак, открываем файл ставим кодировку на UTF8 (без BOM) и видим:

Код: Выделить всё

var settings = require(__dirname+'/../../settings.js');

if (!settings.adapters.ADAPTERNAME || !settings.adapters.ADAPTERNAME.enabled) {
    process.exit();
}

var logger =    require(__dirname+'/../../logger.js'),
    io =        require('socket.io-client');


if (settings.ioListenPort) {
    var socket = io.connect("127.0.0.1", {
        port: settings.ioListenPort
    });
} else if (settings.ioListenPortSsl) {
    var socket = io.connect("127.0.0.1", {
        port: settings.ioListenPortSsl,
        secure: true,
    });
} else {
    process.exit();
}


socket.on('connect', function () {
    logger.info("adapter xxx    connected to ccu.io");
});

socket.on('disconnect', function () {
    logger.info("adapter xxx    disconnected from ccu.io");
});

socket.on('event', function (obj) {
    if (!obj || !obj[0]) {
        return;
    }
});

function stop() {
    logger.info("adapter xxx   terminating");
    setTimeout(function () {
        process.exit();
    }, 250);
}

process.on('SIGINT', function () {
    stop();
});

process.on('SIGTERM', function () {
    stop();
});
Заменяем ADAPTERNAME и xxx на gismeteo.

Начнем расширять функциональность драйвера, т.к. сейчас он не делает ничего, кроме того, что слушает события от CCU.IO и выбрасывает их.

Код: Выделить всё

 //Считать файл с настройками
var settings = require(__dirname + '/../../settings.js');
// Если настройки для драйвера не существуют или драйвер деактивирован
if (!settings.adapters.gismeteo || !settings.adapters.gismeteo.enabled) {
     // Завершаем процесс и не тратим память впустую
    process.exit();
}

// Подключаем модули для протоколирования и коммуникации с CCU.IO
var logger =    require(__dirname+'/../../logger.js'),
    io =        require('socket.io-client'),
    // Загрузим еще и модуль для выполнения GET/POST запросов по http
    http =        require('http'),
    // А также модуль парсинга XML, т.к. ГисМетео отдает результаты в XML
    parseString =  require('xml2js').parseString;


//Надо продумать структуру данных. Данные в CCU.IO устроены по следующему принципу.
//Device => Channel => Datapoint
//          Channel => Datapoint
//                  => Datapoint

// То есть в корне располагается устройство, у которого есть список каналов. Каждый канал должен иметь в списке детей хотя бы одну переменную (datapoint).

//Если посмотреть на возвращаемый формат XML файла:
//<MMWEATHER>
//	<REPORT type="frc3">
//		<TOWN index="28722" sname="%D3%F4%E0" latitude="54" longitude="55">
//			<FORECAST day="16" month="06" year="2014" hour="21" tod="3" predict="0" weekday="2">
//				<PHENOMENA cloudiness="0" precipitation="10" rpower="0" spower="0"/>
//				<PRESSURE max="745" min="743"/>
//				<TEMPERATURE max="15" min="13"/>
//				<WIND min="1" max="3" direction="5"/>
//				<RELWET max="77" min="75"/>
//				<HEAT min="13" max="15"/>
//			</FORECAST>
//			<FORECAST day="17" month="06" year="2014" hour="03" tod="0" predict="0" weekday="3">
//				<PHENOMENA cloudiness="1" precipitation="10" rpower="0" spower="0"/>
//				<PRESSURE max="746" min="744"/>
//				<TEMPERATURE max="11" min="9"/>
//				<WIND min="-1" max="1" direction="1"/>
//				<RELWET max="93" min="91"/>
//				<HEAT min="9" max="11"/>
//			</FORECAST>
//			<FORECAST day="17" month="06" year="2014" hour="09" tod="1" predict="0" weekday="3">
//				<PHENOMENA cloudiness="0" precipitation="10" rpower="0" spower="0"/>
//				<PRESSURE max="747" min="745"/>
//				<TEMPERATURE max="15" min="13"/>
//				<WIND min="0" max="2" direction="5"/>
//				<RELWET max="85" min="83"/>
//				<HEAT min="13" max="15"/>
//			</FORECAST>
//			<FORECAST day="17" month="06" year="2014" hour="15" tod="2" predict="0" weekday="3">
//				<PHENOMENA cloudiness="2" precipitation="10" rpower="0" spower="0"/>
//				<PRESSURE max="748" min="746"/>
//				<TEMPERATURE max="20" min="18"/>
//				<WIND min="3" max="5" direction="5"/>
//				<RELWET max="54" min="52"/>
//				<HEAT min="18" max="20"/>
//			</FORECAST>
//		</TOWN>
//	</REPORT>
//</MMWEATHER>
 
// То можно видеть, что ответ содержит данные для сегодня и три значения на завтра.
// Я буду использовать вот такую структуру данных.
// gismeteo(Device) => now (channel)   => DATE         (datapoint)
//                                     => PRESSURE_MIN (datapoint)
//                                     => PRESSURE_MAX (datapoint)
//                                     => TEMPERATURE  (datapoint)
//                                     => HUMIDITY     (datapoint. Может, конечно, RELWET означает вероятность дождя, но для данного примера это не так важно)
// 
//                     next (channel)  => DATE         (datapoint)
//                                     => PRESSURE_MIN (datapoint)
//                                     => PRESSURE_MAX (datapoint)
//                                     => TEMPERATURE  (datapoint)
//                                     => HUMIDITY     (datapoint. Может, конечно, RELWET означает вероятность дождя, но для данного примера это не так важно)
// 
// Создадим внутренние переменные:
 
var pollTimer        = null, // Таймер для опроса gismeteo
    socket           = null, // Сокет для коммуникации с CCU.IO
    gismeteoSettings = settings.adapters.gismeteo.settings; // Переменная с настройками драйвера (вернемся к настройкам позже)
   
// Соединяемся с CCU.IO
if (settings.ioListenPort) {
    socket = io.connect("127.0.0.1", {
        port: settings.ioListenPort
    });
} else if (settings.ioListenPortSsl) {
    socket = io.connect("127.0.0.1", {
        port: settings.ioListenPortSsl,
        secure: true
    });
} else {
    process.exit();
}

// Реакция на события из сокета
// При соединении
socket.on('connect', function () {
    // драйвер соединился с ccu.io
    logger.info("adapter gismeteo connected to ccu.io");
});

socket.on('disconnect', function () {
    // драйвер потерял соединение с ccu.io. Ничего делать не надо. Он сам снова соединится.
    logger.info("adapter gismeteo disconnected from ccu.io");
});

// Событие от CCU.IO (напишем код позже)
socket.on('event', function (obj) {
    if (!obj || !obj[0]) {
        return;
    }
});

// Функция завершения драйвера. Очень важно, иначе драйвер при перезапуске CCU.IO останется висеть в памяти и будет дальше пытаться соединится
function stop() {
    logger.info("adapter gismeteo terminating");

	// Останавливаем таймер
	if (pollTimer) {
		clearInterval(pollTimer);
		pollTimer = null; // форсируем запуск сборщика мусора
	}
	
	// и через 250 мсекунд завершаем процесс
    setTimeout(function () {
        process.exit();
    }, 250);
}

process.on('SIGINT', function () {
    stop();
});

process.on('SIGTERM', function () {
    stop();
});

// Упростив вызов создания объекта
function setObject (id, obj) {
	socket.emit("setObject", id, obj);
}
function setState(id, val) {
	socket.emit("setState", [id, val, null, true]);
}

// Теперь создаем объекты. Здесь важно использовать настройки для драйвера, которая определяет адресное пространство драйвера firstId
var rootDevice   = gismeteoSettings.firstId;
var nowChannel = rootDevice + 1;
var nowChannel_DPs = {
		DATE:         nowChannel + 1, 
		PRESSURE_MIN: nowChannel + 2, 
		PRESSURE_MAX: nowChannel + 3,
		TEMPERATURE:  nowChannel + 4,
		HUMIDITY:     nowChannel + 5
	};

var nextChannel = nowChannel + 6;
var nextChannel_DPs = {
		DATE:         nextChannel + 1, 
		PRESSURE_MIN: nextChannel + 2, 
		PRESSURE_MAX: nextChannel + 3,
		TEMPERATURE:  nextChannel + 4,
		HUMIDITY:     nextChannel + 5
	};

//Создаем объекты в CCU.IO при старте
function initGismeteo () {
	// Сначала переменные для канала сегодня
	setObject(nowChannel_DPs.DATE, {
		Name:     "gismeteo.now.DATE",
		TypeName: "HSSDP", // говорит CCU.IO, что это переменная содержит реальные значения а не просто структурный элемент, т.е. это datapoint
		Parent:   nowChannel 
	});
	setObject(nowChannel_DPs.PRESSURE_MIN, {
		Name:     "gismeteo.now.PRESSURE_MIN",
		TypeName: "HSSDP", // говорит CCU.IO, что это переменная содержит реальные значения а не просто структурный элемент, т.е. это datapoint
		Parent:   nowChannel 
	});
	setObject(nowChannel_DPs.PRESSURE_MAX, {
		Name:     "gismeteo.now.PRESSURE_MAX",
		TypeName: "HSSDP", // говорит CCU.IO, что это переменная содержит реальные значения а не просто структурный элемент, т.е. это datapoint
		Parent:   nowChannel 
	});
	setObject(nowChannel_DPs.TEMPERATURE, {
		Name:     "gismeteo.now.TEMPERATURE",
		TypeName: "HSSDP", // говорит CCU.IO, что это переменная содержит реальные значения а не просто структурный элемент, т.е. это datapoint
		Parent:   nowChannel 
	});
	setObject(nowChannel_DPs.HUMIDITY, {
		Name:     "gismeteo.now.HUMIDITY",
		TypeName: "HSSDP", // говорит CCU.IO, что это переменная содержит реальные значения а не просто структурный элемент, т.е. это datapoint
		Parent:   nowChannel 
	});

	// Потом сам канал сегодня
	setObject(nowChannel, {
		Name:     "gismeteo.now", // Имя канала
		TypeName: "CHANNEL",        // Важно. Говорит CCU.IO, что это канал
		Address:  "gismeteo.now",
		HssType:  "gismeteo",       // Помоему это свойство можно опустить
		DPs:      nowChannel_DPs,
		Parent:   rootDevice        // Говорит адрес корневого элемента
	});
	
	// тоже самое для завтра
	setObject(nextChannel_DPs.DATE, {
		Name:     "gismeteo.next.DATE",
		TypeName: "HSSDP", // говорит CCU.IO, что это переменная содержит реальные значения а не просто структурный элемент, т.е. это datapoint
		Parent:   nextChannel 
	});	
	setObject(nextChannel_DPs.PRESSURE_MIN, {
		Name:     "gismeteo.next.PRESSURE_MIN",
		TypeName: "HSSDP", // говорит CCU.IO, что это переменная содержит реальные значения а не просто структурный элемент, т.е. это datapoint
		Parent:   nextChannel 
	});
	setObject(nextChannel_DPs.PRESSURE_MAX, {
		Name:     "gismeteo.next.PRESSURE_MAX",
		TypeName: "HSSDP", // говорит CCU.IO, что это переменная содержит реальные значения а не просто структурный элемент, т.е. это datapoint
		Parent:   nextChannel 
	});
	setObject(nextChannel_DPs.TEMPERATURE, {
		Name:     "gismeteo.next.TEMPERATURE",
		TypeName: "HSSDP", // говорит CCU.IO, что это переменная содержит реальные значения а не просто структурный элемент, т.е. это datapoint
		Parent:   nextChannel 
	});
	setObject(nextChannel_DPs.HUMIDITY, {
		Name:     "gismeteo.next.HUMIDITY",
		TypeName: "HSSDP", // говорит CCU.IO, что это переменная содержит реальные значения а не просто структурный элемент, т.е. это datapoint
		Parent:   nextChannel 
	});

	// Потом сам канал сегодня
	setObject(nextChannel, {
		Name:     "gismeteo.next", // Имя канала
		TypeName: "CHANNEL",        // Важно. Говорит CCU.IO, что это канал
		Address:  "gismeteo.next",
		HssType:  "gismeteo",       // Помоему это свойство можно опустить
		DPs:      nextChannel_DPs,
		Parent:   rootDevice        // Говорит адрес корневого элемента
	});	
	
	// И напоследок корневой элемент
	setObject(rootDevice, {
		Name:      "gismeteo",
		TypeName:  "DEVICE",
		HssType:   "gismeteo_ROOT",
		Address:   "gismeteo",
		Interface: "CCU.IO",
		Channels:  [      // Массив с адресами каналов
			nowChannel,
			nextChannel
		]
	});
	
	// Выполняем один раз опрос
	pollGismeteo();
	
	// и запускаем таймер
    pollTimer = setInterval(pollGismeteo, gismeteoSettings.pollIntervalHours * 3600000 /* ms */);
}

// запрашиваем объект 
function getXmlResponse(callback) {
    var options = {
        host: 'informer.gismeteo.com',
        port: 80,
        path: '/xml/' + gismeteoSettings.cityId + '_1.xml'
    };

    console.log('http://informer.gismeteo.com/xml/' + gismeteoSettings.cityId + '_1.xml');

    http.get(options, function(res) {
        var xmldata = '';
        res.setEncoding('utf8');
        res.on('error', function (e) {
            logger.warn ("currency: " + e);
        });
        res.on('data', function(chunk){
            xmldata += chunk;
        });
        res.on('end', function () {
            // Analyse answer and updates staties
            if (callback) {
                parseString(xmldata, function (err, data) {
                    var result = null;
                    if (!err && data) {
                        try {
							// я не знаю точно, какой объект вернет парсер XML, 
							// поэтому я сначала вывожу в консоли его структуру командой: console.log(JSON.stringify(data, "", " "));
							// получаем
							// {
							//  "MMWEATHER": {
							//   "REPORT": [
							//    {
							//     "$": {
							//      "type": "frc3"
							//     },
							//     "TOWN": [
							//      {
							//       "$": {
							//        "index": "28722",
							//        "sname": "%D3%F4%E0",
							//        "latitude": "54",
							//        "longitude": "55"
							//       },
							//       "FORECAST": [
							//        {
							//         "$": {
							//          "day": "17",
							//          "month": "06",
							//          "year": "2014",
							//          "hour": "03",
							//          "tod": "0",
							//          "predict": "0",
							//          "weekday": "3"
							//         },
							//         "PHENOMENA": [
							//          {
							//           "$": {
							//            "cloudiness": "1",
							//            "precipitation": "10",
							//            "rpower": "0",
							//            "spower": "0"
							//           }
							//          }
							//         ],
							//         "PRESSURE": [
							//          {
							//           "$": {
							//            "max": "746",
							//            "min": "744"
							//           }
							//          }
							//         ],
							//         "TEMPERATURE": [
							//          {
							//           "$": {
							//            "max": "11",
							//            "min": "9"
							//           }
							//          }
							//         ],
							//         "WIND": [
							//          {
							//           "$": {
							//            "min": "-1",
							//            "max": "1",
							//            "direction": "1"
							//           }
							//          }
							//         ],
							//         "RELWET": [
							//          {
							//           "$": {
							//            "max": "93",
							//            "min": "91"
							//           }
							//          }
							//         ],
							//         "HEAT": [
							//          {
							//           "$": {
							//            "min": "9",
							//            "max": "11"
							//           }
							//          }
							//         ]
							//        },
							//        {
							//         "$": {
							//          "day": "17",
							//          "month": "06",
							//          "year": "2014",
							//          "hour": "09",
							//          "tod": "1",
							//          "predict": "0",
							//          "weekday": "3"
							//         },
							//         "PHENOMENA": [
							//          {
							//           "$": {
							//            "cloudiness": "0",
							//            "precipitation": "10",
							//            "rpower": "0",
							//            "spower": "0"
							//           }
							//          }
							//         ],
							//         "PRESSURE": [
							//          {
							//           "$": {
							//            "max": "747",
							//            "min": "745"
							//           }
							//          }
							//         ],
							//         "TEMPERATURE": [
							//          {
							//           "$": {
							//            "max": "15",
							//            "min": "13"
							//           }
							//          }
							//         ],
							//         "WIND": [
							//          {
							//           "$": {
							//            "min": "0",
							//            "max": "2",
							//            "direction": "5"
							//           }
							//          }
							//         ],
							//         "RELWET": [
							//          {
							//           "$": {
							//            "max": "85",
							//            "min": "83"
							//           }
							//          }
							//         ],
							//         "HEAT": [
							//          {
							//           "$": {
							//            "min": "13",
							//            "max": "15"
							//           }
							//          }
							//         ]
							//        },
							//        {
							//         "$": {
							//          "day": "17",
							//          "month": "06",
							//          "year": "2014",
							//          "hour": "15",
							//          "tod": "2",
							//          "predict": "0",
							//          "weekday": "3"
							//         },
							//         "PHENOMENA": [
							//          {
							//           "$": {
							//            "cloudiness": "2",
							//            "precipitation": "10",
							//            "rpower": "0",
							//            "spower": "0"
							//           }
							//          }
							//         ],
							//         "PRESSURE": [
							//          {
							//           "$": {
							//            "max": "748",
							//            "min": "746"
							//           }
							//          }
							//         ],
							//         "TEMPERATURE": [
							//          {
							//           "$": {
							//            "max": "20",
							//            "min": "18"
							//           }
							//          }
							//         ],
							//         "WIND": [
							//          {
							//           "$": {
							//            "min": "3",
							//            "max": "5",
							//            "direction": "5"
							//           }
							//          }
							//         ],
							//         "RELWET": [
							//          {
							//           "$": {
							//            "max": "54",
							//            "min": "52"
							//           }
							//          }
							//         ],
							//         "HEAT": [
							//          {
							//           "$": {
							//            "min": "18",
							//            "max": "20"
							//           }
							//          }
							//         ]
							//        },
							//        {
							//         "$": {
							//          "day": "17",
							//          "month": "06",
							//          "year": "2014",
							//          "hour": "21",
							//          "tod": "3",
							//          "predict": "0",
							//          "weekday": "3"
							//         },
							//         "PHENOMENA": [
							//          {
							//           "$": {
							//            "cloudiness": "2",
							//            "precipitation": "10",
							//            "rpower": "0",
							//            "spower": "0"
							//           }
							//          }
							//         ],
							//         "PRESSURE": [
							//          {
							//           "$": {
							//            "max": "749",
							//            "min": "747"
							//           }
							//          }
							//         ],
							//         "TEMPERATURE": [
							//          {
							//           "$": {
							//            "max": "19",
							//            "min": "17"
							//           }
							//          }
							//         ],
							//         "WIND": [
							//          {
							//           "$": {
							//            "min": "0",
							//            "max": "2",
							//            "direction": "6"
							//           }
							//          }
							//         ],
							//         "RELWET": [
							//          {
							//           "$": {
							//            "max": "60",
							//            "min": "58"
							//           }
							//          }
							//         ],
							//         "HEAT": [
							//          {
							//           "$": {
							//            "min": "17",
							//            "max": "19"
							//           }
							//          }
							//         ]
							//        }
							//       ]
							//      }
							//     ]
							//    }
							//   ]
							//  }
							// }
							
							var list = data['MMWEATHER']['REPORT'][0]['TOWN'][0]['FORECAST']; // Можно использовать data.MMWEATHER.REPORT[0].TOWN[0].FORECAST
                            result = {};

							result['now'] = {
								DATE:         list[0].$.year + '.' + list[0]['$'].month + '.' + list[0]['$'].day,
								PRESSURE_MIN: list[0].PRESSURE[0].$.min, 
								PRESSURE_MAX: list[0].PRESSURE[0].$.max,
								TEMPERATURE:  (parseFloat(list[0].TEMPERATURE[0].$.max) + parseFloat(list[0].PRESSURE[0].$.min)) / 2, // берем значение в середине
								HUMIDITY:     (parseFloat(list[0].RELWET[0].$.max) + parseFloat(list[0].RELWET[0].$.min)) / 2        // берем значение в середине
							};
							// Ищем значение для 15:00 и возьмем его, как температуру на завтра
                            for (var i = 1; i < list.length; i++) {
								if (list[i].$.hour == "15") {
									result['next'] = {
										DATE:         list[i].$.year + '.' + list[i]['$'].month + '.' + list[i]['$'].day,
										PRESSURE_MIN: list[i].PRESSURE[0].$.min, 
										PRESSURE_MAX: list[i].PRESSURE[0].$.max,
										TEMPERATURE:  (parseFloat(list[i].TEMPERATURE[0].$.max) + parseFloat(list[i].PRESSURE[0].$.min)) / 2, // берем значение в середине
										HUMIDITY:     (parseFloat(list[i].RELWET[0].$.max) + parseFloat(list[i].RELWET[0].$.min)) / 2        // берем значение в середине
									};
									break;
								}
                            }
                        } catch(e) {
                            logger.warn("adapter gismeteo: cannot parse xml answer");
                        }
                        callback(result);
                    } else {
                        logger.warn("adapter gismeteo: cannot parse xml answer - " + err);
                    }
                });
            }
        });
    }).on('error', function(e) {
        logger.warn("adapter gismeteo: Got error by request " + e.message);
    });
}

// опрашивем gismeteo
function pollGismeteo () {
	getXmlResponse(function (data) {
		if (data) {
			// Передать данные для сейчас
			setState(nowChannel_DPs.DATE,         data.now.DATE);
			setState(nowChannel_DPs.PRESSURE_MIN, data.now.PRESSURE_MIN);
			setState(nowChannel_DPs.PRESSURE_MAX, data.now.PRESSURE_MAX);
			setState(nowChannel_DPs.TEMPERATURE,  data.now.TEMPERATURE);
			setState(nowChannel_DPs.HUMIDITY,     data.now.HUMIDITY);
			
			// Передать данные для завтра
			setState(nextChannel_DPs.DATE,         data.next.DATE);
			setState(nextChannel_DPs.PRESSURE_MIN, data.next.PRESSURE_MIN);
			setState(nextChannel_DPs.PRESSURE_MAX, data.next.PRESSURE_MAX);
			setState(nextChannel_DPs.TEMPERATURE,  data.next.TEMPERATURE);
			setState(nextChannel_DPs.HUMIDITY,     data.next.HUMIDITY);		
		}
	});
}

// Инициализируем драйвер
initGismeteo ();
Попытаемся сделать так, что бы при записи переменной DATE значением true, данные бы обновлялись немедленно.
Для этого изменим обработчик событий:

Код: Выделить всё

// Событие от CCU.IO 
socket.on('event', function (obj) {
    if (!obj || !obj[0]) {
        return;
    }
	
	// CCU.IO шлёт массив из 4х переменных [ID, value, timestamp, direction]
	var ID  = obj[0];
	var val = obj[1];
	var ts  = obj[2];
	var dir = obj[3]; // direction true означает, что данные пришли от драйвера, false - данные пришли от GUI, ScriptEngine, или другого адаптера
	
	// Мы не хотим обрабатывать изменения, которые внесли сами
	if (dir) {
		return;
	}
	
	if ((ID == nowChannel_DPs.DATE || ID == nextChannel_DPs.DATE) && val == true) {
		pollGismeteo();
	}	
});
Вот и все. Перезапускаем ccu.io для создания файла настроек для пользователя.
saved_resource.png
saved_resource.png (32.57 КБ) 30437 просмотров
Вызываем http://hostip:8080/ccu.io/
Проверяем, что драйвер запущен:
saved_resource(1).png
saved_resource(1).png (40.08 КБ) 30437 просмотров
И, voila, видим наши значения в дереве объектов:
saved_resource(2).png
saved_resource(2).png (56.56 КБ) 30437 просмотров
Отладка
Можно понатыкать в файле console.log("test") и запустить драйвер из командной строки:
ccu.io> node adapter/gismeteo/gismeteo.js
и посмотреть какие строки появляются.

Ошибки также еще появляются в ccu.io/log/ccu.io.log
Можно использовать WebStorm для отладки. Там есть возможность debugging как это обычно бывает в, например, Visual Studio.

Ну и, конечно, можно спросить здесь.



Файл с драйвером:
gismeteo.zip
(5.29 КБ) 599 скачиваний
P.S. какая-то ошибка с температурой. Надо будет посмотреть завтра... :roll:
EDIT: В строчке

Код: Выделить всё

								TEMPERATURE:  (parseFloat(list[0].TEMPERATURE[0].$.max) + parseFloat(list[0].PRESSURE[0].$.min)) / 2, // берем значение в середине
второе значение тоже должно быть TEMPERATURE, а не PRESSURE.

Urbas81
Сообщения: 313
Зарегистрирован: 28 авг 2012, 14:22

Re: Создание адаптера для CCU.IO

Сообщение Urbas81 » 18 июн 2014, 11:51

Bluefox

А можно пример реализации модуля, который получает значения с устройства ethernet по типу Megad через get запросы и аналогично через эти запросы и управляется, т.е чтоб создать кнопку в интерфейсе и через нее управлять устройством, и аналогично создать график или манометр и боать для него значение из ус-ва. И еще вопрос где почитать про типы переменных, ну и может еще какая информация по модулям, примеры использования.

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

Re: CCU.IO + DashUI

Сообщение Bluefox » 18 июн 2014, 18:22

А можно пример реализации модуля, который получает значения с устройства ethernet по типу Megad через get запросы и аналогично через эти запросы и управляется
Homepilot как раз так и управляется. Только там приемущество, что есть команда "показать все устройства" и можно внести все datapoints в автоматическом режиме. В Меге (наскоро просмотрев доку) такого нет. Но вроде бы там ограниченное число портов и порты имеют постоянные названия/номера. Это хорошо.

Информация для меня:

Существует несколько видов команд:
http://192.168.0.14/sec/?pt=4&cmd=get - считать состояние порта.
http://192.168.0.14/sec/?cmd=2:1 - установить состояние порта.
Непонятно почему в документации написан порт 2. Ведь он должен быть входом?
А также требуется webserver который будет обслуживать события от меги.
Мега посылает информацию в виде:
http://ccu.io:8090/?pt=6
Это значит, выключение порта нельзя отследить? Возможны только сценарии с кнопкой, а с выключателем нельзя. Я прав?

Есть ли люди у которых стоит 2 меги?
Ограничено ли число портов одной меги 14тью или есть модули расширения? Можно ли установить 2 модуля расширения?

Напишу драйвер, но кто то должен его протестить.

И еще вопрос где почитать про типы переменных,
CCU.IO поддерживает все типы переменных, которые поддерживает JavaScript: от number до object
ну и может еще какая информация по модулям, примеры использования.
Как правило, каждый драйвер заточен под конкретный прибор и других применений у него нет. Например, SONOS адаптер: берете SONOS, вбиваете его IP в настройках и всё. Можно управлять...
Такое же можно написать про все адаптеры.
Просто если не знать, что это такое, то и испольовать это, скорей всего не получится. Например есть драйвер geofency. Пользователи Apple его активано используют, что бы выполнять сценарии по появлении или ухода из дома. А у меня аллергия на яблоки ;) и я не знаю как им пользоваться.

Andrey_B
Администратор
Сообщения: 5327
Зарегистрирован: 18 мар 2011, 12:06

Re: CCU.IO + DashUI

Сообщение Andrey_B » 18 июн 2014, 19:02

Bluefox писал(а):http://192.168.0.14/sec/?cmd=2:1 - установить состояние порта.
Непонятно почему в документации написан порт 2. Ведь он должен быть входом?
Исполнительный модуль может быть любым. Например, MegaD-7I7O имеет 7 входов (с 0 по 6) и 7 выходов (с 7 по 13), но ничто не мешает сделать другой исполнительный модуль с 14 выходами.
Bluefox писал(а):Мега посылает информацию в виде:
http://ccu.io:8090/?pt=6
Да, только порт по умолчанию 80. И пока это настраивается только на уровне исходников прошивки.
Bluefox писал(а):Это значит, выключение порта нельзя отследить?
Это что вы имеете ввиду? Сервер в любой момент может запросить состояние порта. Хотя бы сразу же после передачи информации о каком-либо событии.
Bluefox писал(а):Возможны только сценарии с кнопкой, а с выключателем нельзя. Я прав?
У входа есть режим P&R (Press and Release). То есть исполнительный модуль вполне можно использовать как с кнопками, так и с обычными выключателями. Только с последними не очень удобно. Их положение будет произвольным и никак не коррелировать с текущим состоянием управляемого им освещения. Ну примерно так, как это происходит с т.н. "проходными" выключателями.
Bluefox писал(а):Есть ли люди у которых стоит 2 меги?
У меня стоит значительно больше двух.
Bluefox писал(а):Ограничено ли число портов одной меги 14тью или есть модули расширения? Можно ли установить 2 модуля расширения?
Исполнительный модуль - это не модуль расширения. Это как бы вторая часть устройства. То есть два исполнительных модуля к одному контроллеру подключить нельзя. У контроллера только 14 портов.

Urbas81
Сообщения: 313
Зарегистрирован: 28 авг 2012, 14:22

Re: CCU.IO + DashUI

Сообщение Urbas81 » 18 июн 2014, 19:19

Bluefox писал(а):
А можно пример реализации модуля, который получает значения с устройства ethernet по типу Megad через get запросы и аналогично через эти запросы и управляется
Homepilot как раз так и управляется. Только там приемущество, что есть команда "показать все устройства" и можно внести все datapoints в автоматическом режиме. В Меге (наскоро просмотрев доку) такого нет. Но вроде бы там ограниченное число портов и порты имеют постоянные названия/номера. Это хорошо.

Информация для меня:

Существует несколько видов команд:
http://192.168.0.14/sec/?pt=4&cmd=get - считать состояние порта.
http://192.168.0.14/sec/?cmd=2:1 - установить состояние порта.
Непонятно почему в документации написан порт 2. Ведь он должен быть входом?
А также требуется webserver который будет обслуживать события от меги.
Мега посылает информацию в виде:
http://ccu.io:8090/?pt=6
Это значит, выключение порта нельзя отследить? Возможны только сценарии с кнопкой, а с выключателем нельзя. Я прав?

Есть ли люди у которых стоит 2 меги?
Ограничено ли число портов одной меги 14тью или есть модули расширения? Можно ли установить 2 модуля расширения?

Напишу драйвер, но кто то должен его протестить.
Спасибо за ответы, еще меня интересует такая возможность, для другого модуля NetAlarm, там по команде http://IP/stat выводится состояние всех портов строкой
73:0:0:1:791:955:1:0:0:0:0:200:0:1022:1023:1:1:1:0:1 интересует как это периодически запрашивать, парсить и заводить переменные в систему по типу gismeteo?

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

Re: CCU.IO + DashUI

Сообщение Bluefox » 18 июн 2014, 21:58

Urbas81 писал(а): Спасибо за ответы, еще меня интересует такая возможность, для другого модуля NetAlarm, там по команде http://IP/stat выводится состояние всех портов строкой
73:0:0:1:791:955:1:0:0:0:0:200:0:1022:1023:1:1:1:0:1 интересует как это периодически запрашивать, парсить и заводить переменные в систему по типу gismeteo?
Почти. Отличие NetAlarm в том, что модулей может быть больше, чем 1 (как с мегой). А вот gismeteo нет необходимости подключать больше, чем 1 раз.

Я бы подождал MegaD драйвер и на его основе можно сделать NetAlarm драйвер. Они очень похожи.

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

Re: CCU.IO + DashUI

Сообщение Bluefox » 18 июн 2014, 22:13

Andrey_B писал(а):
Bluefox писал(а):Мега посылает информацию в виде:
http://ccu.io:8090/?pt=6
Да, только порт по умолчанию 80. И пока это настраивается только на уровне исходников прошивки.
Я думаю, что здесь не правильно был понят.
Исходя из этой картинки:
megad-scr4-1.jpg
megad-scr4-1.jpg (34.4 КБ) 30261 просмотр
Ничего не мешает мне написать "192.168.0.250:8084/megad.php"
Не будет работать?

Вот вотрая версия драйвера, так сказать, prove of concept:
megaD_v2.zip
(8.65 КБ) 589 скачиваний
Файл надо распаковать в ccu.io/adapter и перестартовать ccu.io. После этого настроить драйвер и перестартовать ccu.io ещё раз.

Может кто-нибудь протестить и прислать ccu.io/log/ccu.io.log ?

Настоящяя версия поддерживает:
- поддержка более, чем одной меги
- настройка для каждого устройства: количество портов и имя
- настройка для каждого порта: вход или выход и имя порта
- конфигурация для каждого input порта: кнопка или переключатель
- конфигурация для каждого output порта: аналоговый или цифровой

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

Re: CCU.IO + DashUI

Сообщение Bluefox » 19 июн 2014, 03:00

Я обновил ссылку в предыдущем посте.

Andrey_B
Администратор
Сообщения: 5327
Зарегистрирован: 18 мар 2011, 12:06

Re: CCU.IO + DashUI

Сообщение Andrey_B » 19 июн 2014, 11:27

Bluefox писал(а):Ничего не мешает мне написать "192.168.0.250:8084/megad.php"
Не будет работать?
Не будет.

shaman1010
Сообщения: 142
Зарегистрирован: 12 ноя 2013, 00:34

Re: Инсталляция

Сообщение shaman1010 » 19 июн 2014, 12:29

Bluefox писал(а):
Инсталляция Debian-пакета (RaspberyPI):
Войти в консоль raspberry под именем "pi" и для инсталляции Node.js и CCU.IO выполнить:

wget http://ccu.io.mainskater.de/nodejs_0.10.22-1_armhf.deb
wget http://ccu.io.mainskater.de/ccu.io_1.0.29.deb
sudo dpkg -i nodejs_0.10.22-1_armhf.deb
sudo dpkg -i ccu.io_1.0.29.deb



Протестированные платформы:
- Synology DS212, DS214play, DS412+, DS413j (vermutlich auf den meisten ARM- und Atom-basierten Synolgy)
Решил-таки опробовать связку на Synology 212-м. Но, как говорится, не случилось.
Может есть какие-то неописанные нюансы при установке на Synology?
Что делал:
1) wget... sudo dpkg....
Пакеты скачало. Поскольку запуск от суперюзера в синолоджи не используется, запустил без sudo... установщик ругается на не-debian пакеты.
2) установил node.js из внутреннего репозитария (версия 0.10) - стала.
3) распаковал ccu.io_1.0.29.deb и раскинул архив в соответствии со вложенной структурой (правда init.d на synology не используется, там init).
Запустилось! Показало версию 1.0.29. Поменял язык на русский, перезапустил ccu.io - перезапустилось, но язык остался английским. Проверил обновления - есть 1.0.38. Нажал "Обновить" - ругнулось. Перезапустил ccu.io. Попробовал обновиться еще раз - обновилось. Послал в перезагрузку - и все...
Последующие попытки запуска - крешатся с glibc detected...
Сносил node.js, ccu.io, ставил по-новой - все-равно креш. Подкидывал папку с 1.0.38 - результат аналогичный. Подкидывал node.js из debian-пакета - не стартует.

Собственно вопрос: как корректно установить связку на синолоджи 212+ ?

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

Re: Инсталляция

Сообщение Bluefox » 19 июн 2014, 16:15

shaman1010 писал(а):
Bluefox писал(а):
Инсталляция Debian-пакета (RaspberyPI):
Войти в консоль raspberry под именем "pi" и для инсталляции Node.js и CCU.IO выполнить:

wget http://ccu.io.mainskater.de/nodejs_0.10.22-1_armhf.deb
wget http://ccu.io.mainskater.de/ccu.io_1.0.29.deb
sudo dpkg -i nodejs_0.10.22-1_armhf.deb
sudo dpkg -i ccu.io_1.0.29.deb



Протестированные платформы:
- Synology DS212, DS214play, DS412+, DS413j (vermutlich auf den meisten ARM- und Atom-basierten Synolgy)
Решил-таки опробовать связку на Synology 212-м. Но, как говорится, не случилось.
Может есть какие-то неописанные нюансы при установке на Synology?
Что делал:
1) wget... sudo dpkg....
Пакеты скачало. Поскольку запуск от суперюзера в синолоджи не используется, запустил без sudo... установщик ругается на не-debian пакеты.
2) установил node.js из внутреннего репозитария (версия 0.10) - стала.
3) распаковал ccu.io_1.0.29.deb и раскинул архив в соответствии со вложенной структурой (правда init.d на synology не используется, там init).
Запустилось! Показало версию 1.0.29. Поменял язык на русский, перезапустил ccu.io - перезапустилось, но язык остался английским. Проверил обновления - есть 1.0.38. Нажал "Обновить" - ругнулось. Перезапустил ccu.io. Попробовал обновиться еще раз - обновилось. Послал в перезагрузку - и все...
Последующие попытки запуска - крешатся с glibc detected...
Сносил node.js, ccu.io, ставил по-новой - все-равно креш. Подкидывал папку с 1.0.38 - результат аналогичный. Подкидывал node.js из debian-пакета - не стартует.

Собственно вопрос: как корректно установить связку на синолоджи 212+ ?
Проблема в бинарнике node.js.
Можешь попробовать скомпилировать бинарник сам?

http://blog.tatablack.net/it/2012/10/13 ... ogy-ds212/

Bluefox
Сообщения: 150
Зарегистрирован: 03 мар 2014, 20:02

Re: Инсталляция

Сообщение Bluefox » 19 июн 2014, 17:14

shaman1010 писал(а): Собственно вопрос: как корректно установить связку на синолоджи 212+ ?
Можно попробовать вот такой бинарник: https://github.com/stryke76/nodejs/raw/ ... _armhf.deb

Необходимо убедиться, что все файлы в ccu.io имеют права 777 и принадлежат тому пользователю.

shaman1010
Сообщения: 142
Зарегистрирован: 12 ноя 2013, 00:34

Re: Инсталляция

Сообщение shaman1010 » 19 июн 2014, 18:26

Bluefox писал(а):Можно попробовать вот такой бинарник: https://github.com/stryke76/nodejs/raw/ ... _armhf.deb
Необходимо убедиться, что все файлы в ccu.io имеют права 777 и принадлежат тому пользователю.
Если dpkg, то:
debsig: nodejs_0.10.20-1_armhf.deb does not appear to be a deb format package
dpkg: error processing nodejs_0.10.20-1_armhf.deb (--install):
verification on package nodejs_0.10.20-1_armhf.deb failed!

Но в нем ли дело? 0.10.чтото - ставится из репозитария, а потом при запуске ccu.io уже какие-то непонятки выходят. Похоже при запуске самого сервера, что-то нарушается, хотелось бы знать что...
Есть же кто-то, кто подтвердил работоспособность на 212-м (как было тобой написано выше). Может к нему обратиться? Или это все в теории, основываясь на попытках установить node.js еще с 12-го года? (та статья, ссылка на которую ты дал). Кстати, там ссылка на гитхаб, где лежит свежий node.js

Ответить