Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 108 additions & 9 deletions s_tui/s_tui.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,62 @@ def on_unicode_checkbox(self, w=None, state=False):

self.show_graphs()

def on_fahrenheit_checkbox(self, w=None, state=False):
"""Enable temperature logs in fahrenheit"""
logging.debug("Fahrenheit State is %s", state)

self.controller.fahrenheit = state

# Rebuild the Temp source with the new unit and refresh Temp graph/summary
try:
new_temp_source = self.controller.rebuild_temp_source()

# Recreate Temp graph with updated measurement unit
source_name = new_temp_source.get_source_name()
color_pallet = new_temp_source.get_pallet()
alert_pallet = new_temp_source.get_alert_pallet()

self.graphs[source_name] = BarGraphVector(
new_temp_source,
color_pallet,
len(new_temp_source.get_sensor_list()),
self.graphs_menu.active_sensors[source_name],
alert_colors=alert_pallet,
)

if self.controller.script_hooks_enabled:
self.graphs[source_name].source.add_edge_hook(
self.controller.script_loader.load_script(
new_temp_source.__class__.__name__, HOOK_INTERVAL
)
)

# Recreate Temp summary with the new source
self.summaries[source_name] = SummaryTextList(
self.graphs[source_name].source,
self.summary_menu.active_sensors[source_name],
)

# Ensure visible summaries map uses the updated summary widget
if source_name in self.visible_summaries:
self.visible_summaries[source_name] = self.summaries[source_name]

# Update visibility based on current selection
if any(self.graphs_menu.active_sensors[source_name]):
self.visible_graphs[source_name] = self.graphs[source_name]
elif source_name in self.visible_graphs:
del self.visible_graphs[source_name]

# Refresh UI elements: graphs and summaries block
self.show_graphs()
self.main_window_w.base_widget[0].body[
self.summary_widget_index
] = self._generate_summaries()

except Exception:
# Fail silently to avoid crashing UI; logging for debugging
logging.exception("Failed to rebuild Temp source after Fahrenheit toggle")

def on_save_settings(self, w=None):
"""Calls controller save settings method"""
self.controller.save_settings()
Expand Down Expand Up @@ -458,6 +514,14 @@ def _generate_graph_controls(self):
else:
unicode_checkbox = urwid.Text("[N/A] UTF-8")

# Create f/c selection box
default_fahrenheit = self.controller.fahrenheit
fahrenheit_checkbox = urwid.CheckBox(
"Fahrenheit",
state=default_fahrenheit,
on_state_change=self.on_fahrenheit_checkbox,
)

install_stress_message = urwid.Text("")
if not self.controller.firestarter and not self.controller.stress_exe:
install_stress_message = urwid.Text(
Expand All @@ -483,6 +547,7 @@ def _generate_graph_controls(self):
urwid.Divider(),
urwid.Text(("bold text", "Visual Options"), align="center"),
unicode_checkbox,
fahrenheit_checkbox,
self.refresh_rate_ctrl,
urwid.Divider(),
urwid.Text(("bold text", "Summaries"), align="center"),
Expand Down Expand Up @@ -651,21 +716,29 @@ def _load_config(self, t_thresh):
):
logging.debug("No refresh rate configured")

# Change UTF8 setting from config
# Load UTF8 setting from config
try:
if self.conf.getboolean("GraphControl", "UTF8"):
self.smooth_graph_mode = True
else:
logging.debug(
"UTF8 selected as %s", self.conf.get("GraphControl", "UTF8")
)
self.smooth_graph_mode = self.conf.getboolean("GraphControl", "UTF8")
logging.debug("UTF8 %s", self.smooth_graph_mode)
except (
AttributeError,
ValueError,
configparser.NoOptionError,
configparser.NoSectionError,
):
logging.debug("No user config for utf8")
logging.debug("No user config for UTF8")

# Load Fahrenheit setting from config
try:
self.fahrenheit = self.conf.getboolean("GraphControl", "Fahrenheit")
logging.debug("Fahrenheit %s", self.fahrenheit)
except (
AttributeError,
ValueError,
configparser.NoOptionError,
configparser.NoSectionError,
):
logging.debug("No user config for Fahrenheit")

# Try to load high temperature threshold if configured
if t_thresh is None:
Expand All @@ -684,7 +757,7 @@ def _load_config(self, t_thresh):

# This should be the only place where sources are configured
possible_sources = [
TempSource(self.temp_thresh),
TempSource(self.temp_thresh, self.fahrenheit),
FreqSource(),
UtilSource(),
RaplPowerSource(),
Expand Down Expand Up @@ -749,6 +822,7 @@ def __init__(self, args):
self.refresh_rate = args.refresh_rate

self.smooth_graph_mode = False
self.fahrenheit = False

self.summary_default_conf = defaultdict(list)
self.graphs_default_conf = defaultdict(list)
Expand Down Expand Up @@ -783,6 +857,29 @@ def __init__(self, args):
# Debug counter
self.debug_run_counter = 0

def rebuild_temp_source(self):
"""Recreate the temperature source using current Fahrenheit flag.

Returns the new TempSource instance and updates self.sources in place.
"""
for idx, src in enumerate(self.sources):
try:
is_temp = src.get_source_name() == "Temp"
except Exception:
is_temp = False
if is_temp:
new_src = TempSource(self.temp_thresh, self.fahrenheit)
# If new source is unavailable, keep old to avoid removing graphs
if not new_src.get_is_available():
return src
self.sources[idx] = new_src
return new_src
# If Temp source not found, create and append it
new_src = TempSource(self.temp_thresh, self.fahrenheit)
if new_src.get_is_available():
self.sources.append(new_src)
return new_src

def set_mode(self, mode):
"""Allow our view to set the mode."""
self.stress_controller.set_mode(mode)
Expand Down Expand Up @@ -873,6 +970,8 @@ def _save_displayed_setting(conf, submenu):
conf.set("GraphControl", "refresh", str(self.refresh_rate))
# Save the configured UTF8 setting
conf.set("GraphControl", "UTF8", str(self.smooth_graph_mode))
# Save the configured UTF8 setting
conf.set("GraphControl", "Fahrenheit", str(self.fahrenheit))
# Save the configured t_thresh
if self.temp_thresh:
conf.set("GraphControl", "TTHRESH", str(self.temp_thresh))
Expand Down
34 changes: 24 additions & 10 deletions s_tui/sources/temp_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class TempSource(Source):

THRESHOLD_TEMP = 80

def __init__(self, temp_thresh=None):
def __init__(self, temp_thresh=None, fahrenheit=False):
warnings.filterwarnings(
"ignore",
".*FileNotFound.*",
Expand All @@ -49,6 +49,10 @@ def __init__(self, temp_thresh=None):

self.name = "Temp"
self.measurement_unit = "C"
self.farenheit = False
if fahrenheit:
self.measurement_unit = "F"
self.farenheit = True
self.max_last_temp = 0
self.pallet = (
"temp light",
Expand Down Expand Up @@ -76,7 +80,9 @@ def __init__(self, temp_thresh=None):
sensor_name = "".join(key.title().split(" "))
for sensor_idx, sensor in enumerate(value):
sensor_label = sensor.label
if sensor.current <= 1.0 or sensor.current >= 127.0:
if self.to_f(sensor.current) <= self.to_f(1.0) or self.to_f(
sensor.current
) >= self.to_f(127.0):
continue

full_name = ""
Expand All @@ -94,9 +100,9 @@ def __init__(self, temp_thresh=None):
self.last_measurement = [0] * len(self.available_sensors)

# Set temperature threshold if a custom one is set
self.temp_thresh = self.THRESHOLD_TEMP
self.temp_thresh = self.to_f(self.THRESHOLD_TEMP)
if temp_thresh is not None:
if int(temp_thresh) > 0:
if int(temp_thresh) > self.to_f(0):
self.temp_thresh = int(temp_thresh)
logging.debug("Updated custom threshold to %s", self.temp_thresh)

Expand All @@ -105,9 +111,11 @@ def update(self):
self.last_measurement = []
for sensor in sample:
for minor_sensor in sample[sensor]:
if minor_sensor.current <= 1.0 or minor_sensor.current >= 127.0:
if self.to_f(minor_sensor.current) <= self.to_f(1.0) or self.to_f(
minor_sensor.current
) >= self.to_f(127.0):
continue
self.last_measurement.append(minor_sensor.current)
self.last_measurement.append(self.to_f(minor_sensor.current))

if self.last_measurement:
self.max_last_temp = max(self.last_measurement)
Expand All @@ -117,12 +125,18 @@ def update(self):
def get_edge_triggered(self):
return self.max_last_temp > self.temp_thresh

def to_f(self, temp):
if self.farenheit:
return temp * 9.0 / 5.0 + 32.0
else:
return temp

def get_max_triggered(self):
"""Returns whether the current temperature threshold is exceeded"""
return self.max_temp > self.temp_thresh
return self.to_f(self.max_temp) > self.to_f(self.temp_thresh)

def reset(self):
self.max_temp = 10
self.max_temp = self.to_f(10)

def get_maximum(self):
raise NotImplementedError("Get maximum is not implemented")
Expand All @@ -133,8 +147,8 @@ def get_top(self):
for temp in available_temps:
for temp_minor in temp:
try:
if temp_minor.high > top_temp:
if self.to_f(temp_minor.high) > self.to_f(top_temp):
top_temp = temp_minor.critical
except TypeError:
continue
return min(top_temp, 99)
return min(self.to_f(top_temp), self.to_f(99))