Skip to content

Commit face6a2

Browse files
committed
#93 deprecate/hide transitions.
1 parent e3174c4 commit face6a2

File tree

2 files changed

+45
-29
lines changed

2 files changed

+45
-29
lines changed

README.md

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ others). The UI attempts to adapt to the quirks of the different tray implementa
7676
Named ``Preset`` configurations can be saved for later recall. For example, a user could create
7777
presets for night, day, photography, movies, and so forth. Presets may be automatically triggered
7878
according to solar elevation, and can be further constrained by local weather conditions (as
79-
reported by [https://wttr.in](https://wttr.in)). Presets can be set to transition immediately or
80-
gradually. Presets may also be activated by UNIX signals.
79+
reported by [https://wttr.in](https://wttr.in)). Presets may also be activated by UNIX signals.
8180

8281
From any application window, use `F1` to access help, and `F10` to access the context-menu. The
8382
context menu is also available via the right-mouse button in the main-window, the hamburger-menu item
@@ -103,10 +102,10 @@ Repeatably altering VDU settings might affect VDU lifespan. Possible reasons
103102
include the consumption of NVRAM write cycles, stressing the VDU power-supply,
104103
or increasing the LED panel burn-in.
105104

106-
I have a VDU manufactured in 2010 that allows settings to be adjusted, but
107-
reverts to factory defaults whenever it loses power. This VDU was used intensively
108-
for testing vdu_controls over the past four years. This gives credence to the
109-
possibility of exhausting VDU NVRAM, at least in VDUs of that vintage.
105+
In respect to exhausting NVRAM, I can confirm that a vintage-2010 VDU used for
106+
testing vdu_controls now reverts to factory defaults whenever it loses power.
107+
This is after four years of use in development testing. I've subsequently
108+
implemented the ___initialization-preset___ feature to work around the issue.
110109

111110
All that said, ``vdu_controls`` does include a number of features that can be used
112111
to reduce the frequency of writes to VDU NVRAM:
@@ -115,14 +114,15 @@ to reduce the frequency of writes to VDU NVRAM:
115114

116115
+ Slider and spin-box controls only update the VDU when adjustments become slow or stop (when no change occurs in 0.5 seconds).
117116
+ Preset restoration only updates the VDU values that differ from its current values.
118-
+ Transitioning smoothly has been disabled by default and deprecated for version 2.1.0 onward.
117+
+ Transitioning effects and transition controls have been disabled by default and are
118+
deprecated for version 2.1.0 onward.
119119
+ Automatic ambient brightness adjustment only triggers a change when the proposed brightness differs from the current brightness by at least 10%.
120120

121121
#### Electable mitigations:
122122

123123
+ Choose to restore pre-prepared ‘presets’ instead of dragging sliders.
124124
+ Refrain from adding transitions to presets.
125-
+ If using the ambient-light brightness response curves, tune the settings and curves to minimise frequent small changes.
125+
+ If using the ambient-light brightness response curves, tune the settings and curves to avoid frequent small changes.
126126
+ If using a light-meter, disengage metered automatic adjustment when faced with rapidly fluctuating levels of ambient brightness.
127127
+ Consider adjusting the ambient lighting instead of the VDU.
128128

@@ -329,18 +329,22 @@ Michael Hamilton
329329
Version History
330330
---------------
331331
* 2.1.0
332-
* Preset _smooth transitions_ have been deprecated. All presets are now restored instantly no
333-
matter how they have been set to transition. The deprecated smooth-transitions can be
334-
re-enabled by disabling `protect-nvram` in ___Settings___. Unless objections are forthcoming,
335-
preset transition related settings will be removed in a future version.
336-
* Preset restoration now includes additional checks to avoid unnecessarily setting VCP values when
337-
they already the same as those in VDU.
332+
* Preset _transitions_ have been deprecated. All presets are now restored instantly no
333+
matter how they have been set to transition. The Preset-Dialog controls for assiging
334+
transitions have been hidden. Transitions and related controls can be
335+
re-enabled by disabling `protect-nvram` in the _Settings-Dialog_. __All
336+
transition related code may be removed in a future version, please contact me
337+
or comment on issue #93 if you prefer transitions to be retained.__
338+
* To avoid unecessary updates, preset restoration always queries the VDU's existing
339+
values. This may slow down preset restoration.
338340
* Lux-metered auto adjustment has been defaulted to 10 minute intervals (up from 5).
341+
* Color-Preset (VCP code 0x14) has been added to the list of standard controls.
339342
* Added VDU a ___Initializer-Preset___ feature to provide a replacement for dead NVRAM and
340343
a way to restore settings not persisted in VDU NVRAM. A VDU's initializer-preset is
341344
automatically run if the target VDU is present at startup or is subsequently detected.
342345
* The ___Preset-Dialog___ now includes a tool-button to the right of the preset-name entry
343-
that will create VDU specific ___Initializer-Preset___.
346+
that will create VDU specific ___Initializer-Preset___.
347+
344348
345349
* 2.0.4
346350
* The About-Dialog now refreshes the ddcutil version info on each invocation.

vdu_controls.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@
8989
--dbus-signals|--no-dbus-signals
9090
enable D-Bus ddcutil-service VDU-connectivity-change signals
9191
``--dbus-signals`` is the default
92+
--protect-nvram|--no-protect-nvram
93+
alter options and defaults to minimize VDU NVRAM writes
9294
--create-config-files
9395
if they do not exist, create template config INI files
9496
in $HOME/.config/vdu_controls/
@@ -811,7 +813,7 @@
811813
QSplashScreen, QPushButton, QProgressBar, QComboBox, QSystemTrayIcon, QMenu, QStyle, QTextEdit, QDialog, QTabWidget, \
812814
QCheckBox, QPlainTextEdit, QGridLayout, QSizePolicy, QAction, QMainWindow, QToolBar, QToolButton, QFileDialog, \
813815
QWidgetItem, QScrollArea, QGroupBox, QFrame, QSplitter, QSpinBox, QDoubleSpinBox, QInputDialog, QStatusBar, qApp, QShortcut, \
814-
QDesktopWidget
816+
QDesktopWidget, QSpacerItem
815817

816818
APPNAME = "VDU Controls"
817819
VDU_CONTROLS_VERSION = '2.1.0'
@@ -2016,6 +2018,7 @@ def mousePressEvent(self, event):
20162018
'60': VcpCapability('60', QT_TR_NOOP('input source'), SNC, causes_config_change=True),
20172019
'D6': VcpCapability('D6', QT_TR_NOOP('power mode'), SNC, causes_config_change=True),
20182020
'CC': VcpCapability('CC', QT_TR_NOOP('OSD language'), SNC),
2021+
'14': VcpCapability('14', QT_TR_NOOP('color preset'), SNC),
20192022
'0C': VcpCapability('0C', QT_TR_NOOP('color temperature'), CON, icon_source=COLOR_TEMPERATURE_SVG, enabled=True),
20202023
}}
20212024

@@ -2187,7 +2190,7 @@ class ConfOption(Enum): # TODO Enum is used for convenience for scope/iteration
21872190
conf_type=CI.TYPE_LONG_TEXT, cmdline_arg='DISALLOWED',
21882191
tip=QT_TR_NOOP('override/cache for ddcutil capabilities text'))
21892192
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'))
21912194
UNKNOWN = conf_opt_def(cname="UNKNOWN", section=CI.UNKNOWN_SECTION, conf_type=CI.TYPE_BOOL, cmdline_arg='DISALLOWED', tip='')
21922195

