Skip to content

Simplify wind display: label-switching design, opt-in via WIND_DISPLAY#273

Merged
e100 merged 3 commits into
makerplane:masterfrom
billmallard:wind-display
May 2, 2026
Merged

Simplify wind display: label-switching design, opt-in via WIND_DISPLAY#273
e100 merged 3 commits into
makerplane:masterfrom
billmallard:wind-display

Conversation

@billmallard
Copy link
Copy Markdown
Contributor

Summary

Follow-up to merged PR #264 (initial wind display). Addresses @e100's review comment that the wind widget shouldn't overlap with optional UI components like the trim cluster, and simplifies the visual design.

  • Layout: wind moved from row 83 col 15 (inside the trim cluster's footprint) to row 6 col 15 (upper-left, just below the auto-pilot status text, well clear of trim).
  • Design: dropped the cyan arrow polygons. Direction is now encoded by switching the two-character label — HW/TW for headwind/tailwind, RX/LX for crosswind from right/left. Magnitude is always an unsigned integer in knots. ±0.5 kt deadband around zero suppresses label flicker from sensor noise.
  • State / colour:
    • Healthy: white label and value (e.g. HW 12).
    • Bad: amber label and an amber X in place of the value, suppressing the suspect number while flagging the condition.
    • Failed: dim grey label with ---. Wind is supplemental info, so we deliberately avoid the red-X primary-instrument failure treatment to prevent alarm fatigue.
  • Configuration: wind is now opt-in via the WIND_DISPLAY preference (default false), paralleling the existing TRIM_CONTROLS pattern. Was previously hard-coded disabled: true.
  • Robustness: when WIND_DISPLAY is on but HWIND/XWIND aren't defined in the FIX database (e.g., gateway hasn't deployed the wind_components compute function), the widget now constructs cleanly and renders the failed state.

Two commits:

  1. Wind display rework — widget rewrite, position move, preference key, tests, requirements + screenbuilder docs.
  2. Xlib import guard in weston/__init__.py — incidental Windows/macOS compatibility fix needed to test pyEfis off-Linux. One line behind try/except; Linux behaviour unchanged. Happy to lift it out into a separate PR if preferred.

Test plan

  • pytest tests/instruments/wind/ tests/screens/test_screenbuilder.py — 34 passing.
    • 4 new screenbuilder tests for WIND_DISPLAY pref toggle and the missing-keys path.
    • 8 new wind widget tests for label switching, deadband, fail-default labels, feed offline (KeyError), feed dropping mid-flight, recovery.
    • Existing arrow-direction tests reframed as label tests.
  • Manually verified on the PFD with fix-gateway demo plugin publishing HWIND=12 / XWIND=-5 and cycling bad/fail flags every 6 s — all three colour states render correctly, no overlap with the trim cluster.

Notes

GitHub squash-merge has a known defect right now; please use a regular merge commit rather than squash when merging this PR.

🤖 Generated with Claude Code

billmallard and others added 3 commits May 2, 2026 09:52
…WIND_DISPLAY

The maintainer noted on PR makerplane#264 that the wind widget overlapped the
Pitch/Roll/Yaw trim cluster when both were enabled. This rework fixes
the overlap and replaces the arrow-and-number layout with a more compact,
text-only design suited to wind being supplemental information.

