Created
May 11, 2018 22:37
-
-
Save moorer2k/8f63b354615dc40eb4d192e5607129b6 to your computer and use it in GitHub Desktop.
Laravel console command for automated control over TP-Link HS100. Automatically turn on my plugged in fan if temps get over 55 C.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
use Symfony\Component\Process\Process; | |
class FanController extends Command | |
{ | |
/** | |
* The name and signature of the console command. | |
* | |
* @var string | |
*/ | |
protected $signature = 'temps:monitor'; | |
/** | |
* Command description.. | |
* | |
* @var string | |
*/ | |
protected $description = 'Monitor TPLink HS100 to control fan if CPU temps are too high using lm_sensors.'; | |
/** | |
* Create a new command instance. | |
* | |
* @return void | |
*/ | |
public function __construct() | |
{ | |
parent::__construct(); | |
} | |
/** | |
* Execute the console command. | |
* | |
* @return mixed | |
*/ | |
public function handle() | |
{ | |
$this->checkTemps(); | |
} | |
private function checkTemps() | |
{ | |
$curr = $this->getTemps(); | |
foreach ($curr['Temps'] as $index => $temps) { | |
if ($temps[$index] >= 55) { | |
$this->info('Temp ' . $temps[$index] . ' detected! Too hot! Turning on fan...'); | |
$this->sendSmartCmd('on'); | |
} else { | |
$fanStatus = $this->sendSmartCmd('')->system->get_sysinfo->relay_state; | |
if ($fanStatus == 0) { | |
$this->info('Fan already off.'); | |
return; | |
} | |
$this->info('Temp ' . $temps[$index] . ' detected. Cool enough, turning off fan...'); | |
$this->sendSmartCmd('off'); | |
} | |
} | |
} | |
private function getTemps() | |
{ | |
$arrOut = []; | |
$process = new Process('sensors'); | |
$process->run(); | |
if (!$process->isSuccessful()) { | |
return 'fail'; | |
} | |
$sensors_out = str_replace('°', ' ', $process->getOutput()); | |
preg_match_all("/Core\s(?<Core>\N):\s+\+(?<Current>\N+)\s(?<Format>\w)\s+\(high\s=\s\+(?<Warn>\N+)\s\w,\scrit\s=\s\+(?<Crit>\N{5})\s\w/", $sensors_out, $matches); | |
for ($i = 0; $i < count($matches['Core']); $i++) { | |
$arrOut[$i] = [$i => $matches['Current'][$i]]; | |
} | |
return (['Warn' => $matches['Warn'][0], | |
'Crit' => $matches['Crit'][0], | |
'Temps' => $arrOut, | |
]); | |
} | |
//https://github.com/Ramboss/TP-Link_HS100 < credit. | |
private function sendSmartCmd($command) | |
{ | |
$host = '10.0.0.47'; | |
$port = 9999; | |
switch ($command) { | |
case 'on':{ | |
$command = '{"system":{"set_relay_state":{"state": 1}}}'; | |
break;} | |
case 'off':{ | |
$command = '{"system":{"set_relay_state":{"state": 0}}}'; | |
break;} | |
case 'cloudinfo':{ | |
$command = '{"cnCloud":{"get_info":{}}}'; | |
break;} | |
case 'sysinfo':{ | |
$command = '{"system":{"get_sysinfo":{}}}'; | |
break;} | |
case 'wlanscan':{ | |
$command = '{"netif":{"get_scaninfo":{"refresh":0}}}'; | |
break;} | |
case 'time':{ | |
$command = '{"time":{"get_time":{}}}'; | |
break;} | |
case 'schedule':{ | |
$command = '{"schedule":{"get_rules":{}}}'; | |
break;} | |
case 'macaddress':{ | |
$command = '{"system":{"get_sysinfo":{}}}'; | |
break;} | |
case 'countdown':{ | |
$command = '{"count_down":{"get_rules":{}}}'; | |
break;} | |
case 'antitheft':{ | |
$command = '{"anti_theft":{"get_rules":{}}}'; | |
break;} | |
case 'reboot':{ | |
$command = '{"system":{"reboot":{"delay":1}}}'; | |
break;} | |
case 'reset':{ | |
$command = '{"system":{"reset":{"delay":1}}}'; | |
break;} | |
case 'nightModeOn':{ | |
$command = '{"system":{"set_led_off":{"off":1}}}'; | |
break;} | |
case 'nightModeOff':{ | |
$command = '{"system":{"set_led_off":{"off":0}}}'; | |
break;} | |
case 'realtimeVoltage':{ | |
$command = '{"emeter":{"get_realtime":{}}}'; | |
break;} | |
case 'EMeterVGain':{ | |
$command = '{"emeter":{"get_vgain_igain":{}}}'; | |
break;} | |
case 'currentRunTime':{ | |
$command = '{"system":{"get_sysinfo":{}}}'; | |
break;} | |
case 'currentPower':{ | |
$command = '{"emeter":{"get_realtime":{}}}'; | |
break;} | |
case 'gettime':{ | |
$command = '{"emeter":{"get_daystat":{"month":5; break ; }"year":2017}}}'; | |
break;} | |
case 'currentRunTimeHour':{ | |
$command = '{"system":{"get_sysinfo":{}}}'; | |
break;} | |
case 'resetcounter':{ | |
$command = '{"emeter":{"erase_emeter_stat":null}}'; | |
break;} | |
default:{ $command = '{"system":{"get_sysinfo":{}}}';} | |
} | |
$fp = fsockopen($host, $port); | |
if (!$fp) {exit;} | |
$request = pack('N', strlen($command)); | |
$key = 0xAB; | |
for ($i = 0; $i < strlen($command); $i++) { | |
$key = ord(substr($command, $i, 1)) ^ $key; | |
$request .= chr($key); | |
} | |
fwrite($fp, $request, strlen($request)); | |
$response = fread($fp, 4); | |
$response = fread($fp, unpack('N', $response)[1]); | |
fclose($fp); | |
$key = 0xAB; | |
$output = ''; | |
for ($i = 0; $i < strlen($response); $i++) { | |
$nextKey = ord(substr($response, $i, 1)); | |
$output .= chr($nextKey ^ $key); | |
$key = $nextKey; | |
} | |
return json_decode($output); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console; | |
use Illuminate\Console\Scheduling\Schedule; | |
use Illuminate\Foundation\Console\Kernel as ConsoleKernel; | |
class Kernel extends ConsoleKernel | |
{ | |
/** | |
* The Artisan commands provided by your application. | |
* | |
* @var array | |
*/ | |
protected $commands = [ | |
'\App\Console\Commands\FanController', | |
]; | |
/** | |
* Define the application's command schedule. | |
* | |
* @param \Illuminate\Console\Scheduling\Schedule $schedule | |
* @return void | |
*/ | |
protected function schedule(Schedule $schedule) | |
{ | |
$schedule->command('temps:monitor')->everyFiveMinutes(); | |
} | |
/** | |
* Register the commands for the application. | |
* | |
* @return void | |
*/ | |
protected function commands() | |
{ | |
$this->load(__DIR__ . '/Commands'); | |
require base_path('routes/console.php'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment