Size: a a a

ioBroker smarthome

2020 July 01

PM

Pavel Mironov in ioBroker smarthome
Попробовал через startscript, stopscript - не работает.
источник

H

Haba in ioBroker smarthome
Pavel Mironov
Попробовал через startscript, stopscript - не работает.
Тут хз, сам не пробовал
источник

PM

Pavel Mironov in ioBroker smarthome
Скрипты, как я понял должны запускаться и останавливаться отсюда. У меня этого не происходит. При изменении значения оно зеленеет и потом становится коричневым. Причем если выключашь скрипт в закладке "скрипты" тут состояние меняется. Какая-то односторонняя связь.
источник

PM

Pavel Mironov in ioBroker smarthome
Такое впечатление, что там вкючено только read-only.
источник

PM

Pavel Mironov in ioBroker smarthome
Бл...ть. В настройках javascript стояла галка на пункте "Оптимизация состояний". Она все блокировала.
источник

В

Вадим in ioBroker smarthome
Pavel Mironov
Еще ничего не делал. Только домой вошел.
Так и победил?
источник

PM

Pavel Mironov in ioBroker smarthome
Вадим
Так и победил?
Теперь да.
источник

РД

Радченко Денис... in ioBroker smarthome
Pavel Mironov
Теперь да.
оо спасибо  ценная находка ) как догадался тольк
источник

PM

Pavel Mironov in ioBroker smarthome
Радченко Денис
оо спасибо  ценная находка ) как догадался тольк
Через ошибки в скриптах, которые раньше работали, а сейчас почему-то перестали. Была такая: Please disable that setting or use "getState" with a callback в скрипте.
источник

PM

Pavel Mironov in ioBroker smarthome
У меня вот телеграмное меню сломалось. Не понимаю почему не активируется
источник

SR

Sergey Romanov in ioBroker smarthome
Pavel Mironov
У меня вот телеграмное меню сломалось. Не понимаю почему не активируется
отправь меню еще раз в телегу? перезапусти скрипт?
источник

PM

Pavel Mironov in ioBroker smarthome
Sergey Romanov
отправь меню еще раз в телегу? перезапусти скрипт?
да уже много раз попробовал. Скрипт раньше работал. Потом как-то попробовал - не работает. Так и не могу победить. В промежутке между этим переставлял iobroker. Возможно с этим как-то связано
источник

SR

Sergey Romanov in ioBroker smarthome
ну без скрипта тут не поймешь..
источник

PM

