switch off display via xorg.xset

Hendrik Sokolowski 2024-04-10 22:04:01 +02:00
parent 0d085862db
commit 240b9d6ec2
Signed by: hensoko
GPG Key ID: 5C36A01B80BCCC59
4 changed files with 43 additions and 22 deletions

View File

@ -13,7 +13,8 @@
version = "0.0.1";
src = ./src;
propagatedBuildInputs = with pkgs.python311Packages; [
pkgs.brightnessctl
pkgs.light
pkgs.xorg.xset
coloredlogs
configargparse
@ -26,7 +27,8 @@
devShells.default = pkgs.mkShell {
name = "development shell";
nativeBuildInputs = with pkgs.python311Packages; [
pkgs.brightnessctl
pkgs.light
pkgs.xorg.xset
coloredlogs
configargparse

View File

@ -24,11 +24,14 @@ class DisplayBrightnessManager():
brightness_level = BrightnessLevel.LEVEL_BRIGHT
mqtt_entity = None
display_device = None
display_switched_off = False
touch_device = None
logger = None
def __init__(self, device, touch_device, logger: logging.Logger):
def __init__(self, device, display_device, touch_device, logger: logging.Logger):
self.logger = logger
self.display_device = display_device
self.touch_device = self.get_touch_device(touch_device)
force_display_on_info = ha_mqtt_discoverable.sensors.SwitchInfo(
@ -74,6 +77,17 @@ class DisplayBrightnessManager():
self.brightness_mode_new = mode
logging.info(f'brightness mode: {self.brightness_mode}, new mode: {self.brightness_mode_new}')
async def switch_display_on(self):
self.logger.info('switching screen on')
self.display_switched_off = False
await asyncio.create_subprocess_exec('xset', '-display', self.display_device, 'dpms', 'force', 'on')
async def switch_display_off(self):
self.logger.info('switching screen off')
self.display_switched_off = True
await asyncio.create_subprocess_exec('xset', '-display', self.display_device, 'dpms', 'force', 'off')
async def input_device_loop(self):
async for ev in self.touch_device.async_read_loop():
now = time.time()
@ -89,17 +103,26 @@ class DisplayBrightnessManager():
elif self.brightness_level == BrightnessLevel.LEVEL_BRIGHT:
from_value = 50
step_val=(to_value-from_value)/25
for i in range(1, 25):
if to_value != 0 and self.display_switched_off:
await self.switch_display_on()
self.logger.info(f'dimming screen from {from_value} to {to_value}')
step_val=(to_value-from_value)/20
for i in range(1, 20):
new_val = "{:.0f}".format(from_value + i*step_val)
await asyncio.create_subprocess_exec('brightnessctl', 'set', f'{new_val}%', stdout=asyncio.subprocess.DEVNULL, stderr=asyncio.subprocess.DEVNULL)
self.logger.info(f'dimming to value {new_val}')
await asyncio.create_subprocess_exec('light', '-S', f'{new_val}%', stdout=asyncio.subprocess.DEVNULL, stderr=asyncio.subprocess.DEVNULL)
#await asyncio.create_subprocess_exec('brightnessctl', 'set', f'{new_val}%', stdout=asyncio.subprocess.DEVNULL, stderr=asyncio.subprocess.DEVNULL)
await asyncio.sleep(0.005)
if to_value == 0:
await self.switch_display_off()
async def brightness_loop(self):
self.logger.info('starting brightness loop')
while True:
if self.brightness_mode != self.brightness_mode_new:
self.logger.info(f'brightness mode changede to {self.brightness_mode_new}')
self.logger.info(f'brightness mode changed to {self.brightness_mode_new}')
if self.brightness_mode_new == BrightnessMode.MODE_MAN:
await self.dim_screen(50)
self.brightness_level = BrightnessLevel.LEVEL_BRIGHT
@ -108,6 +131,7 @@ class DisplayBrightnessManager():
self.brightness_mode = self.brightness_mode_new
if self.brightness_mode == BrightnessMode.MODE_AUTO:
self.logger.debug(f'brightness loop begin: {self.last_input}, {time.time()}')
if self.last_input + 30 < time.time():
if self.brightness_level != BrightnessLevel.LEVEL_OFF:
await self.dim_screen(0)

View File

@ -30,6 +30,7 @@ async def main():
parser.add_argument("--mqtt-port", dest='mqtt_port', default=os.environ.get('MQTT_PORT', 1883))
parser.add_argument("--mqtt-user", dest='mqtt_user', default=os.environ.get('MQTT_USER'))
parser.add_argument("--mqtt-pass", dest='mqtt_pass', default=os.environ.get('MQTT_PASS'))
parser.add_argument("--touch-device", dest='touch_device', default=os.environ.get('TOUCH_DEVICE'))
args = parser.parse_args()
@ -63,8 +64,8 @@ async def main():
tasks = []
if args.display_device:
dbm = DisplayBrightnessManager(device, args.display_device, logger)
if args.display_device and args.touch_device:
dbm = DisplayBrightnessManager(device, args.display_device, args.touch_device, logger)
tasks.append(dbm.run())
tasks.append(sensor_loop(logger, sensor_entities))
@ -73,4 +74,4 @@ async def main():
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
asyncio.run(main())

View File

@ -80,35 +80,29 @@ class DisplayBrightnessSensor():
self.mqtt_sensor.set_availability(True)
def update_value(self):
res = subprocess.run(['brightnessctl', '-m', 'info'], capture_output=True)
res = subprocess.run(['light', '-G'], capture_output=True)
if res.returncode != 0:
logger.warn(f'failed to get brightness: exit code { res.returncode }')
return
stdout = res.stdout.decode("utf-8")
brightPerc = float(stdout.split(',')[3].split('%')[0])
brightPerc = res.stdout.decode("utf-8")
if brightPerc != self.value:
self.mqtt_sensor.set_value(brightPerc)
self.value = brightPerc
def set_display_brightness(self, number: float) -> float:
res = subprocess.run(['brightnessctl', '-m', 'set', f'{ number }%'], capture_output=True)
def set_display_brightness(self, number: float):
res = subprocess.run(['light', '-S', f'{ number }%'])
if res.returncode != 0:
logger.warn(f'failed to set brightness: exit code { res.returncode }')
return -1
stdout = res.stdout.decode("utf-8")
brightPerc = float(stdout.split(',')[3].split('%')[0])
return brightPerc
# To receive number updates from HA, define a callback function:
def display_brightness_callback(self, client: Client, user_data, message: MQTTMessage):
number = int(message.payload.decode())
logging.info(f"received new value {number} for display brightness")
new_brightness = self.set_display_brightness(number)
self.mqtt_sensor.set_value(new_brightness)
self.set_display_brightness(number)
self.mqtt_sensor.set_value(number)
class IPAddressSensor():