Layout
- Position moved from row 83 col 15 (inside trim's footprint) to row 6
  col 15 (upper-left, just below the auto-pilot status text, well clear
  of the trim cluster at rows 77-107).
- Label and value share one small font sized at 0.40 x row height; bottom
  row stacks at 0.65 x row_h instead of 1.0 to tighten vertical spacing.
- Value uses font metrics to sit a single space-width past the label,
  leaving room for 3-digit magnitudes.

Direction encoding
- Two-character labels switch with sign instead of rendering arrow polygons:
    HW / TW   for headwind / tailwind
    RX / LX   for crosswind from right / from left
- A 0.5 kt deadband around zero suppresses label flicker from sensor noise;
  values inside the deadband round to 0 and use the positive-side label.
- Magnitude is always shown as an unsigned integer in knots.

State / colour
- Healthy: white label and value (e.g. 'HW 12').
- Bad (data flagged unreliable): amber label and an amber 'X' in place of
  the value, suppressing the suspect number while flagging the condition.
- Failed (data unavailable): dim grey label with '---'; label reverts to
  the positive default since sign cannot be trusted. Pilots fly the airplane
  with airspeed/altitude/attitude; wind is supplemental, so we deliberately
  avoid the red-X primary-instrument failure treatment to prevent alarm
  fatigue.

Configuration
- Wind is now opt-in via the WIND_DISPLAY preference key (default false),
  paralleling the existing TRIM_CONTROLS pattern. Was previously hard-coded
  'disabled: true' which made it impossible for users to enable cleanly.
- When WIND_DISPLAY is false the screenbuilder skips instantiation entirely;
  no errors occur if HWIND / XWIND are absent from the FIX database.

Tests added
- tests/instruments/wind: label switching for positive/negative HWIND/XWIND,
  zero-and-deadband cases, fail state forces default label, paint events,
  data feed dropping after widget exists, data feed recovering, KeyError
  path when HWIND/XWIND are not defined in the FIX database.
- tests/screens/test_screenbuilder: wind_display skipped when WIND_DISPLAY
  pref is false, included when true, and built without raising even when
  HWIND/XWIND are missing from the FIX database (combined regression).

Docs updated
- docs/requirements.md: EFIS-WIND-001..008 rewritten and 009..012 added to
  capture position, label switching, deadband, three-state visuals, the
  WIND_DISPLAY preference, missing-keys safety, and the supplemental-info
  font sizing rationale.
- docs/screenbuilder.md: wind_display section rewritten with the label-pair
  table, all three visual states, the WIND_DISPLAY opt-in note, and the
  current YAML placement example.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…orms

The weston instrument is a Linux-only feature that wraps the Weston
compositor for embedded display setups. Its top-level 'from Xlib import
X, display' is therefore only meaningful on Linux, but it ran at module
import time, so the import failed on Windows/macOS even when no weston
instrument was configured on the active screen.

Wrap the import in try/except and fall back to X = display = None. The
Weston widget itself is only instantiated when screenbuilder sees an
instrument of type 'weston', so users on non-Linux platforms never hit
the None values. Linux users see no behaviour change.

This is incidental to the wind PR (the Windows test environment hit
this on every pyEfis launch) and is small enough to ship together; if
the maintainer prefers it as a separate PR I'll lift it out.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  src/pyefis/instruments/weston
  __init__.py 11-13
  src/pyefis/instruments/wind
  __init__.py
Project Total  

This report was generated by python-coverage-comment-action

@e100 e100 merged commit 15c01b2 into makerplane:master May 2, 2026
1 check passed
@e100
Copy link
Copy Markdown
Collaborator

e100 commented May 2, 2026

@billmallard
All code related to filesystem was not written with Windows in mind, that might be another place where improvements need made to accommodate it.

I just merged another commit that gets this to 100% code coverage., including all branches. But we are missing coverage for the changes you made to weston. Would have addressed this when I resolved the merge conflicts but did not notice it. If you have time to make another PR, great, if not, I'll get the tests added sometime soon.

We do have a mixture of unit and integration tests. I've preferred integration tests because testing the code as it would run in the real world gives me more confidence to use this in my airplane. Most of the recent tests I've added are unit tests since they are much easier to implement and better than no tests.

Appreciate the contributions!
I've only been involved in the project since 2024, a few others have commit permissions but I am the only one who is regularly active. I am very open to taking this to the next level so keep the ideas coming!

@billmallard
Copy link
Copy Markdown
Contributor Author

The AI actually was on the fence about including the weston bit since I believe it was Windows specific. I'll see about adding unit covered for it.

My day job is QA test automation. I noticed there was a harness for X-Plane already. I need to build some SIL type testing using that harness. That would be the logical integration testing path I believe.

I'm still learning the power of what all pyEfis can do. You guys really knocked it out of the park - the more I get into it, it's really flexible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants