Управление телевизорами LG через последовательный порт RS232

Подключение исполнительных устройств, датчиков, контроллеров.

Модератор: immortal

skysilver
Сообщения: 3006
Зарегистрирован: Чт авг 21, 2014 8:28 am
Откуда: Киров, Россия
Благодарил (а): 400 раз
Поблагодарили: 1753 раза
Контактная информация:

Управление телевизорами LG через последовательный порт RS232

Сообщение skysilver » Вт июн 02, 2015 1:56 pm

Имеется в хозяйстве старенький но вполне еще бодрый 3D smart TV LG LW575S. А раз все мы тут подключаем к MajorDoMo все подряд, то и ТВ попал под раздачу. :)
Только вот в виду 2011 года выпуска и устаревшего протокола управления по Ethernet подружить мой ТВ с модулем LG SmartTV (v 1.0) by LuckyFIA никак не получилось. Но на выручку пришел порт RS232, также имеющийся в ТВ. С помощью копеечного USB-RS232 адптера все замечательно подключается к серверу, на котором крутится MajorDoMo (в моем случае это Cubietruck с ОС Debian). Полный набор команд управления через последовательный порт можно найти в официальной документации на ТВ.

Немного выдержек из документации на ТВ:
СпойлерПоказать
c146.jpg
c146.jpg (273 КБ) 16427 просмотров
c147.jpg
c147.jpg (185.42 КБ) 16427 просмотров
c148.jpg
c148.jpg (257.31 КБ) 16427 просмотров
Имея на руках набор команд и широко известный класс для работы с СОМ-портами php_serial.class.php, написал простенький класс для управления ТВ, функции которого можно использовать в методах и сценариях MajorDoMo. По аналогии можно управлять и другой техникой, например, ресиверами, многие из которых также имеют СОМ-порт.

Реализованы функции:
  • настройки порта;
  • проверки статуса ТВ (включен, выключен, уровень громкости, номер и название канала и пр.);
  • включение/выключение ТВ;
  • регулировка громкости;
  • выбор канала по номеру или по его названию;
  • включения/выключение 3D (в том числе его режима - SBS, OU);
  • выбор входа ТВ (HDMI, DTV, SATV, CATV и т.д.);
  • отправка любой другой команды телевизору согласно его документации и получения статуса выполнения этой команды.
В меню MajorDoMo добавил пункт и элементы контроля телевизором. Получилось вот так (интерфейс ПДУ позаимствовал у LuckyFIA):
СпойлерПоказать
Основное меню.jpg
Основное меню.jpg (152.19 КБ) 16440 просмотров
Управление каналами.jpg
Управление каналами.jpg (195.76 КБ) 16440 просмотров
Пульт ДУ.jpg
Пульт ДУ.jpg (141.93 КБ) 16440 просмотров
Код меню следующий:
СпойлерПоказать

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

<link type="text/css" rel="stylesheet" href="../templates/app_lgtvrs232/css/style.css" />

<script language="javascript">

function setChannel(channel) {
         var url = '/objects/?object=LG32LW575S&op=m&m=selectTVchannels&channel=';
        url += channel;
        //alert(url);
        AJAXRequest(url, 'updateTVinfo();', '');  
};
 
function setCommand(cmd) {
         var url = '/objects/?object=LG32LW575S&op=m&m=controlTV&cmd=';
        url += cmd;
        //alert(url);
        AJAXRequest(url, 'updateTVinfo();', '');  
};


function setVolume(vol) {
         var url = '/objects/?object=LG32LW575S&op=m&m=controlTV&cmd=setVOL&vol=';
        url += vol;
        //alert(url);
        AJAXRequest(url, '', '');  
};
 
function ajaxGetTVvolume(varname, id, timeout) {
  var url="/";
  url+='?md=application&action=ajaxgetglobal&var='+encodeURIComponent(varname);
  $.ajax({
   url: url
  }).done(function(data) { 
   var obj=jQuery.parseJSON(data);
    if (obj.DATA) {
      $('#'+id).val(obj.DATA);
       $('#'+id).slider("refresh");
    }
   });
  if (timeout>0) {
   window.setTimeout('ajaxGetTVvolume("'+varname+'", "'+id+'", '+timeout+');', timeout);
  }
  return false;
 }

function updateTVinfo() {
         ajaxGetTVvolume('LG32LW575S.volumeLevel', 'tvVOL', 0);
         ajaxGetGlobal('LG32LW575S.statusText', 'tvInfo', 0);
         //alert('Update OK!');
};

