Вашему вниманию предлагается программа для контроля и ограничения времени, проведённого за компьютером, например ребёнком.
Движущих факторов для создания первой версии было два:
Собственно проблема. Учебный год, доступные компьютеры, которые вроде бы нужны для учёбы, но при неограниченном доступе к ним времени ни на что другое уже не оставалось.
Самообразование и тренировка навыков написания скриптов на Python.
Ну и надежда, что подобные ограничения будут мотивировать ребенка на «взлом» системы и как следствие изучение чего‑то полезного.:)
Сразу скажу: с одной стороны, никаких эксклюзивных решений и ноу‑хау в программе нет. С другой стороны, имеющиеся на рынке и в свободном доступе решения по разным критериям меня не устраивали. Поэтому я решил попробовать написать своё.
Первую версию я писал сам, на Python. Поддерживалась одна платформа: Windows 10/11.
Со временем парк компьютеров и операционных систем дома вырос, а вместе с ним выросло и решение. Сейчас дома есть рабочая станция с тремя ОС (Windows, Linux и macOS, выбор при загрузке) и ноутбук. А ребёнок, разумеется, быстро понял: если время в одной системе закончилось, можно перезагрузиться в другую.
Текущая версия:
поддерживает несколько компьютеров и операционных систем с едиными политиками доступа и общим дневным лимитом: минуты, потраченные на Windows, Linux и macOS, складываются;
работает в домашней сети, а вне её (например, ноутбук в поездке) продолжает работать автономно: применяет более строгие лимиты и досылает статистику, когда снова видит сеть;
поддерживает алиасы имён пользователей, если логин одного и того же человека в разных системах пишется по‑разному;
имеет статистику: сколько минут каждый ребёнок провёл на каждом компьютере за любой день, плюс общую ленту событий со всех компьютеров с выгрузкой в CSV;
выдает системное уведомление, почему вход не разрешён, а не просто молча выкидывает из системы.
Преимущества для меня:
Единые политики для разных платформ (Windows, macOS, Linux) и физических устройств.
Всё написано на Python, то есть можно поменять под себя. Было легко поменять. По мере роста функциональности и, как следствие, объёма кода это стало уже не так просто. К тому же последующие версии писались с помощью ИИ (Claude Code). Архитектуру мы обсуждали и решали вместе, но код писал он, поэтому я хуже знаю, что и где реализовано. Об этом опыте ниже.
Данные не уходят «в облако производителя»: статистика хранится на моём собственном NAS.
Как это устроено
Решение состоит из двух частей.
Конфигуратор — графическое приложение (customtkinter). В нём мы добавляем профили детей, задаём политики доступа, настраиваем подключение к хранилищу и смотрим статистику. Его можно запустить на любом из компьютеров.

Для каждого человека задаются три параметра: максимум минут в день, самое раннее и самое позднее время входа. Отдельно задаются будни и выходные, плюс исключения по дням недели (например, в пятницу можно дольше). Каждое значение наследуется независимо: от исключения дня к будням/выходным ребёнка, а от них к общим значениям по умолчанию. Пустое поле означает «как по умолчанию».
Трекер — фоновая программа, которая отслеживает активные сеансы и проверяет их на соответствие политикам. На каждом компьютере и в каждой ОС работает свой экземпляр.
Трекер
Трекер запускается при старте системы от имени SYSTEM (Windows) или root (Linux, macOS) и работает постоянно, циклами. Раз в 5 минут (настраивается) он:
Получает список сеансов. В каждой ОС для этого используется свой механизм:
Windows: Terminal Services API (
WTSEnumerateSessions); заблокированный экран определяется по процессуLogonUI.exeв сеансе;Linux:
loginctl(systemd‑logind). Учитываются только локальные графические сеансы, SSH и текстовые консоли не считаются; блокировка определяется поLockedHint;macOS:
ioreg, ключIOConsoleUsers: кто на экране, кто «в фоне» из‑за быстрого переключения пользователей, у кого заблокирован экран.
Сопоставляет логин с человеком (с учётом алиасов). Чужие учётные записи (например, родительские) не учитываются и не записываются.
Начисляет время только активным и незаблокированным сеансам. Время измеряется монотонными часами процесса и ограничивается интервалом проверки. Поэтому ни перевод часов, ни сон компьютера в использованное время не попадают.
Складывает минуты ребёнка со всех компьютеров и при достижении лимита завершает сеанс.
Между циклами трекер каждые 20 секунд проверяет новые входы. Если ребёнок входит, когда время на сегодня уже закончилось или вход в это время не разрешён, он видит сообщение с настоящей причиной. Через 15 секунд сеанс завершается.

