No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

brightness.py 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #!/usr/bin/env python
  2. import lux
  3. import ddc
  4. import influx
  5. import window
  6. import time
  7. import sys
  8. import select
  9. filter_fact = 0.90
  10. c_in = 0.6, -30.0, # in_a, in_b
  11. calibration = {
  12. "HPN:HP 27xq:CNK1072BJY": [
  13. 1.0, 10.0, # out_a, out_b
  14. ],
  15. "MSI:MSI G27CQ4:": [
  16. 1.0, 0.0, # out_a, out_b
  17. ],
  18. }
  19. running = True
  20. is_active = True
  21. last_brightness = 0
  22. def cal(v, c):
  23. # out = out_b + out_a * in_a * max(0, in_b + in)
  24. return c[1] + c[0] * c_in[0] * max(0, c_in[1] + v)
  25. def filter_lux(old, new):
  26. return max(0.1, (old * filter_fact) + (new * (1.0 - filter_fact)))
  27. def lux_to_disp(name, val):
  28. if name in calibration:
  29. val = cal(int(val), calibration[name])
  30. else:
  31. raise ValueError("no calibration for \"{}\"".format(name))
  32. val = int(val)
  33. return min(max(val, 0), 100)
  34. def main():
  35. global running, is_active, last_brightness
  36. print("usb init")
  37. usb = lux.usb_init()
  38. print("check usb connection")
  39. lux.check_connection(usb)
  40. print("detect displays")
  41. disps = ddc.ddc_detect()
  42. if len(disps) <= 0:
  43. raise ValueError("no displays found")
  44. print("query displays")
  45. for d in disps:
  46. # select i2c bus if available, id otherwise
  47. if "bus" in d:
  48. d["_id"] = d["bus"]
  49. else:
  50. d["_id"] = d["id"]
  51. # get initial value
  52. d["prev"] = ddc.ddc_get(d["_id"])
  53. print("Display \"{}\" ({}) at {}".format(d["name"], d["_id"], d["prev"]))
  54. brightness = lux.read_brightness(usb)
  55. print("Brightness:", brightness)
  56. last_brightness = brightness
  57. print()
  58. print("{}: Starting main loop".format(time.ctime()))
  59. print()
  60. time_brightness = time.time()
  61. time_displays = time.time() - 8.0
  62. time_window = time.time()
  63. is_active = True
  64. while running:
  65. # read brightness at approx. 1Hz with low-pass filtering
  66. time.sleep(1.0)
  67. brightness = filter_lux(brightness, lux.read_brightness(usb))
  68. if select.select([sys.stdin, ], [], [], 0.0)[0]:
  69. line = sys.stdin.readline()
  70. print("Resetting displays")
  71. for d in disps:
  72. try:
  73. ddc.ddc_set(d["_id"], d["prev"])
  74. except Exception as e:
  75. print(e)
  76. # print brightness changes at most every 5s
  77. if (time.time() - time_brightness) > 5.0:
  78. time_brightness = time.time()
  79. if int(brightness) != last_brightness:
  80. last_brightness = int(brightness)
  81. print("{}: Brightness: {}".format(time.ctime(), last_brightness))
  82. try:
  83. influx.write("brightness,location=pc-back", "lux", brightness)
  84. for d in disps:
  85. name = '_'.join(d["name"].split())
  86. influx.write("brightness,location=" + name, "backlight", d["prev"])
  87. except:
  88. pass
  89. # check for fullscreen windows every 20s
  90. if (time.time() - time_window) > 20.0:
  91. time_window = time.time()
  92. info = window.query()
  93. if info["fullscreen"] and is_active:
  94. print("{}: App \"{}\" is now fullscreen! Pausing.".format(time.ctime(), info["name"]))
  95. if (not info["fullscreen"]) and (not is_active):
  96. print("{}: No longer fullscreen. Continuing.".format(time.ctime()))
  97. # re-apply previous brightness values soon
  98. for d in disps:
  99. d["prev"] = -1
  100. is_active = not info["fullscreen"]
  101. # set displays at most every 10s
  102. if is_active and ((time.time() - time_displays) > 10.0):
  103. time_displays = time.time()
  104. for d in disps:
  105. val = lux_to_disp(d["name"], brightness)
  106. if val != d["prev"]:
  107. try:
  108. print("{}: Setting \"{}\" to {}".format(time.ctime(), d["name"], val))
  109. ddc.ddc_set(d["_id"], val)
  110. d["prev"] = val
  111. except Exception as e:
  112. print(e)
  113. # set to zero to show display is disconnected
  114. d["prev"] = -1
  115. if __name__ == "__main__":
  116. main()