$(document).ready(function() {
    
     // Будем обновлять значения громкости и информации о ТВ каждые 30 сек.
     ajaxGetTVvolume('LG32LW575S.volumeLevel', 'tvVOL', 30000);
     ajaxGetGlobal('LG32LW575S.statusText', 'tvInfo', 30000);
 
    $(".tvimg").click(function(){
        var channel = $(this).attr("channel");
        setChannel(channel);
         ajaxGetGlobal('LG32LW575S.statusText', 'tvInfo', 0);
    });
 
     $(".rcBtn").click(function(){
        var cmd = $(this).attr("cmd");
         setCommand(cmd);
         ajaxGetGlobal('LG32LW575S.statusText', 'tvInfo', 0);
     });
    
    $( "#tvVOL" ).slider({
        stop: function( event, ui ) { 
            setVolume($("#tvVOL").val());
         }
    });
    
});
</script>

<div style="width: 305px; border-style:solid; border-width:0px; margin: 0 auto;">
    <table border="0" aligne="center" style="width: 100%; margin: 0 auto;">
        <tr>
            <td width="25%" align="center"><span id="vol-result"></span></td>
            <td width="25%" align="center"><span id="pwr-result"></span></td>
            <td width="25%" align="center"><span id="debugTV"></span></td>
            <td width="25%">                
                <a href="#" cmd="btn_OFF" class="rcBtn ui-btn ui-icon-power ui-btn-icon-notext ui-shadow" style="margin: 0 auto; height: 40px; width: 70px; border-radius: .3125em;"></a>          
            </td>
        </tr>
    </table>
    <table border="0" aligne="center" style="width: 100%; margin: 0 auto;">
        <tr>
            <td width="33%" align="center"></td>
            <td></td>
            <td width="33%">                         
            </td>
        </tr>
        <tr>
            <td colspan="3">
                <div  style="border-style:solid; border-width:0px; text-align:center; margin: 0 auto;">
                    <form style="margin-left: 11px;">
                          <label for="tv_volume" class="ui-hidden-accessible">volume:</label>
                        <input type="range" name="tv_volume" id="tvVOL" data-highlight="true" min="0" max="50" value="12" />
                      </form> 
                </div>
            </td>
        </tr>  
        <tr>
            <td colspan="3">
              <div data-role="controlgroup" data-type="horizontal" data-mini="true" class="ui-nodisc-icon" style="border-style:solid; border-width:0px; text-align:center; margin: 0 auto;">
                   <a href="#" cmd="btn_chDOWN" class="rcBtn ui-btn ui-icon-carat-d ui-btn-icon-notext ui-shadow">&nbsp</a>
                   <span id="tvInfo" class="ui-btn" style="text-align: center; width:175px"></span>
                   <a href="#" cmd="btn_chUP" class="rcBtn ui-btn ui-icon-carat-u ui-btn-icon-notext ui-shadow">&nbsp</a>
             </div>          
            </td>
        </tr>
        <tr>
            <td width="33%" align="center">&nbsp</td>
            <td align="center" >&nbsp</td>
            <td width="33%" align="center">&nbsp</td>
        </tr>
         <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Первый HD.png" class="tvimg" channel="Первый HD"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Россия HD.png" class="tvimg" channel="Россия HD"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Первый городской HD.png" class="tvimg" channel="Первый городской HD"></td>
        </tr>
        <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/СТС.png" class="tvimg" channel="СТС"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/СТС Love.png" class="tvimg" channel="СТС Love"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/ТНТ.png" class="tvimg" channel="ТНТ"></td>
        </tr>
        <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Disney.png" class="tvimg" channel="Disney"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Перец.png" class="tvimg" channel="Перец"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/ТВ-3.png" class="tvimg" channel="ТВ-3"></td>
        </tr>
        <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Пятница.png" class="tvimg" channel="Пятница"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Домашний.png" class="tvimg" channel="Домашний"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Discovery Channel.png" class="tvimg" channel="Discovery Channel"></td>
        </tr>
        <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Animal Planet.png" class="tvimg" channel="Animal Planet"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/TLC.png" class="tvimg" channel="TLC"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/National Geographic.png" class="tvimg" channel="National Geographic"></td>
        </tr>
        <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/National Geographic HD.png" class="tvimg" channel="National Geographic HD"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Nat Geo Wild HD.png" class="tvimg" channel="Nat Geo Wild HD"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Viasat Explorer.png" class="tvimg" channel="Viasat Explorer"></td>
        </tr>
        <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Viasat History.png" class="tvimg" channel="Viasat History"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Дом кино.png" class="tvimg" channel="Дом кино"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Viasat TV1000.png" class="tvimg" channel="Viasat TV1000"></td>
        </tr>
        <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Viasat TV1000 Rus.png" class="tvimg" channel="Viasat TV1000 Rus"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Sony SciFi.png" class="tvimg" channel="Sony SciFi"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Sony Set.png" class="tvimg" channel="Sony Set"></td>
        </tr>
        <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Fox.png" class="tvimg" channel="Fox"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Fox HD.png" class="tvimg" channel="Fox HD"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Fox Life.png" class="tvimg" channel="Fox Life"></td>
        </tr>
        <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Fox Life HD.png" class="tvimg" channel="Fox Life HD"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/Paramount Comedy.png" class="tvimg" channel="Paramount Comedy"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/МУЗ ТВ.png" class="tvimg" channel="МУЗ ТВ"></td>
        </tr> 
          <tr>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/MTV.png" class="tvimg" channel="MTV"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/RU TV.png" class="tvimg" channel="RU TV"></td>
            <td align="center"><img src="../templates/app_lgtvrs232/images/tvlogo/A-One.png" class="tvimg" channel="A-One"></td>
        </tr>
    </table>
