89
89
--dbus-signals|--no-dbus-signals
90
90
enable D-Bus ddcutil-service VDU-connectivity-change signals
91
91
``--dbus-signals`` is the default
92
+ --protect-nvram|--no-protect-nvram
93
+ alter options and defaults to minimize VDU NVRAM writes
92
94
--create-config-files
93
95
if they do not exist, create template config INI files
94
96
in $HOME/.config/vdu_controls/
811
813
QSplashScreen , QPushButton , QProgressBar , QComboBox , QSystemTrayIcon , QMenu , QStyle , QTextEdit , QDialog , QTabWidget , \
812
814
QCheckBox , QPlainTextEdit , QGridLayout , QSizePolicy , QAction , QMainWindow , QToolBar , QToolButton , QFileDialog , \
813
815
QWidgetItem , QScrollArea , QGroupBox , QFrame , QSplitter , QSpinBox , QDoubleSpinBox , QInputDialog , QStatusBar , qApp , QShortcut , \
814
- QDesktopWidget
816
+ QDesktopWidget , QSpacerItem
815
817
816
818
APPNAME = "VDU Controls"
817
819
VDU_CONTROLS_VERSION = '2.1.0'
@@ -2016,6 +2018,7 @@ def mousePressEvent(self, event):
2016
2018
'60' : VcpCapability ('60' , QT_TR_NOOP ('input source' ), SNC , causes_config_change = True ),
2017
2019
'D6' : VcpCapability ('D6' , QT_TR_NOOP ('power mode' ), SNC , causes_config_change = True ),
2018
2020
'CC' : VcpCapability ('CC' , QT_TR_NOOP ('OSD language' ), SNC ),
2021
+ '14' : VcpCapability ('14' , QT_TR_NOOP ('color preset' ), SNC ),
2019
2022
'0C' : VcpCapability ('0C' , QT_TR_NOOP ('color temperature' ), CON , icon_source = COLOR_TEMPERATURE_SVG , enabled = True ),
2020
2023
}}
2021
2024
@@ -2187,7 +2190,7 @@ class ConfOption(Enum): # TODO Enum is used for convenience for scope/iteration
2187
2190
conf_type = CI .TYPE_LONG_TEXT , cmdline_arg = 'DISALLOWED' ,
2188
2191
tip = QT_TR_NOOP ('override/cache for ddcutil capabilities text' ))
2189
2192
PROTECT_NVRAM_ENABLED = conf_opt_def (cname = QT_TR_NOOP ('protect-nvram' ), default = "yes" , restart = True ,
2190
- tip = QT_TR_NOOP ('alter options and defaults to maximise VDU NVRAM lifespan ' ))
2193
+ tip = QT_TR_NOOP ('alter options and defaults to minimize VDU NVRAM writes ' ))
2191
2194
UNKNOWN = conf_opt_def (cname = "UNKNOWN" , section = CI .UNKNOWN_SECTION , conf_type = CI .TYPE_BOOL , cmdline_arg = 'DISALLOWED' , tip = '' )
2192
2195
2193
2196
def __init__ (self , conf_name : str , section : str , cmdline_arg : str , conf_type : str , default : str | None ,
@@ -4568,7 +4571,7 @@ def update_location(self, location: GeoLocation) -> None:
4568
4571
4569
4572
class PresetChooseTransitionWidget (QWidget ):
4570
4573
4571
- def __init__ (self , protect_nvram : bool ) -> None :
4574
+ def __init__ (self ) -> None :
4572
4575
super ().__init__ ()
4573
4576
layout = QHBoxLayout ()
4574
4577
self .setLayout (layout )
@@ -4577,7 +4580,6 @@ def __init__(self, protect_nvram: bool) -> None:
4577
4580
self .button_menu = QMenu ()
4578
4581
self .transition_type = PresetTransitionFlag .NONE
4579
4582
self .is_setting = False
4580
- self .protect_nvram = protect_nvram
4581
4583
4582
4584
for transition_type in PresetTransitionFlag .ALWAYS .component_values ():
4583
4585
action = QAction (transition_type .description (), self .button_menu )
@@ -4598,12 +4600,10 @@ def __init__(self, protect_nvram: bool) -> None:
4598
4600
def update_value (self , checked : bool ) -> None :
4599
4601
if self .is_setting :
4600
4602
return
4601
- if checked and self . protect_nvram :
4603
+ if checked :
4602
4604
alert = MessageBox (QMessageBox .Warning )
4603
- alert .setText (tr ('Transtions have been deprecated to protect VDU NVRAM.' ))
4604
- alert .setInformativeText ('Setting this transition will have no effect '
4605
- 'until protect-nvram is disabled in the Settings-Dialog.\n \n '
4606
- 'Transitions are slated for removal, please '
4605
+ alert .setText (tr ('Transitions have been deprecated to minimize wear on VDU NVRAM.' ))
4606
+ alert .setInformativeText ('Transitions are slated for removal, please '
4607
4607
'contact the developer if you wish to retain them.' )
4608
4608
alert .exec ()
4609
4609
for act in self .button_menu .actions ():
@@ -5109,8 +5109,11 @@ def __init__(self, main_controller: VduAppController, main_config: VduControlsCo
5109
5109
self .editor_layout .addWidget (self .controls_title_widget )
5110
5110
self .editor_layout .addWidget (self .editor_controls_widget )
5111
5111
5112
- self .editor_transitions_widget = PresetChooseTransitionWidget (self .main_config .is_set (ConfOption .PROTECT_NVRAM_ENABLED ))
5113
- self .editor_layout .addWidget (self .editor_transitions_widget )
5112
+ self .editor_transitions_widget = PresetChooseTransitionWidget ()
5113
+ if self .main_config .is_set (ConfOption .PROTECT_NVRAM_ENABLED ):
5114
+ self .editor_layout .addItem (QSpacerItem (1 ,10 ))
5115
+ else :
5116
+ self .editor_layout .addWidget (self .editor_transitions_widget )
5114
5117
5115
5118
self .editor_trigger_widget = PresetChooseElevationWidget (self .main_config )
5116
5119
self .editor_layout .addWidget (self .editor_trigger_widget )
@@ -6203,7 +6206,7 @@ class LuxAutoWorker(WorkerThread): # Why is this so complicated?
6203
6206
6204
6207
_lux_dialog_message_qtsignal = pyqtSignal (str , int , MsgDestination )
6205
6208
6206
- def __init__ (self , auto_controller : LuxAutoController , single_shot : bool = False ) -> None :
6209
+ def __init__ (self , auto_controller : LuxAutoController , single_shot : bool = False , protect_nvram : bool = True ) -> None :
6207
6210
super ().__init__ (task_body = self ._adjust_for_lux , task_finished = self ._adjust_for_lux_finished )
6208
6211
self .single_shot = single_shot # Called for an on-demand single time assessment with immediate effect.
6209
6212
self .main_controller = auto_controller .main_controller
@@ -6228,7 +6231,12 @@ def get_prop(prop: str, fallback: bool | int | float | str) -> bool | int | floa
6228
6231
self .sensitivity_percent = get_prop ('interpolation-sensitivity-percent' , fallback = 10 )
6229
6232
self .convergence_divisor = get_prop ('convergence-divisor' , fallback = 2 )
6230
6233
self .step_pause_millis = get_prop ('step-pause-millis' , fallback = 100 )
6231
- self .max_brightness_jump = get_prop ('max-brightness-jump' , fallback = 100 )
6234
+ if protect_nvram :
6235
+ log_info ("LuxAutoWorker: protect-nvram enabled, ignoring max-brightness-jump" )
6236
+ self .max_brightness_jump = 100
6237
+ else :
6238
+ self .max_brightness_jump = get_prop ('max-brightness-jump' , 20 )
6239
+ log_warning (f"LuxAutoWorker: protect-nvram={ protect_nvram } max-brightness-jump={ self .max_brightness_jump } " )
6232
6240
self ._lux_dialog_message_qtsignal .connect (LuxDialog .lux_dialog_message )
6233
6241
self ._lux_dialog_message_qtsignal .connect (self .main_controller .main_window .status_message )
6234
6242
self .status_message (f"{ TIMER_RUNNING_SYMBOL } 00:00" , 0 , MsgDestination .COUNTDOWN )
@@ -6279,6 +6287,7 @@ def stepping_brightness(self, lux_config: LuxConfig, lux_meter: LuxMeterDevice)
6279
6287
change_count , last_change_count = 0 , - 1
6280
6288
start_of_cycle = True
6281
6289
profile_preset_name = None
6290
+ vdu_changes_count = {}
6282
6291
while change_count != last_change_count : # while brightness changing
6283
6292
last_change_count = change_count
6284
6293
if metered_lux := lux_meter .get_value ():
@@ -6297,10 +6306,12 @@ def stepping_brightness(self, lux_config: LuxConfig, lux_meter: LuxMeterDevice)
6297
6306
profile_brightness , profile_preset_name = self .determine_brightness (vdu_sid , smoothed_lux , lux_profile )
6298
6307
if self .step_one_vdu (vdu_sid , profile_brightness , profile_preset_name , lux_summary_text , start_of_cycle ):
6299
6308
change_count += 1
6309
+ vdu_changes_count [vdu_sid ] = vdu_changes_count .get (vdu_sid , 0 ) + 1
6310
+ else :
6311
+ log_debug (f"LuxAutoWorker: finished { vdu_sid = } VCP-changes={ vdu_changes_count .get (vdu_sid , 0 )} )" )
6300
6312
start_of_cycle = False
6301
6313
self .doze (self .step_pause_millis / 1000.0 ) # Let i2c settle down, then continue - TODO is this really necessary?
6302
6314
if change_count != 0 : # If any work was done in previous steps, finish up the remaining tasks
6303
- log_info (f"LuxAutoWorker: stepping completed { change_count } VCP-changes, { profile_preset_name = } " )
6304
6315
self .status_message (tr ("Brightness adjustment completed" ), timeout = 5000 )
6305
6316
if profile_preset_name is not None : # if a point had a Preset attached, activate it now
6306
6317
# Restoring the Preset's non-brightness settings. Invoke now, so it will happen in this thread's sleep period.
@@ -6311,6 +6322,7 @@ def stepping_brightness(self, lux_config: LuxConfig, lux_meter: LuxMeterDevice)
6311
6322
scheduled_activity = True )
6312
6323
else : # No work done, no adjustment necessary
6313
6324
self .status_message (f"{ SUN_SYMBOL } { SUCCESS_SYMBOL } " , timeout = 3000 )
6325
+ log_info (f"LuxAutoWorker: adjustments completed { change_count } VCP-changes, { profile_preset_name = } " )
6314
6326
6315
6327
def step_one_vdu (self , vdu_sid : VduStableId , profile_brightness : int , profile_preset_name : str | None ,
6316
6328
lux_summary_text : str , first_step : bool ) -> bool :
0 commit comments