Сообщение показывается средствами самой ОС: на Windows это WTSSendMessage (окно в сеансе пользователя из службы SYSTEM), на Linux уведомление через notify-send или D‑Bus от имени пользователя, на macOS диалог через osascript.
Запуск: Windows, Linux, macOS
Трекер упаковывается с помощью PyInstaller. Это не компиляция в машинный код: PyInstaller собирает в одну папку небольшой нативный запускатель, собственную копию интерпретатора Python, все библиотеки и байт‑код программы. На целевом компьютере Python не нужен, и обновление системного Python ничего не сломает. Отдельно собирать приходится под каждую ОС: под Windows получается tracker.exe, под Linux исполняемый ELF‑файл, под macOS — Mach‑O.
Запускает эту программу штатный механизм ОС:
Windows: задача планировщика (Task Scheduler) при старте, от SYSTEM, без ограничения времени работы и с перезапуском при сбое. В комплекте есть PowerShell‑скрипт, который создаёт задачу с нужными настройками, но её можно создать и вручную;
Linux: systemd‑служба (
Restart=always);macOS: LaunchDaemon (
KeepAlive).
Установщика нет: папка копируется в защищённое место (Program Files, /opt, /usr/local). Права проверяет и при необходимости исправляет сам конфигуратор.
Общее хранилище: как подружить несколько компьютеров
Самое интересное архитектурное решение — как делить одно «время» между компьютерами, которые могут работать одновременно, а могут и не видеть друг друга.
Хранилище — обычный WebDAV по HTTPS с паролем. У меня это приложение WebDAV на TrueNAS Scale в домашней сети, но подойдёт и облачный WebDAV. Протокол выбран намеренно простой: от хранилища нужны только «прочитать файл», «записать файл целиком», «список файлов», «удалить». Ни дозаписи, ни блокировок.
Отсюда главное правило: каждый компьютер пишет только свои файлы.
config/limits.toml общие лимиты (пишет только конфигуратор) records/<компьютер>/<дата>.json минуты за день по каждому логину events/<компьютер>/<дата>.jsonl лента событий за день writers/<компьютер>.json имя компьютера, ОС, версия
Общее время ребёнка за день — это сумма его записей со всех компьютеров. Два компьютера никогда не пишут в один файл, поэтому конфликтов нет в принципе, и блокировки не нужны.
Каждый цикл трекер сначала пишет локально, потом отправляет файлы на NAS. Если NAS недоступен (ноутбук вне дома, NAS выключен), трекер:
продолжает считать время локально;
применяет более строгие лимиты: из личных лимитов ребёнка и общих значений по умолчанию для каждого параметра берётся строжайший. Так отключение Wi‑Fi не даёт лишнего времени;
отправляет накопленное, когда хранилище снова доступно.
Конфигурация (limits.toml) лежит на NAS. Каждый трекер скачивает её в каждом цикле, проверяет и только потом заменяет свою локальную копию. Поэтому ошибка в файле никогда не отключает контроль: трекер просто продолжает работать с последней корректной версией. Номер ревизии в файле не даёт двум конфигураторам незаметно перезаписать изменения друг друга.
Статистика
На вкладке Activity за любой день видно, сколько минут каждый ребёнок провёл на каждом компьютере, общий итог и лимит. Ниже — общая лента событий со всех компьютеров: вход, блокировка экрана, предупреждение о скором окончании времени, выход и его причина, потеря и восстановление связи с хранилищем. Обе таблицы можно выгрузить в CSV.