Pavel Mironov in ioBroker smarthome
Sergey Romanov
ну без скрипта тут не поймешь..
unifi.0
2020-07-01 23:16:20.595
info
(22082) Update done
javascript.0
2020-07-01 23:16:12.854
info
(21082) script.js.Scripts.Telegram_menu: i=2, i1=2, i2=2
javascript.0
2020-07-01 23:16:12.853
info
(21082) script.js.Scripts.Telegram_menu: i=2, i1=1, i2=2
javascript.0
2020-07-01 23:16:12.852
info
(21082) script.js.Scripts.Telegram_menu: i=2, i1=0, i2=2
javascript.0
2020-07-01 23:16:12.851
info
(21082) script.js.Scripts.Telegram_menu: i=2, i1=3, i2=2
javascript.0
2020-07-01 23:16:12.849
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=2, i2=1
javascript.0
2020-07-01 23:16:12.848
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=2, i2=0
javascript.0
2020-07-01 23:16:12.847
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=2, i2=6
javascript.0
2020-07-01 23:16:12.846
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=1, i2=5
javascript.0
2020-07-01 23:16:12.845
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=1, i2=4
javascript.0
2020-07-01 23:16:12.844
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=1, i2=3
javascript.0
2020-07-01 23:16:12.843
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=1, i2=2
javascript.0
2020-07-01 23:16:12.842
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=1, i2=1
javascript.0
2020-07-01 23:16:12.841
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=1, i2=0
javascript.0
2020-07-01 23:16:12.839
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=1, i2=6
javascript.0
2020-07-01 23:16:12.838
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=0, i2=5
javascript.0
2020-07-01 23:16:12.837
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=0, i2=4
javascript.0
2020-07-01 23:16:12.836
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=0, i2=3
javascript.0
2020-07-01 23:16:12.831
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=0, i2=2
javascript.0
2020-07-01 23:16:12.830
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=0, i2=1
javascript.0
2020-07-01 23:16:12.829
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=0, i2=0
javascript.0
2020-07-01 23:16:12.827
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=0, i2=undefined
javascript.0
2020-07-01 23:16:12.825
info
(21082) script.js.Scripts.Telegram_menu: i=1, i1=6, i2=undefined
javascript.0
2020-07-01 23:16:12.824
info
(21082) script.js.Scripts.Telegram_menu: i=0, i1=5, i2=undefined
javascript.0
2020-07-01 23:16:12.822
info
(21082) script.js.Scripts.Telegram_menu: i=0, i1=4, i2=undefined
javascript.0
2020-07-01 23:16:12.821
info
(21082) script.js.Scripts.Telegram_menu: i=0, i1=3, i2=undefined
javascript.0
2020-07-01 23:16:12.820
info
(21082) script.js.Scripts.Telegram_menu: i=0, i1=2, i2=undefined
javascript.0
2020-07-01 23:16:12.818
info
(21082) script.js.Scripts.Telegram_menu: i=0, i1=1, i2=undefined
javascript.0
2020-07-01 23:16:12.817
info
(21082) script.js.Scripts.Telegram_menu: i=0, i1=0, i2=undefined
javascript.0
2020-07-01 23:16:12.816
info
(21082) script.js.Scripts.Telegram_menu: i=0, i1=undefined, i2=undefined
javascript.0
2020-07-01 23:16:12.815
info
(21082) script.js.Scripts.Telegram_menu: Определяем sub для команды = /меню
javascript.0
2020-07-01 23:16:12.813
info
(21082) script.js.Scripts.Telegram_menu: ВЫЗОВ ФУНКЦИИ getSub(cmd, arr, cb)
javascript.0
2020-07-01 23:16:12.809
info
(21082) script.js.Scripts.Telegram_menu: Пользователь - [object Object] с id - 323746; Отправленная команда - /меню
text2command.0
2020-07-01 23:16:12.711
info
(21471) processText: "#меню"
источник

PM

Pavel Mironov in ioBroker smarthome
var sub = [];
var iter = 0;

//////////// Настройки ///////////
var options = {
   telegram:   'telegram.0',            // Инстанция драйвера
   prefix:     'menu',                  // Префикс для отправляемых комманд при нажатии на кнопку, можно не менять
   backtext:   '🔙 Назад',              // Надпись на кнопке Назад
   closetext:  '❌ Закрыть',            // Надпись на кнопке Закрыть
   hometext:   '🏚 Главная',            // Надпись на кнопке Домой
   width:      3,                       // Максимальное количество столбцов с кнопками
   users_id:   [323746],  // id пользователей которые имеют доступ к меню
   menucall:   ['меню', '/command1'],   // Команда для вызова меню
   showHome:   true,                    // Показывать кнопку Домой
   showMsg:    true,                    // Показывать вплывающие сообщения
   debug:      true                    // Режим отладки, подробное логирование
};