21932196
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:
45684571

45694572
class PresetChooseTransitionWidget(QWidget):
45704573

4571-
def __init__(self, protect_nvram: bool) -> None:
4574+
def __init__(self) -> None:
45724575
super().__init__()
45734576
layout = QHBoxLayout()
45744577
self.setLayout(layout)
@@ -4577,7 +4580,6 @@ def __init__(self, protect_nvram: bool) -> None:
45774580
self.button_menu = QMenu()
45784581
self.transition_type = PresetTransitionFlag.NONE
45794582
self.is_setting = False
4580-
self.protect_nvram = protect_nvram
45814583

45824584
for transition_type in PresetTransitionFlag.ALWAYS.component_values():
45834585
action = QAction(transition_type.description(), self.button_menu)
@@ -4598,12 +4600,10 @@ def __init__(self, protect_nvram: bool) -> None:
45984600
def update_value(self, checked: bool) -> None:
45994601
if self.is_setting:
46004602
return
4601-
if checked and self.protect_nvram:
4603+
if checked:
46024604
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 '
46074607
'contact the developer if you wish to retain them.')
46084608
alert.exec()
46094609
for act in self.button_menu.actions():
@@ -5109,8 +5109,11 @@ def __init__(self, main_controller: VduAppController, main_config: VduControlsCo
51095109
self.editor_layout.addWidget(self.controls_title_widget)
51105110
self.editor_layout.addWidget(self.editor_controls_widget)
51115111

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)
51145117

51155118
self.editor_trigger_widget = PresetChooseElevationWidget(self.main_config)
51165119
self.editor_layout.addWidget(self.editor_trigger_widget)
@@ -6203,7 +6206,7 @@ class LuxAutoWorker(WorkerThread): # Why is this so complicated?
62036206

62046207
_lux_dialog_message_qtsignal = pyqtSignal(str, int, MsgDestination)
62056208

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:
62076210
super().__init__(task_body=self._adjust_for_lux, task_finished=self._adjust_for_lux_finished)
62086211
self.single_shot = single_shot # Called for an on-demand single time assessment with immediate effect.
62096212
self.main_controller = auto_controller.main_controller
@@ -6228,7 +6231,12 @@ def get_prop(prop: str, fallback: bool | int | float | str) -> bool | int | floa
62286231
self.sensitivity_percent = get_prop('interpolation-sensitivity-percent', fallback=10)
62296232
self.convergence_divisor = get_prop('convergence-divisor', fallback=2)
62306233
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}")
62326240
self._lux_dialog_message_qtsignal.connect(LuxDialog.lux_dialog_message)
62336241
self._lux_dialog_message_qtsignal.connect(self.main_controller.main_window.status_message)
62346242
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)
62796287
change_count, last_change_count = 0, -1
62806288
start_of_cycle = True
62816289
profile_preset_name = None
6290+
vdu_changes_count = {}
62826291
while change_count != last_change_count: # while brightness changing
62836292
last_change_count = change_count
62846293
if metered_lux := lux_meter.get_value():
@@ -6297,10 +6306,12 @@ def stepping_brightness(self, lux_config: LuxConfig, lux_meter: LuxMeterDevice)
62976306
profile_brightness, profile_preset_name = self.determine_brightness(vdu_sid, smoothed_lux, lux_profile)
62986307
if self.step_one_vdu(vdu_sid, profile_brightness, profile_preset_name, lux_summary_text, start_of_cycle):
62996308
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)})")
63006312
start_of_cycle = False
63016313
self.doze(self.step_pause_millis / 1000.0) # Let i2c settle down, then continue - TODO is this really necessary?
63026314
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=}")
63046315
self.status_message(tr("Brightness adjustment completed"), timeout=5000)
63056316
if profile_preset_name is not None: # if a point had a Preset attached, activate it now
63066317
# 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)
63116322
scheduled_activity=True)
63126323
else: # No work done, no adjustment necessary
63136324
self.status_message(f"{SUN_SYMBOL} {SUCCESS_SYMBOL}", timeout=3000)
6325+
log_info(f"LuxAutoWorker: adjustments completed {change_count} VCP-changes, {profile_preset_name=}")
63146326

63156327
def step_one_vdu(self, vdu_sid: VduStableId, profile_brightness: int, profile_preset_name: str | None,
63166328
lux_summary_text: str, first_step: bool) -> bool:

0 commit comments

Comments
 (0)