С момента моего первого сообщения в этой теме прошло уже некоторое время. И я путем проб и ошибок уже несколько раз переделывал взаимодействие с моими ключами 1-wire и пришел к некоторым выводам и алгоритмам работы которые вот уже месяца 2 наверно успешно работают и решили многие мои проблемы, а т.к. я хотел бы поделиться со всеми этим своим решением, то хотел бы выложить его сюда.
Прошу спецам меня не ругать, я очень любитель и не программист совсем, но думаю это может принести пользу другим и возможно, кто-то сможет поправить, что-то в моём решении и оно станет лучше.
Дак вот дано:
Модуль (1-wire) управления освещением -
http://radioseti.ru/index.php?route=pro ... uct_id=138

- 1к 1л принципиальная-500x500.JPG (18.87 КБ) 11589 просмотров
Его особенности:
Модуль управления освещением. Предназначен для управления освещением со стандартного выключателя, а также независимого управления по 1-wire. Управление освещением производится не зависимо есть ли, или нет связи с компьютером, а также есть возможность управлять по 1-wire. Так же пользователь может контролировать включена или выключена нагрузка (лампа). Мощность нагрузки 150 Вт.
Логика его работы:
переключение клавиши выключателя - включение лампы или выключение лампы (в зависимости от состояния до)
1-канал DS2406 ( точнее нужен "PIO.A") - управление по 1-wire, фронт 0 -> 1 (сначала 0 потом 1) переключает состояние на противоположное
2-канал DS2406 (точнее нужен "sensed.B") - контроль наличия напряжения на лампе
Т.е. "sensed.B" - только отображает состояние и работает только "в одну сторону" - значение привязанного свойства нужно только читать и никак не писать в него!!!
Мои выстраданные решения:
1) Создал класс "Light"

- Скриншот 2015-04-07 13.43.37.png (10.56 КБ) 11589 просмотров
2) В классе (именно в классе) создал методы:
refresh - обновление состояния, т.е. если включен то не выключать и наоборот
statusChanged - вызываем при изменении статуса и меняем свойства жизни объекта
switch - переключить состояние на противоположное
turnOff - выключить с проверкой (если не было уже выключено)
turnOn - включаем с проверкой
3) В классе создал свойства:
Название Описание
alive - живой?
aliveTimeOut - время жизни
status - состояние освещения привязанное к 1-wire
status1 - состояние освещения привязанное к меню
statusText - состояние словами
statusWhoTurn - кто включил(или выключил), программа (1) или физический выключатель (2)
trigOnOff - триггер управления освещением 0 -> 1
updatedTimestamp - время последнего изменения
НЕ забываем в настройках свойства
status поставить "
Запускать метод при изменении"

- Скриншот 2015-04-07 14.13.41.png (14.57 КБ) 11589 просмотров
4) В
Меню управления создал для каждого такой пункт(на примере одного)
особенность - привязано к меню именно свойство
status1

- Скриншот 2015-04-07 13.08.41.png (31.62 КБ) 11589 просмотров
5) Привязка 1-wire

