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 3.6KB

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