status() now shows the failed component names (not just the count), a
red/yellow/green state indicator, and a summary of recent request activity
(count, errors, last kind/age/duration) from /stats - previously only
reachable via separate failures()/stats() calls.
recording_mode is now an _AdjustableFSChoice (enum_strs=("all", "throttle",
"sample"), the exact set RecordingSession.__init__ accepts) instead of a
freeform AdjustableFS: rejects an invalid value at set_target_value time,
and exposes enum_strs so it structurally satisfies
eco.elements.protocols.AdjustableEnum for widget-layer dropdown display.
Deliberately not eco.elements.adjustable.AdjustableEnum itself, which
stores an IntEnum's integer rather than the string - storage stays the
plain string the server already parses, no server-side change needed.
Also documents the max_value_elements/max_points_per_channel distinction
inline (per-value-width filter vs. per-channel-length cap over time) -
not obvious from the settings' names alone.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The settings (recording_mode, recording_min_interval, ...) were already
registered for display -- Assembly._append's own is_display defaults to
True and nothing here overrode it. What was missing is that StatusServer
replaces __repr__ outright with a one-line health summary, which never
called Assembly.get_display_str() (the thing that actually renders
is_display=True components into a table), so the settings never showed up
in repr(bernina.status_server) despite being display-eligible all along.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Three follow-ups to the status_server namespace component and
recording feature:
1. StatusServer's recording settings are now AdjustableFS, not
AdjustableMemory - each a small JSON file under the same shared
eco_cnf_bernina/configuration tree channels_JF/config_JFs already
use. The point: a setting changed in one process is visible to any
other process reading the same filesystem (another session, or the
status server itself) with no REST call or other new communication
- confirmed with a test constructing two independent StatusServer
instances against the same config_dir.
2. RecordingSession.size_report(): per-channel projected bandwidth -
rate (this channel's own point count over elapsed time) times a
sample value's size (element count * dtype itemsize, "frequency *
data shape * bitdepth") - to judge storage/bandwidth cost from a
short trial recording before committing to a long one. Works on a
still-running recording. Exposed via GET /recording/<id>?size=1
(optional &size_top_n=N) and StatusServerClient.recording(...,
size=True).
3. failed_required for recordings: a channel that fails to attach and
belongs to a required namespace component (namespace.required_names())
is now reported separately in a recording's report() - the same
"everyone else failing is expected, this failing is not" distinction
/health's failed_required already makes for init failures. New
client-side warn_recording_failed_required (red, but does not
suggest reinit() the way the health one does - a demoted/
disconnected channel isn't fixed by rebuilding the namespace),
wired into Daq.start_scan_monitoring.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New eco.status_server.namespace_component.StatusServer (Assembly),
wired into bernina_daq.py as a top-level namespace object alongside
daq/scans - always built, independent of whether this session's own
Daq is using the server (ECO_STATUS_SERVER), since the server itself
runs regardless.
- Control: .restart()/.reinit(), delegating to StatusServerClient.
- Inspection: .status() (prints a one-line summary, warns in red about
failed_required, returns the raw /health body), .stats(),
.failures(), .monitor_policy() (new GET /monitor_policy route +
client method, surfacing eco.epics_utils.ca_tuning's adaptive
monitor policy from inside the server's own process - max_rate_hz,
how many channels are monitored/known-fast, sensitive-period state;
read-only, the threshold itself is a module constant today).
- .gui(): launches the Qt monitor as a detached subprocess, same
window `eco-status-server gui` opens (not an embedded widget -
noted as a separate, bigger follow-up if wanted).
- Recording settings (mode, min_interval, sample_interval,
max_value_elements, max_points_per_channel) as real AdjustableMemory
children with is_setting=True, so they show up the way any other
device's configuration does. Not yet consumed by Daq.start_scan_
monitoring (still its own mode="throttle"/min_interval=0.1
defaults) - wiring that through is the natural next step, flagged
explicitly in the module docstring rather than left implicit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>