Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Adav

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    A
    • Profile
    • Following 0
    • Followers 0
    • Topics 5
    • Posts 67
    • Best 0
    • Groups 0

    Adav

    @Adav

    0
    Reputation
    37
    Profile views
    67
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Adav Follow

    Latest posts made by Adav

    • RE: Скрипт многотарифного подсчёта эл.энергии

      > Как получить общее число киловатт за месяц из этого скрипта?
      Зачем? Счетчик как раз и дает общее число киловатт - сохраняйте его показание в базе и обрабатывайте. Я это делаю через grafana - вижу график общего потребления по месяцам. Скрипт же заточен под распределение этого показателя по тарифам. Возможно Вы хотите что-то иное…

      Я скрипт немного расширил, посмотрите, может что-то полезное будет.

      //---------------------------------Счетчик-----------------------------
      createState("javascript.0.Values.Energy_total", 0,{name: "Потребление электроэнергии", unit: "кВт⋅ч", type: "number"});
      createState("javascript.0.Energy.Night", 0,{name: "Потребление электроэнергии тариф ночь", unit: "кВт⋅ч", type: "number"});
      createState("javascript.0.Energy.Peak", 0,{name: "Потребление электроэнергии тариф пик", unit: "кВт⋅ч", type: "number"});
      createState("javascript.0.Energy.Half_peak", 0,{name: "Потребление электроэнергии тариф полупик", unit: "кВт⋅ч", type: "number"});
      
      createState("javascript.0.Energy.M_night", 0,{name: "Тариф ночь в текущем месяце", unit: "кВт⋅ч", type: "number"});
      createState("javascript.0.Energy.M_рeak", 0,{name: "Тариф пик в текущем месяце", unit: "кВт⋅ч", type: "number"});
      createState("javascript.0.Energy.M_half_peak", 0,{name: "Тариф полупик в текущем месяце", unit: "кВт⋅ч", type: "number"});
      createState("javascript.0.Energy.M_money", 0,{name: "Стоимость в текущем месяце", unit: "руб", type: "number"});
      createState("javascript.0.Energy.Mlast_money", 0,{name: "Стоимость в предыдущем месяце", unit: "руб", type: "number"});
      
      var total = "javascript.0.Values.Energy_total";
      var night = "javascript.0.Energy.Night";
      var peak = "javascript.0.Energy.Peak";
      var h_peak = "javascript.0.Energy.Half_peak";
      var delta;
      var kt;
      var money;
      
      on({id: "modbus.3.inputRegisters.11.342_total_active_energy", change: "ne"}, function (obj) {
          if(getState(total).val === 0){
             setState(total, obj.state.val, true); 
          }  
          delta = obj.state.val - getState(total).val;                                //разница двух показаний счетчика
          if(compareTime("6:00", "9:00", "between")){                                 //сдвиг на час назад от принятого
             if(compareTime(new Date(getState(total).lc).toLocaleTimeString(), new Date().toLocaleTimeString(), "between", "6:00") && delta > 0.011){ 
                kt = (new Date().setHours(6,0,0,0) - getState(total).lc)/(Date.parse(new Date()) - getState(total).lc);
                setState(night, Math.round(100 * (getState(night).val + kt * delta))/100, true); 
                setState(peak, Math.round(100 * (getState(peak).val + (1 - kt) * delta))/100, true); 
                sendTo('telegram.0', 'Произошел сбой счетчика ЭЭ. Желательно скорректировать значения ночного и пикового тарифов.');
             } else {
                setState(peak, Math.round(100 * (getState(peak).val + delta))/100, true); 
             }    
          }   
          if(compareTime("9:00", "16:00", "between")){ 
             if(compareTime(new Date(getState(total).lc).toLocaleTimeString(), new Date().toLocaleTimeString(), "between", "9:00") && delta > 0.011){ 
                kt = (new Date().setHours(9,0,0,0) - getState(total).lc)/(Date.parse(new Date()) - getState(total).lc);
                setState(peak, Math.round(100 * (getState(peak).val + kt * delta))/100, true); 
                setState(h_peak, Math.round(100 * (getState(h_peak).val + (1 - kt) * delta))/100, true); 
                sendTo('telegram.0', 'Произошел сбой счетчика ЭЭ. Желательно скорректировать значения пикового и полупикового тарифов.');
             } else {
                setState(h_peak, Math.round(100 * (getState(h_peak).val + delta))/100, true); 
             }
          }    
          if(compareTime("16:00", "20:00", "between")){ 
             if(compareTime(new Date(getState(total).lc).toLocaleTimeString(), new Date().toLocaleTimeString(), "between", "16:00") && delta > 0.011){ 
                kt = (new Date().setHours(16,0,0,0) - getState(total).lc)/(Date.parse(new Date()) - getState(total).lc);
                setState(h_peak, Math.round(100 * (getState(h_peak).val + kt * delta))/100, true); 
                setState(peak, Math.round(100 * (getState(peak).val + (1 - kt) * delta))/100, true); 
                sendTo('telegram.0', 'Произошел сбой счетчика ЭЭ. Желательно скорректировать значения полупикового и пикового тарифов.');
             } else {
                setState(peak, Math.round(100 * (getState(peak).val + delta))/100, true); 
             }
          }   
          if(compareTime("20:00", "22:00", "between")){ 
             if(compareTime(new Date(getState(total).lc).toLocaleTimeString(), new Date().toLocaleTimeString(), "between", "20:00") && delta > 0.011){ 
                kt = (new Date().setHours(20,0,0,0) - getState(total).lc)/(Date.parse(new Date()) - getState(total).lc);
                setState(peak, Math.round(100 * (getState(peak).val + kt * delta))/100, true); 
                setState(h_peak, Math.round(100 * (getState(h_peak).val + (1 - kt) * delta))/100, true); 
                sendTo('telegram.0', 'Произошел сбой счетчика ЭЭ. Желательно скорректировать значения пикового и полупикового тарифов.');
             } else {
                setState(h_peak, Math.round(100 * (getState(h_peak).val + delta))/100, true); 
             }
          }   
          if(compareTime("22:00", "6:00", "between")){ 
             if(compareTime(new Date(getState(total).lc).toLocaleTimeString(), new Date().toLocaleTimeString(), "between", "22:00") && delta > 0.011){ 
                kt = (new Date().setHours(22,0,0,0) - getState(total).lc)/(Date.parse(new Date()) - getState(total).lc);
                setState(h_peak, Math.round(100 * (getState(h_peak).val + kt * delta))/100, true); 
                setState(night, Math.round(100 * (getState(night).val + (1 - kt) * delta))/100, true); 
                sendTo('telegram.0', 'Произошел сбой счетчика ЭЭ. Желательно скорректировать значения полупикового и ночного тарифов.');
             } else {
                setState(night, Math.round(100 * (getState(night).val + delta))/100, true); 
             }
          }   
      
          setState(total, obj.state.val, true);
      //------------------
          if(getState("javascript.0.Energy.M_night").val === 0){
             setState("javascript.0.Energy.M_night", getState(night).val, true); 
          } 
          if(getState("javascript.0.Energy.M_рeak").val === 0){
             setState("javascript.0.Energy.M_рeak", getState(peak).val, true); 
          }      
          if(getState("javascript.0.Energy.M_half_peak").val === 0){
             setState("javascript.0.Energy.M_half_peak", getState(h_peak).val, true);     
          }      
      
          money = 1.92*(getState(night).val - getState("javascript.0.Energy.M_night").val) + 6.46*(getState(peak).val - getState("javascript.0.Energy.M_рeak").val) + 5.38*(getState(h_peak).val - getState("javascript.0.Energy.M_half_peak").val);
          setState("javascript.0.Energy.M_money", Math.round(money), true);    
      });
      
      schedule({date : 1, hour: 0, minute: 0}, function () {
          setState("javascript.0.Energy.Mlast_money", getState("javascript.0.Energy.M_money").val, true);
          setState("javascript.0.Energy.M_night", getState(night).val, true); 
          setState("javascript.0.Energy.M_рeak", getState(peak).val, true);
          setState("javascript.0.Energy.M_half_peak", getState(h_peak).val, true);
      });    
      
      
      posted in ioBroker скрипты
      A
      Adav
    • RE: Sql.0 не сохраняются данные

      Ровно то же самое с драйвером influxdb. Выше писал. Поэтому и использую до сих пор совсем старую версию, где такой проблемы не было. Вероятно и sql будет нормально работать на старой версии. Issue оставлял на гитхабе, результат нулевой. И провалы начинаются уже с 2 секунд и чем больше значение - тем более вероятно, что значение не сохранится.

      posted in ioBroker ошибки
      A
      Adav
    • RE: Скрипт многотарифного подсчёта эл.энергии

      Возникла такая же задача. Написал скрипт, который выдает в реальном времени тарифные значения. Без проблем отрабатывает сбои внутри тарифного интервала. В случае сбоя на границе тарифа - сделана аппроксимация с распределением потребленной за время сбоя энергии между соседними тарифами пропорционально времени сбоя до/после времени переключения тарифа. По возможности оттестировано, но возможны ньюансы… время тарификации у меня свое - особенности настройки счетчика энергосбыта.

      createState("javascript.0.Values.Energy_total", 0,{name: "Потребление электроэнергии", unit: "кВт⋅ч", type: "number"});
      
      createState("javascript.0.Energy.Night", 0,{name: "Потребление электроэнергии тариф ночь", unit: "кВт⋅ч", type: "number"});
      createState("javascript.0.Energy.Peak", 0,{name: "Потребление электроэнергии тариф пик", unit: "кВт⋅ч", type: "number"});
      createState("javascript.0.Energy.Half_peak", 0,{name: "Потребление электроэнергии тариф полупик", unit: "кВт⋅ч", type: "number"});
      
      var kt;
      var total = "javascript.0.Values.Energy_total";
      var night = "javascript.0.Energy.Night";
      var peak = "javascript.0.Energy.Peak";
      var h_peak = "javascript.0.Energy.Half_peak";
      
      on({id: "modbus.3.inputRegisters.11.342_total_active_energy", change: "ne"}, function (obj) {
          if(getState(total).val === 0){
             setState(total, obj.state.val, true); 
          }  
          if(compareTime("6:00", "9:00", "between")){                                 //сдвиг на час назад от принятого
             if(compareTime(new Date(getState(total).lc).toLocaleTimeString(), new Date().toLocaleTimeString(), "between", "6:00") && obj.state.val - getState(total).val > 0.011){ 
                kt = (new Date().setHours(6,0,0,0) - getState(total).lc)/(Date.parse(new Date()) - getState(total).lc);
                setState(night, Math.round(100 * (getState(night).val + kt * (obj.state.val - getState(total).val)))/100, true); 
                setState(peak, Math.round(100 * (getState(peak).val + (1 - kt) * (obj.state.val - getState(total).val)))/100, true); 
                sendTo('telegram.0', 'Произошел сбой счетчика ЭЭ. Желательно скорректировать значения ночного и пикового тарифов.');
             } else {
                setState(peak, Math.round(100 * (getState(peak).val + obj.state.val - getState(total).val))/100, true); 
             }    
          }   
          if(compareTime("9:00", "16:00", "between")){ 
             if(compareTime(new Date(getState(total).lc).toLocaleTimeString(), new Date().toLocaleTimeString(), "between", "9:00") && obj.state.val - getState(total).val > 0.011){ 
                kt = (new Date().setHours(9,0,0,0) - getState(total).lc)/(Date.parse(new Date()) - getState(total).lc);
                setState(peak, Math.round(100 * (getState(peak).val + kt * (obj.state.val - getState(total).val)))/100, true); 
                setState(h_peak, Math.round(100 * (getState(h_peak).val + (1 - kt) * (obj.state.val - getState(total).val)))/100, true); 
                sendTo('telegram.0', 'Произошел сбой счетчика ЭЭ. Желательно скорректировать значения пикового и полупикового тарифов.');
             } else {
                setState(h_peak, Math.round(100 * (getState(h_peak).val + obj.state.val - getState(total).val))/100, true); 
             }
          }    
          if(compareTime("16:00", "20:00", "between")){ 
             if(compareTime(new Date(getState(total).lc).toLocaleTimeString(), new Date().toLocaleTimeString(), "between", "16:00") && obj.state.val - getState(total).val > 0.011){ 
                kt = (new Date().setHours(16,0,0,0) - getState(total).lc)/(Date.parse(new Date()) - getState(total).lc);
                setState(h_peak, Math.round(100 * (getState(h_peak).val + kt * (obj.state.val - getState(total).val)))/100, true); 
                setState(peak, Math.round(100 * (getState(peak).val + (1 - kt) * (obj.state.val - getState(total).val)))/100, true); 
                sendTo('telegram.0', 'Произошел сбой счетчика ЭЭ. Желательно скорректировать значения полупикового и пикового тарифов.');
             } else {
                setState(peak, Math.round(100 * (getState(peak).val + obj.state.val - getState(total).val))/100, true); 
             }
          }   
          if(compareTime("20:00", "22:00", "between")){ 
             if(compareTime(new Date(getState(total).lc).toLocaleTimeString(), new Date().toLocaleTimeString(), "between", "20:00") && obj.state.val - getState(total).val > 0.011){ 
                kt = (new Date().setHours(20,0,0,0) - getState(total).lc)/(Date.parse(new Date()) - getState(total).lc);
                setState(peak, Math.round(100 * (getState(peak).val + kt * (obj.state.val - getState(total).val)))/100, true); 
                setState(h_peak, Math.round(100 * (getState(h_peak).val + (1 - kt) * (obj.state.val - getState(total).val)))/100, true); 
                sendTo('telegram.0', 'Произошел сбой счетчика ЭЭ. Желательно скорректировать значения пикового и полупикового тарифов.');
             } else {
                setState(h_peak, Math.round(100 * (getState(h_peak).val + obj.state.val - getState(total).val))/100, true); 
             }
          }   
          if(compareTime("22:00", "6:00", "between")){ 
             if(compareTime(new Date(getState(total).lc).toLocaleTimeString(), new Date().toLocaleTimeString(), "between", "22:00") && obj.state.val - getState(total).val > 0.011){ 
                kt = (new Date().setHours(22,0,0,0) - getState(total).lc)/(Date.parse(new Date()) - getState(total).lc);
                setState(h_peak, Math.round(100 * (getState(h_peak).val + kt * (obj.state.val - getState(total).val)))/100, true); 
                setState(night, Math.round(100 * (getState(night).val + (1 - kt) * (obj.state.val - getState(total).val)))/100, true); 
                sendTo('telegram.0', 'Произошел сбой счетчика ЭЭ. Желательно скорректировать значения полупикового и ночного тарифов.');
             } else {
                setState(night, Math.round(100 * (getState(night).val + obj.state.val - getState(total).val))/100, true); 
             }
          }   
      
          setState(total, obj.state.val, true);
      });
      
      
      posted in ioBroker скрипты
      A
      Adav
    • RE: Драйвер ModBus

      @Sergey777:

      Почему Modbus Постоянно отваливается? `

      Я так и не смог добиться стабильной работы если на одной шине 485 больше одного устройства. Причем в разных вариантах - и на USB-485, и на COM-сервере Ethernet-485. Вероятнее всего причина в том, что разные драйвера для разных устройств ничего не знают друг о друге и шлют запросы на одну шину случайным образом, создавая конфликты. Странно что у Вас те же проблемы и с одним устройством, я пробовал подключать такой же счетчик, работало нормально.

      Ну и попробуйте разные параметры настройки драйвера. К примеру, одно из устройств стабильно у меня работает с таймаутом чтения 0. Другие же при 1000…

      posted in ioBroker драйвера
      A
      Adav
    • RE: Sql.0 не сохраняются данные

      @Bluefox:

      Если есть проблемы, то я очень советую создать issue на github (причём на английском)

      modbus - да я его писал. Но железа у меня нет и я пользуюсь симуляторами.

      sql - Apollon не понимает по русски и именно он поддерживает sql/influx/history

      Я не в состоянии прочитать и ответить на 50 сообщений в день в форуме. А ещё есть telegram, whatsapp, email, facebook, github, trello.

      И потом у меня работа и двое детей с женой в придачу, а ведь надо фиксить баги и добавлять новые фичи, поддерживать сайт и 2 облака, а то все пользователи разбегутся 🙂 `

      Не воспринимайте это как претензию. Скорее как отдельные выявленные недостатки. Но даже с ними система работает очень неплохо. Шустро и стабильно. Нет никакого желания искать что-то другое. Про issue я понял. Как руки дойдут - воспользуюсь. Прямо сейчас не получится - надо вспоминать подробности. К тому же уже и так приладился…

      Вообщем-то на старой версии influx прекрасно работает, и действительно эта проблема возникла после обновлений от Apollon.

      С modbus эмулятором наверное можно попробовать повторить ошибку с дискретными регистрами. Попробуйте дискретные входы (или выходы) задать на эмуляторе не подряд. Скажем, адреса регистров 0,1,3,4,5,6,7,8,10 и попробовать такое считать. Понимаю, такой "бардак" с адресацией не типичен, но вот мне досталось именно такое устройство. Такое происходит только с дискретными, с input или c holding такой проблемы нет. С несколькими устройствами на шине 485, как я понимаю, с эмулятором не получится повторить. В меру моего разумения, проблема в том, что нет очереди при использовании разных драйверов на опрос разных устройств на одной 485 шине с разными ID. Вот и возникает конфликт при опросе.

      posted in ioBroker ошибки
      A
      Adav
    • RE: Sql.0 не сохраняются данные

      @select2:

      Adav, с версией драйвера sql 1.3.4. у вас работает без этих проблем, я правильно понял?

      C драйвером modbus я помучился при настройке, но в работе он показал себя неплохо. Вопросов к modbus нет. `

      Я использую influxdb, со старой версией работает не только на секунде. Гляньте ветку по influxdb - я там подробно описал. A sql я пробовал чисто ради интереса последнюю - с ней та же беда, старую не проверял. Подозреваю, что тут будет все то же самое. Очень похоже, что сделали какое-то новшество во всех этих драйверах одновременно. С modbus у меня есть пара проблем - есть девайс, где дискретные входы идут не подряд, с пропусками - там ошибки всегда (как я понял, драйвер по-любому считывает сразу 8), несколько устройств на одной шине не работают (точнее работают, но постоянно конфликтуют с ошибками в логах). Ни при прямом подключении на USB-485, ни через 485-Ethernet конвертер. А вообще у меня modbus устройств немало, но вот такое неудобство… Сначала хотел перенести опрос напрямую с iobroker, но после такой фигни оставил почти все как было (за исключением нескольких устройств) - опрос modbus через WB5 и уже с него на iobroker через mqtt. Это касается 485. Есть устройство с TCP modbs - тут все нормально. Но оно типовое (универсальные входы-выходы) и негде ему конфликтовать на одной 485 шине.

      posted in ioBroker ошибки
      A
      Adav
    • RE: Sql.0 не сохраняются данные

      @select2:

      Попутно подобрал параметры для классического варианта:

      Минимальный интервал 1000 `

      Я еще летом в теме по influxdb писал про ту же проблему. Можете посмотреть. И тоже путем подбора пришел к тому, что стабильная работа идет только при секундной или меньше записи. Причем со старой версией драйвера такой проблемы нет. Поэтому и не обновляю, оставаясь на 1.3.4. Пробовал и sql с postgresql - все то же самое. Разработчики большого интереса к проблеме не проявили. Странно, что проблема не массовая, возможно люди не заморачиваются объемом хранения и оставляют секунду по умолчанию. Модбас тут совершенно ни при чем, поскольку у меня данные для базы берутся не только оттуда с теми же проблемами. Хотя и к драйверу модбаса тоже у меня немало претензий и тоже никакого интереса у разработчиков.

      posted in ioBroker ошибки
      A
      Adav
    • RE: Вопросы по написанию скриптов

      Вернулся к вопросу с рестартом сервиса nut (о чем выше). Спасибо spectrekr и instalator за два варианта решения проблемы. Но я нашел третий вариант, на мой взгляд проще. Отслеживается одна из переменных (в принципе любая, но лучше константа), приходящих от драйвера nut, и если она не обновлялась дольше, чем два цикла опроса (в моем случае цикл 5 сек), то идет команда на рестарт сервиса на удаленном сервере. Вроде работает… В скрипте это так (может кому пригодится):

      //---------------------------Restart nut------------------
      var nut_timer_timeout_ms = 12 * 1000;
      var nut_timer_id = null;
      
      on({id: "nut.0.input.transfer-low", change: "eq"}, function (obj) { 
      if (nut_timer_id) {
          clearTimeout(nut_timer_id);
                        }
          nut_timer_id = setTimeout(function () {
             exec('ssh root@192.168.118.115 service nut-driver restart');       
             sendTo('telegram.0', {
                text:'Сервис NUT на сервере System завис и перезагружен.',
                disable_notification:   true
          });          
          nut_timer_id = null;   
         	}, nut_timer_timeout_ms);      
      });
      
      posted in ioBroker скрипты
      A
      Adav
    • RE: Вопросы по написанию скриптов

      @instalator:

      @spectrekr:

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

      Это было бы идеально, но тут вопрос к разработчику… Как вариант - отслеживать состояние сервиса непосредственно на удаленной машине bash скриптом, но тут я тоже не тяну сделать самостоятельно. По идее можно делать запрос upsc и если нет данных - перегружать сервис.

      posted in ioBroker скрипты
      A
      Adav
    • RE: Вопросы по написанию скриптов

      @spectrekr:

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

      Как это сделать? Есть примеры? С действием тоже вопрос - через exec надо отправить команду на удаленную машину (со своим паролем и логином), а не выполнять локально.

      posted in ioBroker скрипты
      A
      Adav
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo