| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- from enum import Enum, StrEnum
- # reads and writes RGB and brightness data for led background color of Clevo NL51 Laptops
- # ensure to compile drivers before ! read: https://wiki.siningsoft.de/doku.php?id=terra:1500p
- # Kernelmodul: tuxedo_keyboard
- # 2026-02-02 - devnull - initial
- # 2026-02-03 - devnull - added Brightness restore
- # 2026-02-04 - devnull - JSON statefile
- # 2026-02-11 - devnull - created class
- # 2026-02-18 - devnull - added logging
- # 2026-02-19 - devnull - added commandline arguments for changing
- # 2026-02-21 - devnull - color and brightness switching on commandline
- # 2026-02-21 - devnull - enable/disable LED via Commandline
- ver="1.4"
- import sys
- import argparse
- import json
- import logging
- # start with a logger object
- log = logging.getLogger(__name__)
- class kbdLED_class():
- # 2026-02-11 - devnull - added class definition
- # 2026-02-19 - devnull - bugfixed write procedure
- # - added hard coded colors
- class colors(StrEnum):
- GREEN = "0 255 0"
- WHITE = "255 255 255"
- RED = "255 0 0"
- BLUE = "0 0 255"
- YELLOW = "255 255 0"
- PURPLE = "255 0 255"
- LIGHTBLUE = "0 0 255"
- # d_GREEN = {"R":0,"G": 255,"B": 0}
- # d_WHITE = {"R":255,"G": 255,"B": 255}
- # d_RED = {"R":255,"G": 0,"B": 0}
- # d_BLUE = {"R":0,"G": 0,"B": 255}
- # d_YELLOW = {"R":255,"G": 255,"B": 0}
- # d_PURPLE = {"R":255,"G": 0,"B": 255}
- # d_LIGHTBLUE = {"R":0,"G": 255,"B": 255}
- # diese Versionsnummer wird getrennt vom Programmcode geführt, da es sich getrennt entwickeln wird
- __version__ = 1.1
- config = dict()
- # Objekt erzeugen
- def __init__(self, cmd,
- log,
- INcolor=colors.WHITE,
- INbrightness=255,
- kbd_state_fp='/var/lib/kbdLED.state.json',
- sysfs_color_fp='/sys/devices/platform/tuxedo_keyboard/leds/rgb:kbd_backlight/multi_intensity',
- sysfs_bri_fp='/sys/devices/platform/tuxedo_keyboard/leds/rgb:kbd_backlight/brightness'):
- self.log = log
- self.config = {"sysfs" :
- {
- "color" : sysfs_color_fp ,
- "bri" : sysfs_bri_fp
- },
- "state" : kbd_state_fp}
- self.log.debug(str(self.config))
- # startup and restore states
- if cmd=="start":
- self.readStateFile(self.config['state'])
- self.log.debug(str(self.config))
- self.writeColor()
- self.writeBrightness()
- # shutdown system and save last states
- elif cmd=="stop":
- self.readColor()
- self.readBrightness()
- self.writeStateFile(self.config['state'])
- # set the color from commandline
- elif cmd=="color":
- self.log.debug("INcolor=" + str(INcolor))
- self.color2dict2config(INcolor)
- self.log.debug("__init__(cmd=color).config['color']=" + str(self.config['color']))
- self.writeColor()
- # set the brightness from commandline
- elif cmd=="brightness":
- self.config['Brightness']= int(INbrightness)
- self.writeBrightness()
- def readStateFile(self,kbd_state_fp):
- config = {"color":
- {"R": 255,
- "G": 255,
- "B": 255},
- "Brightness": 255
- }
- try:
- with open(kbd_state_fp, 'r') as kbd_state_fh:
- self.config = json.load(kbd_state_fh)
- except FileNotFoundError:
- self.log.error("keine Statusdatei gefunden, nutze Standardwerte")
- except PermissionError:
- self.log.error("Fehler beim lesen")
- def writeStateFile(self,kbd_state_fp):
- try:
- with open(kbd_state_fp, 'w') as kbd_state_fh:
- json.dump(self.config,kbd_state_fh)
- except FileNotFoundError:
- self.log.error("Verzeichnis oder Datei nicht gefunden")
- # color String nach Config Dict
- def color2dict2config(self, color_string):
- ca=color_string.split(" ")
- self.log.debug("color_string=" + color_string)
- self.log.debug("after splitting=" + str(ca))
- self.config['color'] = {"R": int(ca[0]),
- "G": int(ca[1]),
- "B": int(ca[2])}
- # color Confi Dict nach String
- def config2dict2color(self):
- return str(self.config['color']['R']) + " " + str(self.config['color']['G']) + " " + str(self.config['color']['B'])
- # reads the color Values from sysfs
- def readColor(self):
- try:
- with open(self.config['sysfs']['color']) as fh:
- self.color2dict2config(fh.read())
- except FileNotFoundError:
- self.log.error("fehler beim Öffnen der Sysfs Datei " + self.config['sysfs']['color'])
- sys.exit(1)
- except PermissionError:
- self.log.error("keine Rechte die Datei zu lesen " + self.config['sysfs']['color'])
- sys.exit(1)
- # writes the color values to sysfs
- def writeColor(self):
- try:
- #with open(self.config['sysfs']['color']) as fh:
- # fh.write(self.dict2color())
- fh = open(self.config['sysfs']['color'], 'w')
- fh.write(self.config2dict2color())
- fh.close()
- except FileNotFoundError:
- self.log.error("fehler beim Schreiben der Sysfs Datei " + self.config['sysfs']['color'])
- sys.exit(1)
- except PermissionError:
- self.log.error("keine Rechte die Datei zu schreiben " + self.config['sysfs']['color'])
- sys.exit(1)
- # reads Brightness from sysfs
- def readBrightness(self):
- try:
- with open(self.config['sysfs']['bri']) as fh:
- self.config['Brightness'] = int(fh.read())
- except FileNotFoundError:
- self.log.error("fehler beim Öffnen der Sysfs Datei " + self.config['sysfs']['bri'])
- sys.exit(1)
- except PermissionError:
- self.log.error("keine Rechte die Datei zu lesen " + self.config['sysfs']['bri'])
- sys.exit(1)
- # writes Brightness to sysfs
- def writeBrightness(self):
- try:
- #with open(self.config['sysfs']['bri']) as fh:
- # fh.write(self.config['Brightness'])
- fh = open(self.config['sysfs']['bri'], 'w')
- fh.write(str(self.config['Brightness']))
- fh.close()
- except FileNotFoundError:
- self.log.error("- fehler beim Schreiben der Sysfs Datei " + self.config['sysfs']['bri'])
- sys.exit(1)
- except PermissionError:
- self.log.error("- keine Rechte die Datei zu schreiben " + self.config['sysfs']['bri'])
- sys.exit(1)
- # Press the green button in the gutter to run the script.
- # noinspection aK
- if __name__ == '__main__':
- #https: // argparse.readthedocs.io
- # internal note: um mehrere sich ausschließende Argumente zuzulassen, muss add_mutually_exclusive_groups verwenden
- parser = argparse.ArgumentParser(
- prog='T1500_KeyboardLED',
- description='saves and restore LED Colors',
- epilog='GPL')
- group_common = parser.add_argument_group("common")
- output = group_common.add_mutually_exclusive_group(required=False)
- output.add_argument('--verbose', action='store_true', help='extended logging', required=False)
- output.add_argument('--debug', action='store_true', help='debug output', required=False)
- group_function = parser.add_argument_group("function")
- startstop = group_function.add_mutually_exclusive_group()
- startstop.add_argument('--on', action='store_true', help='generally turn LED Backlight on')
- startstop.add_argument('--off', action='store_true', help='generally turn LED Backlight off')
- startstop.add_argument('--start', action='store_true', help='will be used for system starts')
- startstop.add_argument('--stop', action='store_true', help='will be used for system shutdowns')
- startstop.add_argument('-c', '--color', choices=['white','blue','lightblue','green','red','purple','yellow'], help='keyboard color out of fixed feature set', required=False)
- startstop.add_argument('-b', '--brightness', type=int, help='keybpoard brightness between 0..255', required=False)
- startstop.add_argument('--version', action='version', version='%(prog)s ' + ver, default='d')
- args = parser.parse_args()
- if args.verbose:
- log.setLevel(logging.INFO)
- elif args.debug:
- log.setLevel(logging.DEBUG)
- else:
- log.setLevel(logging.ERROR)
- logging.basicConfig(format='%(asctime)s %(message)s')
- if args.start:
- print("Keyboard: read and set Color and Brightness")
- log.debug("System start")
- kL = kbdLED_class("start", log)
- elif args.stop:
- print("Keyboard: read and save Color and Brightness")
- log.debug("System stop")
- kL = kbdLED_class("stop", log)
- elif args.color:
- print("Keyboard: set color " + args.color)
- log.debug("resolveed Color=" + getattr(kbdLED_class.colors,args.color.upper()))
- try:
- log.debug("setup keyboard color " + args.color)
- kL = kbdLED_class("color", log, INcolor=getattr(kbdLED_class.colors, args.color.upper()))
- except AttributeError:
- log.error("color does not exists " + args.color)
- parser.print_help()
- sys.exit((1))
- elif args.brightness:
- print("Keyboard: set brightness " + str(args.brightness))
- log.debug("setup keyboard brightness " + str(args.brightness))
- kL = kbdLED_class("brightness",log, INbrightness=args.brightness)
- elif args.on:
- print("Keyboard: enable Backlight LED")
- kL = kbdLED_class("brightness",log, INbrightness=255)
- elif args.off:
- print("Keyboard: disable Backlight LED")
- kL = kbdLED_class("brightness", log, INbrightness=0)
- else:
- parser.print_help()
- sys.exit((10))
- sys.exit(0)
|