JezerM
3 years ago
5 changed files with 182 additions and 81 deletions
@ -0,0 +1,165 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# |
||||||
|
# brightness.py |
||||||
|
# |
||||||
|
# Copyright © 2021 JezerM |
||||||
|
# |
||||||
|
# This file is part of Web Greeter. |
||||||
|
# |
||||||
|
# Web Greeter is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 3 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# Web Greeter is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# The following additional terms are in effect as per Section 7 of the license: |
||||||
|
# |
||||||
|
# The preservation of all legal notices and author attributions in |
||||||
|
# the material or in the Appropriate Legal Notices displayed |
||||||
|
# by works containing it is required. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with Web Greeter; If not, see <http://www.gnu.org/licenses/>. |
||||||
|
|
||||||
|
import os |
||||||
|
import stat |
||||||
|
import time |
||||||
|
import pyinotify |
||||||
|
from typing import List |
||||||
|
from threading import Thread |
||||||
|
import globals |
||||||
|
from logger import logger |
||||||
|
from config import web_greeter_config |
||||||
|
|
||||||
|
sys_path = ["/sys/class/backlight/"] |
||||||
|
|
||||||
|
def get_controllers() -> List[str]: |
||||||
|
ctrls: List[str] = [] |
||||||
|
for dev in sys_path: |
||||||
|
if os.path.exists(dev) and stat.S_ISDIR(os.stat(dev).st_mode): |
||||||
|
drs = os.listdir(dev) |
||||||
|
for name in drs: |
||||||
|
ctrls.append(os.path.join(dev, name)) |
||||||
|
return ctrls |
||||||
|
|
||||||
|
class EventHandler(pyinotify.ProcessEvent): |
||||||
|
def process_IN_MODIFY(self, event): |
||||||
|
if globals.greeter: |
||||||
|
globals.greeter.greeter.brightness_update.emit() |
||||||
|
|
||||||
|
|
||||||
|
# Behavior based on "acpilight" |
||||||
|
# Copyright(c) 2016-2019 by wave++ "Yuri D'Elia" <wavexx@thregr.org> |
||||||
|
# See https://gitlab.com/wavexx/acpilight |
||||||
|
class BrightnessController: |
||||||
|
|
||||||
|
_controllers: List[str] = [] |
||||||
|
_available: bool = False |
||||||
|
_brightness_path: str |
||||||
|
_max_brightness_path: str |
||||||
|
steps: int |
||||||
|
delay: int |
||||||
|
_brightness: int |
||||||
|
_max_brightness: int = -1 |
||||||
|
|
||||||
|
def __init__(self): |
||||||
|
self._controllers = get_controllers() |
||||||
|
if (len(self._controllers) == 0 or |
||||||
|
self._controllers[0] == None or |
||||||
|
web_greeter_config["config"]["features"]["backlight"]["enabled"] == False): |
||||||
|
self._available = False |
||||||
|
return |
||||||
|
b_path = self._controllers[0] |
||||||
|
self._available = True |
||||||
|
self._brightness_path = os.path.join(b_path, "brightness") |
||||||
|
self._max_brightness_path = os.path.join(b_path, "max_brightness") |
||||||
|
|
||||||
|
with open(self._max_brightness_path, "r") as f: |
||||||
|
self._max_brightness = int(f.read()) |
||||||
|
|
||||||
|
steps = web_greeter_config["config"]["features"]["backlight"]["steps"] |
||||||
|
self.steps = 1 if steps <= 1 else steps |
||||||
|
self.delay = 200 |
||||||
|
self.watch_brightness() |
||||||
|
|
||||||
|
def _watch(self): |
||||||
|
wm = pyinotify.WatchManager() |
||||||
|
handler = EventHandler() |
||||||
|
wm.add_watch(self._brightness_path, pyinotify.IN_MODIFY) |
||||||
|
|
||||||
|
notifier = pyinotify.Notifier(wm, handler) |
||||||
|
|
||||||
|
notifier.loop() |
||||||
|
|
||||||
|
def watch_brightness(self): |
||||||
|
if not self._available: |
||||||
|
return |
||||||
|
thread = Thread(target = self._watch) |
||||||
|
thread.daemon = True |
||||||
|
thread.start() |
||||||
|
|
||||||
|
@property |
||||||
|
def max_brightness(self) -> int: |
||||||
|
return self._max_brightness |
||||||
|
|
||||||
|
@property |
||||||
|
def real_brightness(self) -> int: |
||||||
|
if not self._available: return -1 |
||||||
|
try: |
||||||
|
with open(self._brightness_path, "r") as f: |
||||||
|
return int(f.read()) |
||||||
|
except OSError: |
||||||
|
logger.error("Couldn't read from \"" + self._brightness_path + "\"") |
||||||
|
return -1 |
||||||
|
|
||||||
|
@real_brightness.setter |
||||||
|
def real_brightness(self, v: int): |
||||||
|
if not self._available: return |
||||||
|
if v > self.max_brightness: v = self.max_brightness |
||||||
|
elif v <= 0: v = 0 |
||||||
|
|
||||||
|
if not os.path.exists(self._brightness_path): return |
||||||
|
|
||||||
|
try: |
||||||
|
with open(self._brightness_path, "w") as f: |
||||||
|
f.write(str(round(v))) |
||||||
|
except OSError: |
||||||
|
logger.error("Couldn't write to \"" + self._brightness_path + "\"") |
||||||
|
|
||||||
|
@property |
||||||
|
def brightness(self) -> int: |
||||||
|
if not self._available: return -1 |
||||||
|
return round(self.real_brightness * 100 / self.max_brightness) |
||||||
|
|
||||||
|
@brightness.setter |
||||||
|
def brightness(self, v: int): |
||||||
|
self.real_brightness = round(v * self.max_brightness / 100) |
||||||
|
|
||||||
|
def _set_brightness(self, value: int): |
||||||
|
if not self._available: return |
||||||
|
steps = self.steps or 1 |
||||||
|
sleep = self.delay / steps |
||||||
|
current = self.brightness |
||||||
|
|
||||||
|
if steps <= 1: |
||||||
|
self.brightness = value |
||||||
|
return |
||||||
|
|
||||||
|
for i in range(steps + 1): |
||||||
|
time.sleep(sleep / 1000) |
||||||
|
brigh = current + ((value - current) * i) / steps |
||||||
|
self.brightness = round(brigh) |
||||||
|
|
||||||
|
def set_brightness(self, value: int): |
||||||
|
thread = Thread(target = self._set_brightness, args = (value,)) |
||||||
|
thread.start() |
||||||
|
|
||||||
|
def inc_brightness(self, value: int): |
||||||
|
self.set_brightness(self.brightness + value) |
||||||
|
|
||||||
|
def dec_brightness(self, value: int): |
||||||
|
self.set_brightness(self.brightness - value) |
Loading…
Reference in new issue