summaryrefslogtreecommitdiff
path: root/localwebsite/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'localwebsite/handlers')
-rw-r--r--localwebsite/handlers/FakeRequestHandler.php20
-rw-r--r--localwebsite/handlers/InverterHandler.php88
-rw-r--r--localwebsite/handlers/MiscHandler.php52
-rw-r--r--localwebsite/handlers/ModemHandler.php192
-rw-r--r--localwebsite/handlers/RequestHandler.php41
5 files changed, 393 insertions, 0 deletions
diff --git a/localwebsite/handlers/FakeRequestHandler.php b/localwebsite/handlers/FakeRequestHandler.php
new file mode 100644
index 0000000..09e03b8
--- /dev/null
+++ b/localwebsite/handlers/FakeRequestHandler.php
@@ -0,0 +1,20 @@
+<?php
+
+class FakeRequestHandler extends RequestHandler {
+
+ public function apacheNotFound() {
+ http_response_code(404);
+ $uri = htmlspecialchars($_SERVER['REQUEST_URI']);
+ echo <<<EOF
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<html><head>
+<title>404 Not Found</title>
+</head><body>
+<h1>Not Found</h1>
+<p>The requested URL {$uri} was not found on this server.</p>
+</body></html>
+EOF;
+ exit;
+ }
+
+} \ No newline at end of file
diff --git a/localwebsite/handlers/InverterHandler.php b/localwebsite/handlers/InverterHandler.php
new file mode 100644
index 0000000..7878c4f
--- /dev/null
+++ b/localwebsite/handlers/InverterHandler.php
@@ -0,0 +1,88 @@
+<?php
+
+class InverterHandler extends RequestHandler
+{
+
+ public function __construct()
+ {
+ parent::__construct();
+ $this->tpl->add_static('inverter.js');
+ }
+
+ public function GET_status_page()
+ {
+ global $config;
+ $inv = new InverterdClient($config['inverterd_host'], $config['inverterd_port']);
+ $inv->setFormat('json');
+ $status = jsonDecode($inv->exec('get-status'))['data'];
+
+ $this->tpl->set([
+ 'status' => $status,
+ 'html' => $this->renderStatusHtml($status)
+ ]);
+ $this->tpl->set_title('Инвертор');
+ $this->tpl->render_page('inverter_page.twig');
+ }
+
+ public function GET_status_ajax() {
+ global $config;
+ $inv = new InverterdClient($config['inverterd_host'], $config['inverterd_port']);
+ $inv->setFormat('json');
+ $status = jsonDecode($inv->exec('get-status'))['data'];
+ ajax_ok(['html' => $this->renderStatusHtml($status)]);
+ }
+
+ protected function renderStatusHtml(array $status)
+ {
+ $power_direction = strtolower($status['battery_power_direction']);
+ $power_direction = preg_replace('/ge$/', 'ging', $power_direction);
+
+ $charging_rate = '';
+ if ($power_direction == 'charging')
+ $charging_rate = sprintf(' @ %s %s',
+ $status['battery_charging_current']['value'],
+ $status['battery_charging_current']['unit']);
+ else if ($power_direction == 'discharging')
+ $charging_rate = sprintf(' @ %s %s',
+ $status['battery_discharging_current']['value'],
+ $status['battery_discharging_current']['unit']);
+
+ $html = sprintf('<b>Battery:</b> %s %s',
+ $status['battery_voltage']['value'],
+ $status['battery_voltage']['unit']);
+ $html .= sprintf(' (%s%s, ',
+ $status['battery_capacity']['value'],
+ $status['battery_capacity']['unit']);
+ $html .= sprintf('%s%s)',
+ $power_direction,
+ $charging_rate);
+
+ $html .= "\n".sprintf('<b>Load:</b> %s %s',
+ $status['ac_output_active_power']['value'],
+ $status['ac_output_active_power']['unit']);
+ $html .= sprintf(' (%s%%)',
+ $status['output_load_percent']['value']);
+
+ if ($status['pv1_input_power']['value'] > 0)
+ $html .= "\n".sprintf('<b>Input power:</b> %s %s',
+ $status['pv1_input_power']['value'],
+ $status['pv1_input_power']['unit']);
+
+ if ($status['grid_voltage']['value'] > 0 or $status['grid_freq']['value'] > 0) {
+ $html .= "\n".sprintf('<b>Generator:</b> %s %s',
+ $status['grid_voltage']['unit'],
+ $status['grid_voltage']['value']);
+ $html .= sprintf(', %s %s',
+ $status['grid_freq']['value'],
+ $status['grid_freq']['unit']);
+ }
+
+ return nl2br($html);
+ }
+
+ public function GET_status_page_update()
+ {
+
+ }
+
+} \ No newline at end of file
diff --git a/localwebsite/handlers/MiscHandler.php b/localwebsite/handlers/MiscHandler.php
new file mode 100644
index 0000000..4f35981
--- /dev/null
+++ b/localwebsite/handlers/MiscHandler.php
@@ -0,0 +1,52 @@
+<?php
+
+class MiscHandler extends RequestHandler
+{
+
+ public function GET_main() {
+ $this->tpl->set_title('Главная');
+ $this->tpl->render_page('index.twig');
+ }
+
+ public function GET_phpinfo() {
+ phpinfo();
+ exit;
+ }
+
+ public function GET_sensors_page() {
+ global $config;
+
+ $clients = [];
+ foreach ($config['si7021d_servers'] as $key => $params) {
+ $cl = new Si7021dClient(...$params);
+ $clients[$key] = $cl;
+
+ $cl->readSensor();
+ }
+
+ $this->tpl->set(['sensors' => $clients]);
+ $this->tpl->set_title('Датчики');
+ $this->tpl->render_page('sensors.twig');
+ }
+
+ public function GET_pump_page() {
+ global $config;
+
+ list($set) = $this->input('set');
+ $client = new GPIORelaydClient($config['pump_host'], $config['pump_port']);
+
+ if ($set == GPIORelaydClient::STATUS_ON || $set == GPIORelaydClient::STATUS_OFF) {
+ $client->setStatus($set);
+ redirect('/pump/');
+ }
+
+ $status = $client->getStatus();
+
+ $this->tpl->set([
+ 'status' => $status
+ ]);
+ $this->tpl->set_title('Насос');
+ $this->tpl->render_page('pump.twig');
+ }
+
+} \ No newline at end of file
diff --git a/localwebsite/handlers/ModemHandler.php b/localwebsite/handlers/ModemHandler.php
new file mode 100644
index 0000000..88fe463
--- /dev/null
+++ b/localwebsite/handlers/ModemHandler.php
@@ -0,0 +1,192 @@
+<?php
+
+class ModemHandler extends RequestHandler
+{
+
+ public function __construct()
+ {
+ parent::__construct();
+ $this->tpl->add_static('modem.js');
+ }
+
+ public function GET_status_page() {
+ global $config;
+
+ $this->tpl->set([
+ 'modems' => $config['modems'],
+ 'js_modems' => array_keys($config['modems']),
+ ]);
+
+ $this->tpl->set_title('Состояние модемов');
+ $this->tpl->render_page('modem_status_page.twig');
+ }
+
+ public function GET_status_get_ajax() {
+ global $config;
+ list($id) = $this->input('id');
+ if (!isset($config['modems'][$id]))
+ ajax_error('invalid modem id: '.$id);
+
+ $modem_data = self::getModemData(
+ $config['modems'][$id]['ip'],
+ $config['modems'][$id]['legacy_token_auth']);
+
+ ajax_ok([
+ 'html' => $this->tpl->render('modem_data.twig', [
+ 'loading' => false,
+ 'modem_data' => $modem_data
+ ])
+ ]);
+ }
+
+
+ public function GET_routing_smallhome_page() {
+ global $config;
+
+ list($error) = $this->input('error');
+ $upstream = self::getCurrentSmallHomeUpstream();
+
+ $current_upstream = [
+ 'key' => $upstream,
+ 'label' => $config['modems'][$upstream]['label']
+ ];
+
+ $this->tpl->set([
+ 'error' => $error,
+ 'current' => $current_upstream,
+ 'modems' => $config['modems'],
+ ]);
+ $this->tpl->set_title('Маршрутизация');
+ $this->tpl->render_page('routing_page.twig');
+ }
+
+ public function GET_routing_smallhome_switch() {
+ global $config;
+ list($new_upstream) = $this->input('upstream');
+ if (!isset($config['modems'][$new_upstream]))
+ redirect('/routing/?error='.urlencode('invalid upstream'));
+
+ $current_upstream = self::getCurrentSmallHomeUpstream();
+ if ($current_upstream != $new_upstream) {
+ if ($current_upstream != $config['routing_default'])
+ MyOpenWrtUtils::ipsetDel($current_upstream, $config['routing_smallhome_ip']);
+ if ($new_upstream != $config['routing_default'])
+ MyOpenWrtUtils::ipsetAdd($new_upstream, $config['routing_smallhome_ip']);
+ }
+
+ redirect('/routing/');
+ }
+
+ public function GET_routing_ipsets_page() {
+ list($error) = $this->input('error');
+
+ $ip_sets = MyOpenWrtUtils::ipsetListAll();
+ $this->tpl->set([
+ 'sets' => $ip_sets,
+ 'error' => $error
+ ]);
+ $this->tpl->set_title('Маршрутизация: IP sets');
+ $this->tpl->render_page('routing_ipsets_page.twig');
+ }
+
+ public function GET_routing_ipsets_del() {
+ list($set, $ip) = $this->input('set, ip');
+ self::validateIpsetsInput($set, $ip);
+
+ $output = MyOpenWrtUtils::ipsetDel($set, $ip);
+
+ $url = '/routing/ipsets/';
+ if ($output != '')
+ $url .= '?error='.urlencode($output);
+ redirect($url);
+ }
+
+ public function POST_routing_ipsets_add() {
+ list($set, $ip) = $this->input('set, ip');
+ self::validateIpsetsInput($set, $ip);
+
+ $output = MyOpenWrtUtils::ipsetAdd($set, $ip);
+
+ $url = '/routing/ipsets/';
+ if ($output != '')
+ $url .= '?error='.urlencode($output);
+ redirect($url);
+ }
+
+ public function GET_routing_dhcp_page() {
+ $leases = MyOpenWrtUtils::getDHCPLeases();
+ $this->tpl->set([
+ 'leases' => $leases
+ ]);
+ $this->tpl->set_title('Маршрутизация: DHCP');
+ $this->tpl->render_page('routing_dhcp_page.twig');
+ }
+
+ public function GET_sms_page() {
+ global $config;
+
+ list($selected) = $this->input('modem');
+ if (!$selected)
+ $selected = array_key_first($config['modems']);
+
+ $cfg = $config['modems'][$selected];
+ $e3372 = new E3372($cfg['ip'], $cfg['legacy_token_auth']);
+ $messages = $e3372->getSMSList();
+
+ $this->tpl->set([
+ 'modems_list' => array_keys($config['modems']),
+ 'modems' => $config['modems'],
+ 'selected_modem' => $selected,
+ 'messages' => $messages
+ ]);
+ $this->tpl->set_title('Модемы: SMS-сообщения');
+ $this->tpl->render_page('sms_page.twig');
+ }
+
+ protected static function getModemData(string $ip, bool $need_auth = true): array {
+ $modem = new E3372($ip, $need_auth);
+ $signal = $modem->getDeviceSignal();
+ $status = $modem->getMonitoringStatus();
+ $traffic = $modem->getTrafficStats();
+ return [
+ 'type' => e3372::getNetworkTypeLabel($status['CurrentNetworkType']),
+ 'level' => $status['SignalIcon'] ?? 0,
+ 'rssi' => $signal['rssi'],
+ 'sinr' => $signal['sinr'],
+ 'connected_time' => secondsToTime($traffic['CurrentConnectTime']),
+ 'downloaded' => bytesToUnitsLabel(gmp_init($traffic['CurrentDownload'])),
+ 'uploaded' => bytesToUnitsLabel(gmp_init($traffic['CurrentUpload'])),
+ ];
+ }
+
+ protected static function getCurrentSmallHomeUpstream() {
+ global $config;
+
+ $upstream = null;
+ $ip_sets = MyOpenWrtUtils::ipsetListAll();
+ foreach ($ip_sets as $set => $ips) {
+ if (in_array($config['routing_smallhome_ip'], $ips)) {
+ $upstream = $set;
+ break;
+ }
+ }
+ if (is_null($upstream))
+ $upstream = $config['routing_default'];
+
+ return $upstream;
+ }
+
+ protected static function validateIpsetsInput($set, $ip) {
+ global $config;
+
+ if (!isset($config['modems'][$set]))
+ redirect('/routing/ipsets/?error='.urlencode('invalid set: '.$set));
+
+ if (($slashpos = strpos($ip, '/')) !== false)
+ $ip = substr($ip, 0, $slashpos);
+
+ if (!filter_var($ip, FILTER_VALIDATE_IP))
+ redirect('/routing/ipsets/?error='.urlencode('invalid ip/network: '.$ip));
+ }
+
+} \ No newline at end of file
diff --git a/localwebsite/handlers/RequestHandler.php b/localwebsite/handlers/RequestHandler.php
new file mode 100644
index 0000000..2fffdc0
--- /dev/null
+++ b/localwebsite/handlers/RequestHandler.php
@@ -0,0 +1,41 @@
+<?php
+
+class RequestHandler extends request_handler {
+
+ /** @var web_tpl*/
+ protected $tpl;
+
+ public function __construct() {
+ global $__tpl;
+ $__tpl = new web_tpl();
+ $this->tpl = $__tpl;
+
+ $this->tpl->add_static('bootstrap.min.css');
+ $this->tpl->add_static('bootstrap.min.js');
+ $this->tpl->add_static('polyfills.js');
+ $this->tpl->add_static('app.js');
+ $this->tpl->add_static('app.css');
+ }
+
+ public function dispatch(string $act) {
+ global $config;
+ $this->tpl->set_global([
+ '__dev' => $config['is_dev'],
+ ]);
+ return parent::dispatch($act);
+ }
+
+ protected function method_not_found(string $method, string $act)
+ {
+ global $config;
+
+ if ($act != '404' && $config['is_dev'])
+ debugError(get_called_class() . ": act {$method}_{$act} not found.");
+
+ if (!is_xhr_request())
+ $this->tpl->render_not_found();
+ else
+ ajax_error('unknown act "'.$act.'"', 404);
+
+ }
+} \ No newline at end of file