Компьютер давно многим заменил телевизор, а что не хватает компьютеру для комфортного просмотра кино, сериалов и прочего? Мне, лично, не хватало пульта дистанционного управления.

image

Я немного увлекаюсь веб-программированием в свободное время. Было решено написать свой велосипед, и, заодно совместить приятное с полезным. Была изучена возможность с помощью консоли управлять компьютером, в первую очередь меня интересовал следующий минимальный объем задач (который немного увеличился в последствии):

  • Возможность отправить ПК в режим сна
  • Возможность выключить громкость

С помощью известного поисковика нашел консольную программу, NirCmd, программа позволяет осуществлять достаточно много действий кроме указанных выше. С основной частью мы определились. Как я говорил, немного изучаю php, веб-сервер у меня как правило запущен постоянно, поэтому ничего специфичного в плане сервера я придумывать не стал. Сервер написан на php и состоит из двух классов: Control, который представляет собой методы, которые исполняют консольные команды и Route, который делает валидацию приходящих запросов и исполняет методы класса Control.

Control выгладит вот так (код однотипный, поэтому я сократил):

class Control implements ActionControl {
		protected $Path; //путь до программы nirCmd;
		
		function __construct($p = 'C:/nircmd/nircmd.exe') {
			$this->Path = $p;
		}
		function standby() {
			`{$this->Path} standby`;
		}
		function hibernate() {
			`rundll32 powrprof.dll,SetSuspendState 0,1,0`;
		}
		function reboot() {
			`{$this->Path} exitwin reboot`;
		}
		function turnOff() {
			`{$this->Path} exitwin poweroff`;
		}
		function logout() {
			`{$this->Path} exitwin logoff`;
		}
}

Второй класс, — Route. Собственно, к нему обращается клиент. Класс, в первую очередь осуществляет валидацию запроса, и, если запрос правильный вызывает методы класса Control.
Выглядит это так:

class Route implements ActionRoute {
		protected $possible = []; 		
		protected $ControlObj;
	
		function __construct($obj) {
			$this->possible = get_class_methods($obj); 
			$this->ControlObj = $obj;
		}
		function route($arr) { 
			forEach($arr as $key => $value) {	
		   if (in_array($key, $this->possible) && $value == 'true') {
		   	$this->execute($key);
		   } else 
		   	{
		   		Message::sent('wrong method');
		   	}	
			}
		}
		function execute($c) {
			$this->ControlObj->$c();
			Message::sent('executed');
		}
	}

Чтобы получилось в случае чего легко расширить количество методов в классе Control, валидация в классе Route жестко не привязана к определенному списку методов класса Control, точнее привязана, но все возможные методы извлекаются из самого объекта, с ними и идет сравнение пришедших данных.

Сам файл к которому обращается клиент выглядит вот так:

<?
	define("PATH", "C:/nircmd/nircmd.exe"); 
	function __autoload($name) {
		require "class/$name.class.php";
	}
	
	$obj = new Control(PATH);
	$route = new Route($obj);

	if ($_GET) {
		$route->route($_GET);
	}
?>

Если приходит GET запрос, то весь массив отдаем методу route.

Клиентская часть представляет собой кнопки управления и один обработчик, по которому мы шлем данные при помощи ajax на сервер.

var wrapper = document.querySelector(".wrapper");

function getXmlHttpRequest(){
	if (window.XMLHttpRequest) {
		try {
			return new XMLHttpRequest();
		} catch (e){ }
	} else if (window.ActiveXObject) {
		try {
			return new ActiveXObject('Msxml2.XMLHTTP');
		} catch (e){}
		try {
			return new ActiveXObject('Microsoft.XMLHTTP');
		} catch (e){}
		}
	return null;
}

wrapper.addEventListener('click', function(e){
	var target = e.target;

	if(target.tagName!= 'BUTTON') return;
	if (target.getAttribute('data')=='qestion') {
		var yn = confirm("Уверен?");
		if (!yn) return
			ajaxf(target.id);
	}
	ajaxf(target.id);
})

	function ajaxf($com) {
	 	var command = $com+'=true';
		var xhr = new getXmlHttpRequest();
		xhr.open('GET', 'remote.php?'+command, true);
		xhr.send();
		xhr.onreadystatechange = function() { 
  			if (xhr.readyState != 4) return;
  			if (xhr.status != 200) {
    			console.log(xhr.status + ': ' + xhr.statusText);
  			} else {
   	 		console.log(xhr.responseText);
  			}
		}
	}

