Skip to content
Snippets Groups Projects
Verified Commit 70aeef2d authored by Thomas Flori's avatar Thomas Flori
Browse files

implement daemon command

parent f3fcc560
No related merge requests found
Pipeline #644 canceled with stages
<?php
namespace App\Command;
use App\Application;
use GetOpt\GetOpt;
use Hugga\Console;
class Daemon extends AbstractCommand
{
protected $name = 'daemon';
protected $description = 'Run the monitoring and control the fans';
public function __construct(Application $app, Console $console)
{
parent::__construct($app, $console);
}
public function handle(GetOpt $getOpt): int
{
if (posix_getuid() !== 0) {
$this->warn('This programm has to run as root');
return 1;
}
$fanConfig = $this->app->fanConfig;
try {
$fanConfig->readConfig();
} catch (\Throwable $e) {
$this->error('Unable to read config: ' . $e->getMessage());
return 2;
}
if (!$fanConfig->hasFans()) {
$this->error('No fans configured. Run config first');
return 3;
}
// @todo check that the fans are not in manual controll already
// prepare
$rules = $fanConfig->getRules();
// main loop
while (true) {
foreach ($rules as $rule) {
$rule->apply($this->console);
}
sleep(1);
}
}
}
......@@ -48,6 +48,18 @@ class FanConfig
return $this->fans;
}
public function getSensors(): array
{
$this->load();
return $this->sensors;
}
public function getRules(): array
{
$this->load();
return $this->rules;
}
protected function load()
{
if (!$this->loaded) {
......@@ -162,36 +174,40 @@ class FanConfig
$table->column(4, ['width' => 5]);
$table->draw();
$console->line('');
$console->info('Sensors');
$table = new Table($console, array_map(function (Sensor $sensor) {
$options = $sensor->toArray()['options'];
$result = [$sensor->name];
if ($sensor instanceof Sensor\HwmonSensor) {
$result[] = $options['hwmon'];
$result[] = $options['temp'];
} elseif ($sensor instanceof Sensor\CommandSensor) {
$result[] = null;
$result[] = $options['command'];
} else {
$result[] = null;
$result[] = null;
}
return $result;
}, $this->sensors), ['Name', 'hwmon', 'sensor / command']);
$table->draw();
if (!empty($this->sensors)) {
$console->line('');
$console->info('Sensors');
$table = new Table($console, array_map(function (Sensor $sensor) {
$options = $sensor->toArray()['options'];
$result = [$sensor->name];
if ($sensor instanceof Sensor\HwmonSensor) {
$result[] = $options['hwmon'];
$result[] = $options['temp'];
} elseif ($sensor instanceof Sensor\CommandSensor) {
$result[] = null;
$result[] = $options['command'];
} else {
$result[] = null;
$result[] = null;
}
return $result;
}, $this->sensors), ['Name', 'hwmon', 'sensor / command']);
$table->draw();
}
$console->line('');
if (!empty($this->rules)) {
$console->line('');
$console->info('Rules');
$table = new Table($console, array_map(function (Rule $rule) {
return [
implode(', ', array_map(fn($fan) => $fan->name, $rule->fans)),
$rule->sensor->name,
$rule->describe(),
];
}, $this->rules), ['Fans', 'Sensor', 'Description']);
$table->draw();
$console->info('Rules');
$table = new Table($console, array_map(function (Rule $rule) {
return [
implode(', ', array_map(fn($fan) => $fan->name, $rule->fans)),
$rule->sensor->name,
$rule->describe(),
];
}, $this->rules), ['Fans', 'Sensor', 'Description']);
$table->draw();
}
}
}
......@@ -17,6 +17,7 @@ class Kernel extends \Riki\Kernel
protected static $commands = [
Command\Config::class,
Command\ShowConfig::class,
Command\Daemon::class,
];
/** @var \Riki\Application|Application */
......
......@@ -3,6 +3,7 @@
namespace App\Model;
use App\Model;
use Hugga\Console;
abstract class Rule extends Model
{
......@@ -12,7 +13,7 @@ abstract class Rule extends Model
/** @var Sensor */
public $sensor;
abstract public function apply();
abstract public function apply(Console $console);
abstract public function describe(): string;
}
......@@ -5,6 +5,7 @@ namespace App\Model\Rule;
use App\Model\Fan;
use App\Model\Rule;
use App\Model\Sensor;
use Hugga\Console;
class CurveRule extends Rule
{
......@@ -43,29 +44,50 @@ class CurveRule extends Rule
}
}
public function apply()
public function apply(Console $console)
{
$temp = $this->sensor->getTemperature();
$lastPercentage = null;
$lastLimit = null;
foreach ($this->points as $percentage => $limit) {
if ($temp >= $limit) {
if ($temp > $limit) {
$lastPercentage = $percentage;
$lastLimit = $limit;
continue;
// somewhere between $lastV and $v
}
if (!$this->alwaysOn && $lastPercentage === null) {
// stop the fans if they should not run all the time and first limit not reached
$this->stopFans();
} elseif ($lastPercentage === null) {
// run the fans with the lowest percentage value before the first point
$console->line(sprintf(
'Temperature of %s: %d° C; Speed: %.2f%%',
$this->sensor->name,
$temp,
$percentage,
), Console::WEIGHT_DEBUG);
$this->setSpeed($percentage);
} else {
$factor = $temp - $lastLimit / ($limit - $lastLimit);
$this->setSpeed(($percentage - $lastPercentage) * $factor);
$factor = ($temp - $lastLimit) / ($limit - $lastLimit);
$speed = round(($percentage - $lastPercentage) * $factor + $lastPercentage, 2);
$console->line(sprintf(
'Temperature of %s: %d° C; Speed: %.2f%% (Calculation: (%d - %d) / (%d - %d) * (%d - %d) + %d)',
$this->sensor->name,
$temp,
$speed,
$temp,
$lastLimit,
$limit,
$lastLimit,
$percentage,
$lastPercentage,
$lastPercentage
), Console::WEIGHT_DEBUG);
$this->setSpeed($speed);
}
break;
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment