Jump to content

Включение/выключение клиентов динамически


Recommended Posts

Решение возникло из необходимости включения и выключения интернета ребенку, например.

  • Выключить интернет прямо сейчас (и соответственно включить обратно), не ожидая расписания
  • Включить инет на 5/15/30 минут

Не нашел готового решения, пришлось колхозить.

Решение простое - крон и список команд для выполнения ndmq с указанием их времени (в примере ниже /opt/home/scheduler_list). Список команд заполняется PHP скриптом с простой веб страницы.

Установить: крон, любой веб сервер (у меня lighttpd), php (для вебсервера). Я написал скрипт на питоне, но это чтобы изучить его, можно обойтись php (скрипт переписать, 20 строк всего)

Крон конфигурируется на выполнение следующего скрипта каждую минуту: 

import re
from datetime import datetime
import os

file_name = '/opt/home/scheduler_list'
file_content = open(file_name, 'r').readlines()
keep = []
modified = False
for line in file_content:
    parts = line.rstrip().split('|')
    if datetime.strptime(parts[0], '%Y-%m-%d %H:%M:%S') <= datetime.now():
        os.system(parts[1])
        modified = True
    else:
        keep.append(line)

if modified:
    list_file = open(file_name, 'w')
    for line in keep:
        list_file.write(line)

PHP скрипт для веб страницы

<?php
  $status = [];
  $fname = '/opt/home/scheduler_list';
  if (isset($_POST['amount']) && isset($_POST['device'])) {
    $time = new DateTime('now');
    $off_time = $on_time = $time->format('Y-m-d H:i:s');
    if ($_POST["amount"] != "on" && $_POST["amount"] != "off") {
      $time = $time->add(new DateInterval($_POST["amount"]));
      $off_time = $time->format('Y-m-d H:i:s');
    }
    $cmd = "";

    $content = file_get_contents($fname);

    foreach ($_POST['device'] as $key => $value) {
      $content = preg_replace('/.+ ' . $value . ' .+[\n]/iu', '', $content);
      if ($_POST["amount"] != 'off') {
        $cmd .= $on_time . '|ndmq -p "ip hotspot host ' . $value . ' permit"' . "\n";
        $status[$value] = "permit";
      }
      if ($_POST["amount"] != 'on') {
        $cmd .= $off_time . '|ndmq -p "ip hotspot host ' . $value . ' deny"' . "\n";
        if ($_POST["amount"] == 'off') $status[$value] = "deny";
      }
    }

    $content .= $cmd;

    $fp = fopen($fname, 'w');
    fwrite($fp, $content);
    fclose($fp);

    exec('python /opt/home/scheduler.py');
  }

  function status($mac) {
    global $status, $off_time;
    if (isset($status[$mac])) {
      $time = '';
      if ($_POST["amount"] != "on" && $_POST["amount"] != "off") {
        $time = preg_split('/ /', $off_time)[1];
      }
      return array("status" => $status[$mac], "time" => $time);
    }
    $cmd = 'ndmq -p "show ip hotspot ' . $mac . '" -P host/access';
    exec($cmd, $output, $retval);

    global $content, $fname;
    if (!isset($content)) $content = file_get_contents($fname);

    preg_match('/\d{4}\-\d{2}\-\d{2} (\d{2}:\d{2}:\d{2})\|.*' . $mac . ' deny/iu', $content, $m);
    return array("status" => $output[0], "time" => isset($m[1]) ? $m[1] : "");
  }

  $devices = [
    "20:e2:a8:27:00:00" => "Телефон 1",
    "d4:fb:8e:8f:00:00" => "Телефон 2",
  ];
?>
<html>
<head>
<title>Access setup page</title>
<style>
        body,table {
            font-size: 5.5rem;
            background-color: black;
            color: white;
        }
        input[type=checkbox],input[type=radio]{
            width: 70px;
            height: 70px;
        }
        input[type=submit]{
            font-size:5rem;
        }
        td {
            vertical-align-:top;
            border: lightgray 1px solid; 
            padding: 0px 20px;
        }
        .status-deny {
            color: red;
        }
        .status-permit {
            color: green;
        }
        .offtime {
            color: white;
            font-size:2rem;
        }
</style>
</head>
<body>
<form method="post">
<table border="0" style="border-collapse: collapse;">
    <?php
      foreach ($devices as $key => $value) {
        $device_status = status($key);
    ?>
    <tr>
      <td><input type="checkbox" name="device[]" value="<?= $key; ?>"></td>
      <td>
        <span class="status-<?= $device_status['status']; ?>"><?= $value ?></span>
        <?php if ($device_status["time"] != '') { ?><span class="offtime">[<?= $device_status['time'] ?>]</span><?php  } ?>
      </td>
    <tr>
    <?php } ?>
    <tr><td colspan="2" style="height:3rem"></td></tr>
    <tr><td><input type="radio" name="amount" value="PT5M"></td><td>5 минут</td><tr>
    <tr><td><input type="radio" name="amount" value="PT15M"></td><td>15 минут</td><tr>
    <tr><td><input type="radio" name="amount" value="PT30M"></td><td>30 минут</td><tr>
    <tr><td><input type="radio" name="amount" value="PT1H"></td><td>1 час</td><tr>
    <tr><td><input type="radio" name="amount" value="on"></td><td>Включить</td><tr>
    <tr><td><input type="radio" name="amount" value="off"></td><td>Выключить</td><tr>
</table>
<input type="submit" style="margin-top:30px">
</form>
</body>
</html>

 

  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...