/////////// МЕНЮ НАЧАЛО ////////////
var menu = {
   name: 'Главное меню',
   icon: '⚙️',
   submenu: [
       { // Сценарии
           name: 'Сценарии',
           icon: '⚙️',
           submenu: [
               {
                   name: 'ТВ',
                   state: 'lgtv.0.states.power'/*Switch TV power*/,
                   icons: {on: '📺', off: '✖️'},
                   submenu: []
               },
               {
                   name: 'Кино',
                   state: 'javascript.0.Scenes.Moves',
                   icons: {on: '📽', off: '✖️'},
                   submenu: []
               },
               {
                   name: 'Спать',
                   state: 'javascript.0.Scenes.Sleep',
                   icons: {on: '🛌', off: '✖️'},
                   submenu: []
               },
               {
                   name: 'Уборка',
                   state: 'javascript.0.Scenes.Сleaning',
                   icons: {on: '🤦', off: '✖️'},
                   submenu: []
               },
               {
                   name: 'Оповещение',
                   state: 'javascript.0.Scenes.sayOff',
                   icons: {on: '🔇', off: '🔊'},
                   submenu: []
               },
               {
                   name: 'Отпуск',
                   state: 'javascript.0.Scenes.Otpusk',
                   icons: {on: '📅', off: '✖️'},
                   submenu: []
               }
               ]
       },
       { // Освещение
           name: 'Освещение',
           icon: '💡',
           submenu: [
               {
                   name: 'Первый этаж',
                   icon: '💡',
                   submenu: [
                       {
                           name: 'Прихожая',
                           state: 'megad.1.p7_Прихожая_свет'/*Прихожая свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Коридор',
                           state: 'megad.1.p8_Коридор_свет'/*Коридор свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Ванная',
                           state: 'megad.1.p10_Ванная1_свет'/*Ванная1 свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Кухня',
                           state: 'megad.1.p11_Кухня_свет'/*Кухня свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Гостиная',
                           state: 'megad.1.p9_Гостиная_свет'/*Гостиная свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Лес
источник

PM

Pavel Mironov in ioBroker smarthome
тница',
                           state: 'megad.1.p13_Лестница1_свет'/*Лестница1 свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       }                                                                        
                   ]
               },
               {
                   name: 'Второй этаж',
                   icon: '💡',
                   submenu: [
                       {
                           name: 'Гардеробная',
                           state: 'megad.0.p7_Гардеробная_свет'/*Гардеробная свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Спальня',
                           state: 'megad.0.p8_Спальня_свет'/*Спальня свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Ванная',
                           state: 'megad.0.p9_Ванная_2_свет'/*Ванная 2 свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Гостевая 1',
                           state: 'megad.0.p10_Гостевая_1_свет'/*Гостевая 1 свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Гостевая 2',
                           state: 'megad.0.p11_Гостевая_2_свет'/*Гостевая 2 свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Лестница',
                           state: 'megad.0.p12_Лестница_2_свет'/*Лестница 2 свет*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       }
                   ]
               },
               {
                   name: 'Улица',
                   icon: '💡',
                   submenu: [
                       {
                           name: 'Освещение',
                           state: 'megad.0.p13_Крыльцо'/*Крыльцо*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       },
                       {
                           name: 'Гирлянда',
                           state: 'mqtt.0.cmnd.tasmota.POWER_ON/OFF'/*Power on/off*/,
                           icons: {on: '💡', off: '✖️'},
                           submenu: []
                       }
                   ]
               },            
           ]
       },
       { // Информация
           name: 'Информация',
           icon: 'ℹ️',
           submenu: [
               {
                   name: 'Температура',
                   state: function (){ //Можно вызвать функцию так
                           var val1 = getState('mqtt.0.ESPMETEO.sensors.dsw1'/*/ESPMETEO/sensors/dsw1*/).val
                           var val2 = getState('mqtt.0.ESPMETEO.sensors.dhtt1'/*/ESPMETEO/sensors/dhtt1*/).val
                           var val3 = getState('mihome.0.devices.weather_v1_158d0001ab17e6.temperature'/*Temperature*/).val
                           var val4 = getState('mihome.0.devices.weather_v1_158d000224cd1f.temperature'/*Temperature*/).val
                           var val5 = getState('mihome.0.devices.weather_v1_158d0002b56eb1.temperature'/*Temperature*/).val
                           var val6 = getState('mihome.0.devices.weather_v1_158d000272ea3e.temperature'/*Temperature*/).val
                           return "🌡 Температура на улице: " + val1 + " °C, \n"
                           + "🌡 Температура в коридоре: " + val2 + " °C, \n"
                           + "🌡 Температура в спальне: " +
источник

PM

Pavel Mironov in ioBroker smarthome
].name){
               obj.submenu[i].name = Rand(obj.submenu[i].name);
           }
           if(obj.submenu[i].submenu.length > 0){
               for(var i1 = 0; i1 < obj.submenu[i].submenu.length; i1++){
                   if(obj.submenu[i].submenu[i1].name){
                       obj.submenu[i].submenu[i1].name = Rand(obj.submenu[i].submenu[i1].name);
                   }
                   if(obj.submenu[i].submenu[i1].submenu.length > 0){
                       for(var i2 = 0; i2 < obj.submenu[i].submenu[i1].submenu.length; i2++){
                           if(obj.submenu[i].submenu[i1].submenu[i2].name){
                               obj.submenu[i].submenu[i1].submenu[i2].name = Rand(obj.submenu[i].submenu[i1].submenu[i2].name);
                           }
                       }
                   }
               }
           }
       }
   }
   logs(obj);
   menu = obj;
}

function Rand(val){
   val = iter + val;
   iter++;
   return val;
}

function UnUnique(name){
   return name.replace(/^\d+/, '');
}

UniqueNames(menu);

function logs(txt){
   if(options.debug){
       log(txt);
   }
}
источник

PM

Pavel Mironov in ioBroker smarthome
val3+ " °C, \n"
                           + "🌡 Температура в ванной: " + val4+ " °C, \n"
                           + "🌡 Температура в беседке: " + val5+ " °C, \n"
                           + "🌡 Температура в сарае: " + val6 + " °C, \n";
                       },
                   icon: '🌡',
                   submenu: []
               },
               {
                   name: 'Влажность',
                   state: Humidity, // А можно вызвать функцию вот так
                   icon: '💦',
                   submenu: []
               },
               {
                   name: 'Котел',
                   state: Boiler, // А можно вызвать функцию вот так
                   icon: '☀️',
                   submenu: []
               }
           ]
       },
   ]
};
/////////// МЕНЮ КОНЕЦ ////////////

/////////// ПОЛЬЗОВАТЕЛЬСКИЕ ФУНКЦИИ НАЧАЛО /////////////
function Humidity(){
   var val1 = getState('mqtt.0.ESPMETEO.sensors.dhth1'/*/ESPMETEO/sensors/dhth1*/).val;
   var val2 = getState('mihome.0.devices.weather_v1_158d0001ab17e6.humidity'/*Humidity*/).val;
   var val3 = getState('mihome.0.devices.weather_v1_158d000224cd1f.humidity'/*Humidity*/).val;
   var val4 = getState('mihome.0.devices.weather_v1_158d0002b56eb1.humidity'/*Humidity*/).val;
   var val5 = getState('mihome.0.devices.weather_v1_158d000272ea3e.humidity'/*Humidity*/).val;
   return "💦 Влажность в коридоре: " + val1 + " %, \n"
   +"💦 Влажность в спальне: " + val2 + " %, \n"
   +"💦 Влажность в ванной: " + val3 + " %, \n"
   +"💦 Влажность в беседке: " + val4 + " %, \n"
   +"💦 Влажность в сарае: " + val5 + " %, \n";
}
function Boiler(){
   var val1 = getState('mqtt.0.events.BAXI..outsidetemperature'/*events/BAXI//outsidetemperature*/).val;
   var val2 = getState('mqtt.0.events.BAXI..flame'/*events/BAXI//flame*/).val;
   var val3 = getState('mqtt.0.events.BAXI..dhwtemperature'/*events/BAXI//dhwtemperature*/).val;
   var val4 = getState('mqtt.0.events.BAXI..modulation'/*events/BAXI//modulation*/).val;
   var val5 = getState('mqtt.0.events.BAXI..fault'/*events/BAXI//fault*/).val;
   return "☀️ Температура на улице: " + val1 + " °C, \n"
   +"☀️ Горелка: " + val2 + " %, \n"
   +"☀️ Температура горячей воды: " + val3 + " °C, \n"
   +"☀️ Модуляция: " + val4 + " %, \n"
   +"☀️ Ошибка: " + val5 + " %, \n";
}
/////////// ПОЛЬЗОВАТЕЛЬСКИЕ ФУНКЦИИ КОНЕЦ /////////////


////////////////////////////////////////////////////////////////
////////////////////////// МАГИЯ ///////////////////////////////
////////////////////////////////////////////////////////////////
function setCommand(state, user){
   var timer;
   logs('ОТПРАВЛЯЕМ КОММАНДУ ' + state);
   if(typeof state !== 'function'){
       logs('ОБЬЕКТ = ' + JSON.stringify(getObject(state)));
       var obj = getObject(state);
       var role = obj.common.role;
       var type = obj.common.type;
       clearTimeout(timer);
       timer = setTimeout(function() {
           showMsg('Ошибка! нет ответа', user);
           sub = sub.slice(0, sub.length-1);
           show(user, sub);
       }, 4000);

   } else {
       show(user, sub);
   }
   if(type === 'boolean'){
       setState(state, !getState(state).val, function cb(){
           clearTimeout(timer);
           sub = sub.slice(0, sub.length-1);
           showMsg('Успешно!', user);
           show(user, sub);
           logs('СОСТОЯНИЕ = ' + getState(state).val);
       });
   } else {
       logs('НЕ ВЕРНЫЙ ТИП ОБЬЕКТА');
       showMsg('Не верный тип обьекта', user);
   }
}

function show(user, num, state){  /*** show ***/
   logs('ВЫЗОВ ФУНКЦИИ show(user, num)');
   getMenu(state, function cb(keyboard){
       logs('КОЛБЭК в show - function cb(keyboard)');
       logs('keyboard = ' + JSON.stringify(keyboard));
       if(sub.length > 0){
           keyboard.buttons = splitMenu(keyboard.buttons);
           if(options.showHome){
               keyboard.buttons.push([{ text: options.backtext, callback_data: 'back' }, { text: options.hometext, callback_data: 'home' }, { tex
источник

PM

Pavel Mironov in ioBroker smarthome
= arr[i].submenu;
           if(arr1.length > 0){
               for (var i1 = 0; i1 < arr1.length; i1++) {
                   logs('i=' + i + ', i1=' + i1 + ', i2=' + i2);
                   if(cmd === arr1[i1].name.toLowerCase()){
                       sub[0] = i;
                       sub[1] = i1;
                       if(arr1[i1].submenu.length == 0){
                           return cb(sub, arr1[i1].state);
                       } else {
                           return cb(sub, false);
                       }
                   }
                   var arr2 = arr1[i1].submenu;
                   if(arr2.length > 0){
                       for (var i2 = 0; i2 < arr2.length; i2++) {
                           logs('i=' + i + ', i1=' + i1 + ', i2=' + i2);
                           if(cmd === arr2[i2].name.toLowerCase()){
                               sub[0] = i;
                               sub[1] = i1;
                               sub[2] = i2;
                               if(arr2[i2].submenu.length == 0){
                                   return cb(sub, arr2[i2].state);
                               } else {
                                   return cb(sub, false);
                               }
                           }
                       }
                   }
               }
           }
       }
   }
}

function callback(user, cmd){
   if(~options.menucall.indexOf(cmd)){
       sub = [];
       show(user, sub);
   } else {
       if(cmd === 'close'){
           sub = [];
           close(user);
       } else if(cmd === 'back'){
           if(sub.length !== 0){
               sub = sub.slice(0, sub.length-1);
           }
           show(user, sub);
       } else if(cmd === 'home'){
           sub = [];
           show(user, sub);
       } else {
           getSub(cmd, menu, function cb(sub, state){
               logs('КОЛБЭК в callback - function cb(sub, state)');
               logs('state = ' + state);
               if(!state || typeof state === 'function'){
                   show(user, sub, state);
               } else {
                   setCommand(state, user);
               }
           });
       }
   }
}

function close(user){
   sendTo(options.telegram, {
       user: user,
       deleteMessage: {
           options: {
               chat_id: getState(options.telegram + ".communicate.requestChatId").val,
               message_id: getState(options.telegram + ".communicate.requestMessageId").val,
           }
       }
   });
}

on({id: options.telegram + '.communicate.request', change: 'any'}, function (obj) {
   var cmd = (obj.state.val.substring(obj.state.val.indexOf(']')+1)).toLowerCase();
   var userid = getState(options.telegram + ".communicate.requestChatId").val;
   if (userid){
       var name = getState(options.telegram + ".communicate.users").val;
       try {
           name = JSON.parse(name);
       } catch (err) {
           logs("Ошибка парсинга - " + JSON.stringify(err));
       }
       if (~options.users_id.indexOf(userid)){
           logs('Пользователь - ' + name[userid] + ' с id - ' + userid + '; Отправленная команда - ' + cmd);
           callback(name[userid], cmd);
       }  else {
           log('Доступ запрещен. Пользователя - ' + name[userid] + ' с id - ' + userid + ' нет в списке доверенных.' );
       }
   }
});

function splitMenu(arr){
   var i, j, tmp = [];
   for (i = 0, j = arr.length; i < j; i += options.width) {
       tmp.push(arr.slice(i, i + options.width));
   }
   return tmp;
}

function showMsg(text, user, showAlert){
   if(options.showMsg){
       sendTo(options.telegram, {
           user: user,
           answerCallbackQuery: {
               text: text,
               showAlert: showAlert ? true:false
           }
       });
   }
}

function UniqueNames(obj){
   if(obj.name){
       obj.name = Rand(obj.name);
   }
   if(obj.submenu.length > 0){
       for(var i = 0; i < obj.submenu.length; i++){
           if(obj.submenu[i
источник

PM

Pavel Mironov in ioBroker smarthome
t: options.closetext, callback_data: 'close' }]);
           } else {
               keyboard.buttons.push([{ text: options.backtext, callback_data: 'back' }, { text: options.closetext, callback_data: 'close' }]);
           }
           logs('keyboard.buttons = ' + JSON.stringify(keyboard.buttons));
           if(typeof keyboard.state === "function"){
               keyboard.menutext += '\r\n' + keyboard.state();
           }
           logs('keyboard 2 = ' + JSON.stringify(keyboard));
           sendTo(options.telegram, {
               user: user,
               text: keyboard.menutext,
               editMessageText: {
                   options: {
                       chat_id: getState(options.telegram + ".communicate.requestChatId").val,
                       message_id: getState(options.telegram + ".communicate.requestMessageId").val,
                       reply_markup: {
                           inline_keyboard: keyboard.buttons,
                       }
                   }
               }
           });
       } else {
           close(user);
           sendTo(options.telegram, {
               user: user,
               text: keyboard.menutext,
                   reply_markup: {
                       inline_keyboard: [
                           keyboard.buttons,
                           [{ text: options.closetext, callback_data: 'close' }]
                       ]
                   }
           });
       }
   });
}

function getMenu(state, cb){ /*** getMenu ***/
   logs('ВЫЗОВ ФУНКЦИИ getMenu(cb)');
   var keyboard_ = {
       menutext: (menu.icon ? menu.icon + ' ':'') + UnUnique(menu.name),
       state: '',
       buttons: []
   };
   var SubArr = sub.concat([]);
   logs('menu.submenu = ' + menu.submenu[2].submenu[1].state);
   getObj(menu.submenu, SubArr, keyboard_, function callback(SubMenuObj, keyboard, isfunc){
       logs('КОЛБЭК в getMenu - function callback(SubMenuObj, keyboard)');
       for (var i = 0; i < SubMenuObj.length; i++) {
           var icon;
           if(SubMenuObj[i].state && typeof SubMenuObj[i].state !== 'function' && getState(SubMenuObj[i].state).val){
               icon = SubMenuObj[i].icons.on;
           } else if (SubMenuObj[i].state && typeof SubMenuObj[i].state !== 'function'){
               icon = SubMenuObj[i].icons.off;
           } else {
               icon = SubMenuObj[i].icon;
           }
           logs('** SubMenuObj[i] = ' + JSON.stringify(SubMenuObj[i]));
           keyboard.buttons.push({
               text: icon + ' ' + UnUnique(SubMenuObj[i].name),
               callback_data: options.prefix + SubMenuObj[i].name
           });
       }
       cb(keyboard);
   });
}

function getObj(SubMenuObj, SubArr, keyboard, cb){  /*** getObj ***/
   logs('ВЫЗОВ ФУНКЦИИ getObj(obj, num, keyboard, cb)');
   var n;
   logs('SubArr.length = ' + SubArr.length);
   if(SubArr.length > 0){
       keyboard.menutext += ' > ' + (SubMenuObj[SubArr[0]].icon ? SubMenuObj[SubArr[0]].icon + ' ':'') + UnUnique(SubMenuObj[SubArr[0]].name);
       n = SubArr.shift();
       if(typeof SubMenuObj[n].state == 'function'){
           keyboard.state = SubMenuObj[n].state;
       }
       getObj(SubMenuObj[n].submenu, SubArr, keyboard, cb);
   } else {
       logs('****** getObj SubArr = ' + JSON.stringify(SubMenuObj[n]));
       cb(SubMenuObj, keyboard);
   }
}

function getSub(cmd, arr, cb){   /*** getSub ***/
   logs('ВЫЗОВ ФУНКЦИИ getSub(cmd, arr, cb)');
   cmd = cmd.replace(options.prefix, '');
   sub = [];
   arr = arr.submenu;
   logs('Определяем sub для команды = ' + cmd);
   if(arr.length > 0){
       for (var i = 0; i < arr.length; i++) {
           logs('i=' + i + ', i1=' + i1 + ', i2=' + i2);
           if(cmd === arr[i].name.toLowerCase()){
               sub[0] = i;
               if(arr[i].submenu.length == 0){
                   return cb(sub, arr[i].state);
               } else {
                   return cb(sub, false);
               }
           }
           var arr1
источник