Безопасность
Модель угроз — любопытный ребёнок с обычной (не административной) учётной записью. От неё и строится защита:
трекер работает от SYSTEM/root, и обычный пользователь не может его остановить;
папка программы защищена от записи: иначе можно было бы подменить программу, которая работает от SYSTEM;
файл с паролем к хранилищу читают только администраторы и SYSTEM (root);
соединение с NAS идёт только по HTTPS с проверкой сертификата. Для самоподписанного сертификата указывается файл сертификата, а
verify=Falseне используется никогда;всё, что пришло из хранилища, проверяется (размер, схема, типы). Программа только читает данные и никогда их не исполняет.
От чего программа не защищает: загрузка с флешки, вход под администратором, отсутствие трекера в одной из ОС. Это закрывается настройками самой системы: пароль на BIOS/UEFI, запрет загрузки с USB, пароль загрузчика, у детей только обычные учётные записи. Отдельный нюанс Windows: обычный пользователь по умолчанию может сменить часовой пояс и так «сдвинуть» полночь и разрешённые часы. Это право стоит отобрать через secpol.msc. Собственно варианты как «вломать» систему при желании есть. На это и расчет.:)
Грабли, на которые я наступил
Версия 1.x: ошибки, которых не было видно
Задача планировщика «умирала» через трое суток. Трекер у меня был одним долгим циклом, а задача создавалась без параметра
-ExecutionTimeLimit. По умолчанию Windows останавливает задачу через 72 часа. Перезапускать её было нечему до следующей перезагрузки, так что контроль просто тихо выключался. Лечение:-ExecutionTimeLimit ([TimeSpan]::Zero)и перезапуск при сбое.Пользователь из конфигурации игнорировался. Функция возвращала
Noneдля «чужого» пользователя и пустой словарь для «своего, но без личных лимитов». А проверка былаif user_config:, и пустой словарь давалFalse. В логе ни слова, трекер исправно работал и ничего не ограничивал. Лечение: сравнение сNone, а пустой профиль наследует лимиты по умолчанию.Исключения по дням недели не работали вообще. Конфигуратор сохранял их с ключами
mon,tue…, а трекер искалmonday. Нашлось только при переписывании на 2.0; старые файлы теперь конвертируются автоматически.Трекер падал на каждой проверке лимита. Функция возвращала кортеж
(минуты, время), а его сравнивали с числом. Пока исключение перехватывалось где‑то выше, этого никто не видел.Одна битая строка в файле статистики отключала учёт. Ошибка разбора при чтении означала, что запись перестаёт работать до ручной правки файла. Хуже того, при ошибке чтения функция возвращала
{}, и следующая запись сохраняла только одного пользователя, стирая историю остальных. В 2.0 запись атомарная (временный файл →fsync→os.replace), а повреждённый файл не затирается, а откладывается в сторону.Заблокированный экран считался игрой. Сеанс на экране блокировки для Windows остаётся «активным». Определяю его по процессу
LogonUI.exeв этом сеансе.Перерасход времени. Проверка раз в 5 минут означает до 5 лишних минут на каждом компьютере. Особенно если войти снова после того, как выкинуло: у меня набегало 415 минут при лимите 400. В 2.1 появилась быстрая проверка новых входов раз в 20 секунд.
Мультизагрузка и часы. Windows хранит в аппаратных часах местное время, Linux и macOS — UTC. После каждой перезагрузки в другую ОС часы «уезжают» на величину часового пояса. Лечится ключом
RealTimeIsUniversalв реестре Windows. Сам трекер от этого защищён: время считается по монотонным часам процесса.Забытый порт. URL без
:30036вёл на тот же NAS с тем же сертификатом, но на веб‑интерфейс TrueNAS. Вместо файла лимитов приходила HTML‑страница. Теперь проверка подключения прямо говорит: «этот адрес отвечает без пароля, это не WebDAV‑ресурс, проверьте порт».
Опыт разработки с ИИ
Вторая версия писалась уже с Claude Code. Схема работы получилась такая: я выступал архитектором и админом, ИИ — разработчиком. Архитектуру обсуждали по пунктам, примерно как на ревью: хранилище, идентичность пользователей, время и часы, надёжность записи, безопасность. Решения фиксировались в журнале, а код и тесты (около 70) писал ИИ. Я ставил и проверял всё на реальных машинах и приносил логи.
Что понравилось: скорость, внимание к краевым случаям (сон, перевод часов, повреждённые файлы, офлайн) и тесты. Что стоит учитывать: я хуже знаю код изнутри. А часть проблем (масштабирование на Linux, сертификаты на Mac, групповая политика) нашлась только при реальной установке: ни ИИ, ни тесты их заранее не увидели.
Исходный код, сборки и инструкции по установке для всех трёх систем
Буду рад замечаниям и предложениям в комментариях.