</div>
Таким образом, можно полноценно управлять ТВ либо прямо через интерфейс MajorDoMo (смартфоны, планшеты, ПК), либо по расписанию или событиям.

Вот небольшой набор примеров, придуманный навскидку:
  • Продвинутый будильник. В указанное время включить телевизор и плавно увеличивать громкость.
  • Продвинутый напоминальщик. Можно сделать планировщик, который включит телевизор на указанном канале в нужное время.
  • Экономайзер электроэнергии. У телевизора есть режим энергосбережения, в котором гасится подсветка ЖК-панели. Снабдить компьютер (или самодельное устройство на каком-нибудь микроконтроллере) датчиком движения — и телевизор можно будет автоматически переводить в режим экономии энергии, когда у телевизора никого нет.
  • Эмулятор присутствия. Телевизор может включаться-выключаться автоматически (по расписанию) или удаленно.
  • Голосовое управление телевизором.
  • Удаленное управление телевизором без пульта ДУ.
  • Охранная система (автоматическое переключение источника на видеокамеру при срабатывании датчиков охраны).
В планах связать все это дело с XBMC, и тогда будет красота! Вот примеру, чтобы сейчас мне посмотреть фильм, нужно выполнить следующий ряд действий:
  • включить медиа-центр XBMC;
  • включить ТВ и выбрать вход HDMI, к которому подключен XBMC;
  • включить 5.1-акустику и выбрать на ней нужный вход и установить громкость;
  • запустить фильм в XBMC;
  • если этот фильм в 3D, то на ТВ включить соотвествующий режим (а это еще три нажатия на пульте :));
  • при завершении фильма надо опять же этот режим 3Д выключать.
Ужас, вообщем! )) Ну а теперь все идет к тому, что достаточно будет сказать "Алиса, хочу смотреть кино!", и ни о чем больше не беспокоиться.

Все используемые файлы, разложенные по нужным каталогам, в архиве:
https://yadi.sk/d/bcLBWrYhh2rms

Экспортированный класс TV с объектом LG32LW575S и методами здесь:
TV.zip
(3.59 КБ) 438 скачиваний
С уважением, skysilver.
За это сообщение автора skysilver поблагодарили (всего 3):
foxvlad (Вс сен 20, 2015 11:06 pm) • Дмитрий Иванов (Ср мар 09, 2016 10:34 pm) • XeonStaf (Вс сен 03, 2017 11:01 am)
Рейтинг: 3.49%
MajorDoMo (GitHub) на Cubietruck. ОС Debian 7 (wheezy) (kernel 3.4.105) с переносом на HDD.
Мой CONNECT | Блоги | Telegram
Msff
Сообщения: 3
Зарегистрирован: Сб мар 05, 2016 9:58 am
Благодарил (а): 1 раз
Поблагодарили: 0

Re: Управление телевизорами LG через последовательный порт R

Сообщение Msff » Сб мар 05, 2016 10:15 am

Так получилось, что и у меня есть лыжи (еще менее навороченные чем у автора, но так же с rs232). Используется в качестве монитора.
Соответственно ведет телевизор себя не как монитор, авто отключение есть, а вот в обратную сторону уже только пальцем, либо пульт. Небольшая, но проблема. И начать постигать все прелести управления ТВ средствами последовательных команд, я решил, именно с устранения этой проблемы.
Сабж накатал, мажордом рухнул. Перестал индекс обрабатывать (на localhost просто чистый белый экран).
В общем надеюсь тема не уникальна и кто нибудь поможет разобраться с этим хозяйством.
Параметры системы: debian с циннамоном на amd64. Мажордом мастерзипом с гитхаба взят.
Дмитрий Иванов
Сообщения: 83
Зарегистрирован: Вс фев 28, 2016 11:36 pm
Благодарил (а): 17 раз
Поблагодарили: 25 раз