- Скриншот 2015-04-07 15.01.09.png (56.89 КБ) 11589 просмотров
Код методов:
метод (самый важный)
statusChanged
Код: Выделить всё
if ($params['NEW_VALUE']==$params['OLD_VALUE']) return;
$status = $this->getProperty('status');
if (!$status) {
$status=0;
}
// определение настройки по проговариванию и логу
$saylights = gg('Sets.saylights');
// узнаем прежнее состояние
$statusOld = $this->getProperty('statusOld');
if (!$statusOld) {
$statusOld=0;
}
$this->setProperty('updatedTimestamp',time());
$this->setProperty('alive',1);
$ot=$this->object_title;
// проверка заданно ли время жизни для ключа
$alive_timeout=(int)$this->getProperty('aliveTimeOut');
if (!$alive_timeout) {
$alive_timeout=8*60*60; // если не было заданно, то берем 8 часов
}
if ($status) {
$this->setProperty('statusText', "включен");
}
else {
$this->setProperty('statusText', "выключен");
}
if ($saylights) {
say("Свет. ".str_replace("_"," ",$ot)." ".$this->getProperty('statusText'),($saylights-2));
}
clearTimeOut($ot."_alive");
setTimeOut($ot."_alive","sg('".$ot.".alive',0);",$alive_timeout);
$this->setProperty('statusOld',$status);
if (($this->getProperty("status"))<>($this->getProperty("status1"))) {
$this->setProperty("statusWhoTurn",2);
//say ("Переключили выключателем на стене");
}
$this->setProperty('status1',$status);
// считаем количество всего включенных модулей света
$objects=getObjectsByClass("Light");
$all_lights_off=0;
foreach($objects as $obj) {
$all_lights_off = gg($obj['TITLE'].".status") + $all_lights_off;
}
sg ("Sets.all_lights_off",$all_lights_off);
метод
turnOff
Код: Выделить всё
$status_in=$this->getProperty("status");
$ot1=$this->object_title;
// определение настройки по проговариванию и логу
$saylights = gg('Sets.saylights');
if ($status_in) {
// было включено - выключаем
// переключение по фронту 0 -> 1
// при этом пытаемся это сделать до 7 раз с проверкой изменения статуса
for ($k = 1; $k <= 7; $k++) {
if (($this->getProperty("status"))==$status_in) {
$this->setProperty("trigOnOff",0);
$this->setProperty("trigOnOff",1);
//say ("-> ".$k);
}
}
}
else {
if ($saylights) {
say("Свет. ".str_replace("_"," ",$ot1)." уже был выключен.",($saylights-2));
}
//say ("Уже было выключено");
}
метод
turnOn - (по сути "зеркален" методу
turnOFF)
Код: Выделить всё
$status_in=$this->getProperty("status");
if (!$status_in) {
// было вЫключено - включаем
// переключение по фронту 0 -> 1
// при этом пытаемся это сделать до 5 раз с проверкой изменения статуса
for ($k = 1; $k <= 5; $k++) {
if (($this->getProperty("status"))==$status_in) {
$this->setProperty("trigOnOff",0);
$this->setProperty("trigOnOff",1);
//say ("-> ".$k);
}
}
}
else {
//say ("Уже было включено");
}
метод
switch
Код: Выделить всё
$status_in=$this->getProperty("status");
$ot1=$this->object_title;
// определение настройки по проговариванию и логу
$saylights = gg('Sets.saylights');
// переключение по фронту 0 -> 1
// при этом пытаемся это сделать до 10 раз с проверкой изменения статуса
for ($k = 1; $k <= 10; $k++) {
if (($this->getProperty("status"))==$status_in) {
$this->setProperty("trigOnOff",0);
$this->setProperty("trigOnOff",1);
}
}
if (($this->getProperty("status"))<>$status_in) {
$this->setProperty("statusWhoTurn",1);
}
else {
if ($saylights) {
say("Изменить состояние освещения ".str_replace("_"," ",$ot1)." не удалось! Возможно неисправность модуля 1-wire.",($saylights-2));
}
}
Некоторые пояснения:
Решение: Я ушел от первоначального варианта, когда ползунок выключателя был привязан к свойству
status (которое в свою очередь связанно с
sensed.B ключа 1-wire) напрямую
Результат: так называемые нотисы прекратились, т.к. включение ползунка не меняет теперь
sensed.B самостоятельно, что как раз делать было нельзя (этот параметр ключа может быть только Read)!
Решение: Методы
turnOn,
turnOff и
switch несколько раз (жестко) пытаются выдать фронт 0->1 в привязанное к
PIO.A модуля 1-wire, свойство
trigOnOff при чем с проверкой реакции модуля 1-wire.
Результат: При плохой сети 1-wire модули отваливаются и появляются в сети периодически и такой "финт ушами" позволил мне привести надежность программного включения/выключения света к 99%! (возможно заменю цикл FOR на цикл WHILE)
При включение света выключателем на стене в модуле меняется значение
sensed.B, что приводит к изменению свойства
status, что в свою очередь приводит к запуску метода
statusChanged!
выбранный вариант решения также оставляет метку - кто (вернее наверно что) вкл/выкл конкретную лампочку крайний раз - выключатель на стене или программа (может в дальнейшем это получиться как-то использовать).