На сегодня реализован следующий функционал управления:

  • спящий режим
  • гибернация
  • перезагрузится
  • выключить
  • выйти
  • выключить монитор
  • включить/отключить звук по триггеру
  • громкость больше
  • громкость меньше
  • Медиа кнопки, stop/play next/prev

Все, что я хотел получить, получил, но, как говорится, аппетит приходит во время еды. Хотелось бы иметь обратную связь от сервера, т.е. при первом заходе на страницу делать запрос текущего уровня громкости, например. К сожалению, nirCmd не возвращает значения при выполнении, поэтому с тем, что имеем сейчас, я не знаю, как это осуществить.

Вопрос безопасности. Хотя это все и крутится на локальной машине, будет очень печально, если доступ к исполнению команд nirCmd будет у злоумышленника, т.к. можно сотворить много деструктивных действий.

Готовый проект на GIthub.
Поделиться с друзьями
-->

Комментарии (41)


  1. nikitasius
    08.08.2016 13:28
    -3

    ssh, не?


    1. HunterXXI
      08.08.2016 13:40
      +3

      причем здесь ssh? Разве заголовок статьи звучит «Я нифига не понял как управлять компьютером удаленно и поэтому сделал все на PHP». Помоему нет.


      1. nikitasius
        08.08.2016 16:39

        К тому, что если есть доступ на комп, то можно поставить на андроид простой ssh клиент и спокойно рулит компом, закинув пару bash скриптов, если что-то по памяти не помнишь, а не городить на php со всеми вытекающими.


        1. Andrusha
          08.08.2016 18:46
          +1

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


          1. nikitasius
            09.08.2016 12:09

            Тапнуть ./ это тоже быстро.


        1. Taragolis
          08.08.2016 19:18
          +1

          Судя по скриптам все это из под Windows крутится


          1. nikitasius
            09.08.2016 12:10

            Я то вижу. Было бы решение кросплатформенным, было бы хорошо.


            1. Taragolis
              09.08.2016 14:14

              Не думаю, что для такой задачи тянуть OpenSSH в Windows хорошая идея. Да и кроссплатформенным это решения навряд ли будет


    1. akdes
      08.08.2016 19:18
      +1

      Статья о контроле компа браузером…
      Решение имеет место быть… Если бы автор захотел контролить ssh, он бы написал «Управление компьютером с помощью ssh»


  1. r1zar
    08.08.2016 13:38

    Тоже писал для себя нечто подобное, было еще управление мышкой, возможность передачи нажатия любой клавиши и авторизация по Basic Auth.
    Добавляет много комфорта, но я не доверяю сам себе в плане безопасности, поэтому перестал пользоваться. Лучше уж встать и нажать на кнопки, чем увеличивать риск предоставить полное управление злоумышленнику.


  1. McDeFF
    08.08.2016 13:40
    -2

    Готовый проект на GIthab.

    Вообще-то, GitHub.


    1. Sad_Bro
      08.08.2016 13:47

      да, конечно, подправил


  1. HunterXXI
    08.08.2016 13:45

    Отлично. Можно добавить авторизацию по токенам или сертификатам и любой мобильный девайс станет пультом управления для того устройства где установлен даный скрипт. В некоторых ситуация может быть весьма удобно.


    1. Sad_Bro
      08.08.2016 13:49

      Спасибо. Если выпускать в интернет только, но с таким функционалом смысла нет. А так да, думал сделать для «потренироваться».


      1. bustEXZ
        09.08.2016 08:52

        из лиги лени, приятно включив фильм и раскинувшись на диване, через телефон увеличивать громкость. Почему нет? =)


  1. Sad_Bro
    08.08.2016 13:53

    буду благодарен если покритикуете мое ООП, буквально первые шаги делаю.


    1. saksmt
      09.08.2016 00:36

      ООП тут нет, почти совсем. Да и не настолько это большое приложение, чтоб об этом думать. (Естественно об этом надо задумываться, но иногда имеет смысл сделать проще) Как домашняя поделка для себя вполне сойдёт, но пожалуй было ошибкой выкладывать это сюда, впрочем как и на гитхаб. Если хотите попрактиковаться в PHP — выберите задачу посложнее (или эту преобразуйте), почитайте PSR, постигните composer, напишите свой велосипедофреймворк (главное не забудьте его потом выкинуть) и возьмите что-нибудь достойное — symfony, zend, phalcon,… Ну и хабру на эту тему почитайте уже сотни одних и тех же рекомендаций написано.


      Ну и добро пожаловать на хабр!


      1. Sad_Bro
        09.08.2016 09:11

        Спасибо! буду ковырять дальше. PSR не уделял внимания совершенно, оставил «на потом», на что сразу обратили внимание на гитхаб) в общем начинаю вникать)


        1. vanxant
          15.08.2016 01:14

          Вот несогласен с saksmt, не стоит сразу грузиться монстрами типа zend-а или симфони. Пока доберётесь до уровня, где они нужны — модны будут совсем другие фреймворки.
          Писать свой велосипед с нуля сейчас тоже неактуально, сначала нужно посмотреть, «чё там как у других».
          Начните с чего-нибудь лёгкого, но прекрасного. Типа peej/tonic. Попробуйте переписать свой проект под него. Мозги сразу вправятся в нужную сторону, при этом не засоряясь мусором.


          1. Sad_Bro
            15.08.2016 09:28

            у меня план сейчас такой,- уяснить принципы популярных паттернов, остановится на наиболее востребованом (на сегодня я так понял это MVC), далее планирую погрузится в Yii, пока остановился на нем, просто из за того что информация по нему вроде как достаточно.


          1. saksmt
            16.08.2016 20:26

            Без своих велосипедов далеко не уедешь, ну это ИМХО конечно. Сам ровно так учился к простому (silex) я пришёл в итоге своей php-карьеры, после чего радостно нырнул в яву.


            • Я не говорил, что велосипед должен быть гигантским, что-нибудь простенькое для понимания фабрик, фронт-контроллера и т.д.


  1. mihmig
    08.08.2016 14:10
    -1

    >>запрос текущего уровня громкости
    Поверхностный поиск не дал результатов, придётся писать маленькую консольную утилитку на Delphi

    А вообще, если канал связи позволяет — поставьте teamViewer — полный доступ к компьютеру со смартфона.


    1. Psychosynthesis
      08.08.2016 16:19

      А это не всегда удобно. У меня например 4'' смарт (принципы, знаете ли), в мелкие элементы с него тыкать крайне неудобно.

      Да и как-то запускать tV чтобы трек переключить, ну… кхм…


  1. Tallanvor
    08.08.2016 14:20

    С одной стороны, это ценно само по себе именно с точки зрения «сделать самому».
    Но с другой, «всё уже придумано до нас» — MaxRemote имеет весь необходимый функционал.


  1. vconst
    08.08.2016 14:37

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


  1. Sad_Bro
    08.08.2016 16:00

    Спасибо, за критику, не могу минуса подправить к сожалению, так как уровень не тот. Да конечно я знал про teamViewer, но столь мощный комбайн мне был не нужен, как я писал цель была свой простой велосипед придумать, что и было сделано в каком то объеме.


    1. Andrusha
      08.08.2016 18:51

      Ну TeamViewer тут действительно избыточен, есть специально заточенные программы для превращения смартфона в пульт управления. Например, Unified Remote


  1. ionicman
    08.08.2016 19:15

    Не, круто конечно… но why is so complicated?
    Цена вопроса — 300 рублей (даже меньше) + возможность управлять мышкой с пульта, причем вполне себе полноценно.
    Если не хватает того, что идет из коробки (что мало вероятно, но может быть — биндинг нужных scan-кодов на нужные ф-ии)


    1. HunterXXI
      08.08.2016 23:21

      ты не чуешь перспективу. управлять то можно через интернет. например выключить удаленно или включить. например грабителя так можно напугать…


      1. ionicman
        09.08.2016 12:30

        Не, перспективу я не чую, я чую задачу автора, которую он четко описал :)
        Задача была — управлять с дивана базовыми функциями проигрывания аля громкость / пуск / пауза и т.д. + сервисное типа «выключить комп». С этим данный девайс справляется на ура без велосипедов и строчек кода. Цена вопроса — 300 рублей :D

        А управлять через интернет можно элементарно — OpenVPN на роутер, wakeup-lan на комп и ammyadmin (teamviewer) в автозагрузку (если винда), а если нет — обычный SSH и все.

        А дальше телефон / планшет с OpenVPN + программой удаленки.


  1. ExplosiveZ
    08.08.2016 23:12

    Отличная идея! Изучаю JavaEE, попробую реализовать такое.
    Те, кто предлагают поставить TeamViewer/radmin/rdp/%app_name% — вы серьёзно? Загружать машину непонятным софтом, который требует много ресурсов(относительно данной реализации).
    А тем, кто говорит, что можно купить мышь/клавиатуру/%device_name% — товарищ реализовал это скорее всего за пол часа перерыва и эта вещь имеет куда больший потенциал, чем %device_name% с 1,5 функциями.


    1. akaSStalkALEX
      09.08.2016 10:42

      Стоит TeamViewer много лет, весьма понятный софт и, скорее всего, требует столько же ресурсов, сколько веб-сервер, может меньше.


  1. instalator
    09.08.2016 09:07

    В умном доме понадобилось управлять компьютером, написал себе такую программку, пользуюсь полгода, замечаний нет.


    1. Sad_Bro
      09.08.2016 09:12

      интересный проект!


      1. instalator
        09.08.2016 09:19

        Спасибо! Если интересно, есть несколько статей на https://geektimes.ru/users/instalator/topics/


  1. kalobyte
    09.08.2016 09:07
    +1

    надо было на шарпе такое делать
    вот для образца http://www.sources.ru/csharp/SimpleHttpServer.html

    95% можно сделать при помощи powershell, надо только подцепить его к вебсерверу как цги модуль


  1. Ivan_83
    09.08.2016 10:22

    Хабр не торт: всего один человек в теме как надо чтобы было удобно.

    ИК приёмник покупается или паяется простейшая схема для подключения к ком порту.
    Далее LIRC (WinLIRC под венду) и/или Girder.
    Потом некоторое время+усилия чтобы обучить софт реакции на любые любимые пульты ДУ и софт принимать команды.

    Я так себе сделал году в 2004 и года до 2009 оно у меня использовалось, потом был переезд, смена юзкейсов… а потом был куплен ящег для семейных просмотров. Сейчас подумываю про внешний мозг к ящику, и хочу чтобы рулился по HDMI-CEC родным пультом.

    У меня была рулёжка:
    — громкостью
    — винампом: вкл/выкл, пауза, плей, далее, прев.
    — виндовс медиа плеером: плей/пауза
    — вкл/выкл красивые опенгл часики на весь экран
    — блокировка (Win+L)
    — Кажется ещё было переключение каналов в софтине от тв тюнера(бехолдер), и соответственно её запуск/сворачивание в трей.

    К вопросу юзабилити: обычный пду в 100500 раз удобнее всяких планшетов, фуфлонов и прочего барахла с сенсорным экраном потому что:
    — стоит копейки / или вообще бесплатно от помершей техники
    — не нужно смотреть куда жмёшь, крайне легко на ощупь ориентироваться — это весьма актуально
    — зарядка батарейками раз в пару лет

    И удобнее всяких дистанционных клав/мышек, по тем же причинам. Плюс для пду не требуется орлиное зрение дабы разглядеть курсор через всю комнату.

    2 Sad_Bro
    Хочешь критики — участвуй в чужих опенсорсных проектах.


    1. instalator
      09.08.2016 10:39

      Задачи удаленного управления бывают разные. IR хорошо, но что делать если комп в другом помещении? Я делал управление для автоматизации, например сценарий Музыка, включается кмоп (если выключен) запускается foobar (люблю я его, слушаю lossles), ресивер переключается на вход PC и начинает играть музыка, не прикасаясь к пульту. сценарии запускаю голосовыми командами.


  1. Notimer
    09.08.2016 10:42
    +1

    Или включить MediaPlayer Classic, у которого уже из коробки веб-морда, слушающая нужный порт (по дефолту отключен)


  1. alexyr
    09.08.2016 19:30

    Для себя что-то подобное написал используя бота Telegram на Python2.7.


  1. GadPetrovich
    10.08.2016 21:50

    Компьютер можно удаленно включать, если использовать WakeOnLan.