Re: Управление телевизорами LG через последовательный порт R

Сообщение Дмитрий Иванов » Ср мар 09, 2016 10:44 pm

Спасибо за классную тему! MajorDoMo у меня на Raspberry Pi2 установлен и при попытке подкинуть файл php_serial.class.php в директорию /var/www/lib/ апач вываливается с ошибкой "Fatal error: Cannot redeclare class phpSerial in /var/www/lib/php_serial.class.php on line 18". Пытаюсь понять где еще может объявляться этот класс? (соответственно без этого класса не работает и lgtv_rs232.class.php).
Данная ошибка возникает только после добавления файла lgtv_rs232.class.php, сам по себе php_serial ошибку не вызывает... Помогите, плз, разобраться!
Msff
Сообщения: 3
Зарегистрирован: Сб мар 05, 2016 9:58 am
Благодарил (а): 1 раз
Поблагодарили: 0

Re: Управление телевизорами LG через последовательный порт R

Сообщение Msff » Ср мар 09, 2016 10:59 pm

У меня он лежал в /var/www/scripts
И там же лежал пример использования в мажордом.
Я решил начать с элементарных вещей и начать с ардуины. Вроде порт запускается в цикле, но получает какую то белиберду (хотя открываю порт с соответствующими настройками), как следствие не парсит ничего и... Ой как все запутано.
Где знающие? Нид хэлп
Дмитрий Иванов
Сообщения: 83
Зарегистрирован: Вс фев 28, 2016 11:36 pm
Благодарил (а): 17 раз
Поблагодарили: 25 раз

Re: Управление телевизорами LG через последовательный порт R

Сообщение Дмитрий Иванов » Ср мар 09, 2016 11:10 pm

Пытаюсь разбираться дальше, если в файле закоментировать: //require('php_serial.class.php'); и //require('my.class.php');, то запускается без ошибок... Работает или нет не знаю... Пробовал запускать на винде (без телека), без ошибок запускалось если убрать require('my.class.php');, Подредактировал в методе устройство и попробовал посмотреть через монитор com-порта - данные шли. Вот теперь дома пробую на малине, чем мониторить ком-порт на ней не знаю пока... А провода пока нет (только usb-com адаптер)... завтра провод спаяю продолжу эксперименты... Но, ошибки, конечно смущают...
skysilver
Сообщения: 3006
Зарегистрирован: Чт авг 21, 2014 8:28 am
Откуда: Киров, Россия
Благодарил (а): 400 раз
Поблагодарили: 1753 раза
Контактная информация:

Re: Управление телевизорами LG через последовательный порт R

Сообщение skysilver » Чт мар 10, 2016 10:07 am

Готовых решений по вашим проблемам не предложу, но попробую немного разъяснить ситуацию. ;)

1. Все, что предложено мною выше было протестировано и успешно используется в ОС Linux (Debian). На Windows я не пробовал. Насколько знаю, библиотека php_serial.class.php (идет в архиве в первом посте) поддерживает и Linux, и Windows, поэтому вполне возможно, что заведется и под виндой.

2. Прежде, чем загонять все это в MajorDoMo, нужно убедиться, что само управление ТВ работает просто через консоль. Я гонял команды через утилиту minicom.

3. Если главный цикл MajorDoMo запущен от пользователя www-data, нужно дать права этому пользователю на работу с com-портами (т.е. добавить в группу dialout).

4. В каталоге /www/scripts/ у меня тоже есть файлы sample_cycle_arduino_direct.php и php_serial.class.php. Но т.к. цикл начинается с префикса sample_, то он не запускается при старте главного цикла, поэтому ошибка "Fatal error: Cannot redeclare class phpSerial" у меня не возникает.

5. Строчку require('my.class.php'); в lgtv_rs232.class.php можно смело убирать. Функции из my.class.php в финальной версии класса lgtv_rs232.class не используются. А вот строка require('php_serial.class.php'); обязательно нужна. Именно функции из php_serial.class обеспечивают работу с com-портами в ОС.

Ну и напоследок - в любой нештатной ситуации нужно смотреть логи Apache. :) Именно Apache, а не debmes в MajorDoMo.
За это сообщение автора skysilver поблагодарили (всего 2):
Msff (Чт мар 10, 2016 10:34 am) • Дмитрий Иванов (Чт мар 10, 2016 10:10 pm)
Рейтинг: 2.33%
MajorDoMo (GitHub) на Cubietruck. ОС Debian 7 (wheezy) (kernel 3.4.105) с переносом на HDD.
Мой CONNECT | Блоги | Telegram
Дмитрий Иванов
Сообщения: 83
Зарегистрирован: Вс фев 28, 2016 11:36 pm
Благодарил (а): 17 раз
Поблагодарили: 25 раз

Re: Управление телевизорами LG через последовательный порт R

Сообщение Дмитрий Иванов » Чт мар 10, 2016 10:20 pm

У меня как раз-таки Debian (Raspberry Pi2). Спаял кабель проверил через minicom - все работает! Через Majordomo тоже вроде работает - громкость регулируется и каналы вверх-вниз переключаются... кнопка вкл. не работает... кнопки каналов тоже (нужно разбираться еще с ними - под себя). В общем продолжаю разбираться (кстати строка //require('php_serial.class.php');, по прежнему закоментирована...), но что-то же работает))
p.s. телек LG LH-5000 - в инструкции команды для rs232 совпадают приведенными в первом посте...
Дмитрий Иванов
Сообщения: 83
Зарегистрирован: Вс фев 28, 2016 11:36 pm
Благодарил (а): 17 раз
Поблагодарили: 25 раз

Re: Управление телевизорами LG через последовательный порт R

Сообщение Дмитрий Иванов » Пт мар 11, 2016 8:19 am

Методы on/off работают!
skysilver А приведите, пожалуйста, пример сценария включения канала с определенным номером!
Спасибо!
skysilver
Сообщения: 3006
Зарегистрирован: Чт авг 21, 2014 8:28 am
Откуда: Киров, Россия
Благодарил (а): 400 раз
Поблагодарили: 1753 раза
Контактная информация:

Re: Управление телевизорами LG через последовательный порт R

Сообщение skysilver » Пт мар 11, 2016 9:54 am

Дмитрий Иванов писал(а):skysilver А приведите, пожалуйста, пример сценария включения канала с определенным номером!
У меня есть шаблоны по типу "Включи СТС" (включ.+? стс), т.е. происходит включение определенного канала. Код шаблона простой:

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

callMethod('LG32LW575S.selectTVchannels', array('channel'=>'СТС'));
т.е. вызывается метод selectTVchannels и ему передается параметр channel, который и определяет нужный канал. При этом нужно не забыть отредактировать под себя список channels.csv (\www\templates\app_lgtvrs232\channels.csv), в котором прописано соответствие номера канала и его названия.

Моя модель ТВ даже не требует предварительного включения ТВ, т.е. просто выбираем канал и ТВ включается на нужном. А если ТВ уже был включен, то просто переключится, куда надо. В вашем случае, возможно, потребуется сначала вызвать метод powerOn, а после него с некоторой задержкой selectTVchannels.

Также замечу, что метод selectTVchannels актуален только для кабельного цифрового вещания, для других типов вещания (dtv, sadtv, analog, cable) надо дописывать.
За это сообщение автора skysilver поблагодарил:
Дмитрий Иванов (Пт мар 11, 2016 12:20 pm)
Рейтинг: 1.16%
MajorDoMo (GitHub) на Cubietruck. ОС Debian 7 (wheezy) (kernel 3.4.105) с переносом на HDD.
Мой CONNECT | Блоги | Telegram
Дмитрий Иванов
Сообщения: 83
Зарегистрирован: Вс фев 28, 2016 11:36 pm
Благодарил (а): 17 раз
Поблагодарили: 25 раз

Re: Управление телевизорами LG через последовательный порт R

Сообщение Дмитрий Иванов » Пт мар 11, 2016 12:33 pm

Огромное спасибо! Попробовал на работе (на винде, без телевизора), судя по выводу программы Advanced Serial Port Monitor, все работает (ma 01 00 0d 90 [len=14])
Сейчас ломаю голову, как распарсить шаблон, что бы передать в переменную имя канала. Пока, что дошел, как передать номер канала, типа:

Включи телевизор на (\d+)(\s*)(\d*)

$сh=$matches[1];
say("$сh");

А как сделать тоже самое с именем канала, например СТС?

Спасибо!
Последний раз редактировалось Дмитрий Иванов Пт мар 11, 2016 2:25 pm, всего редактировалось 3 раза.
Ответить