Main loop for updating the EPD display with shared data.
(self)
| 2790 | Uses the live animated character sprite when one is loaded so the panel |
| 2791 | moves, falling back to the static ragnar1 mascot. Scaled up to fill the |
| 2792 | content band above the footer, preserving aspect ratio. |
| 2793 | """ |
| 2794 | sy = getattr(self, 'render_sy', self.scale_factor_y) |
| 2795 | w = getattr(self, 'render_w', self.shared_data.width) |
| 2796 | font = self.shared_data.font_arial9 |
| 2797 | footer_y = self._draw_wd_compact_chrome(draw) |
| 2798 | |
| 2799 | sd = self.shared_data |
| 2800 | vk = getattr(sd, 'imagegen', None) or getattr(sd, 'ragnar1', None) |
| 2801 | top = int(2 * sy) |
| 2802 | band_h = footer_y - top - int(2 * sy) |
| 2803 | if vk is None or band_h <= 0: |
| 2804 | msg = self._unit_display_title() |
| 2805 | draw.text(((w - font.getlength(msg)) / 2, footer_y / 2), msg, font=font, fill=0) |
| 2806 | return |
| 2807 | try: |
| 2808 | # Fill the band on the tighter axis so the whole viking stays visible. |
| 2809 | ratio = min((w - 4) / vk.width, band_h / vk.height) |
| 2810 | if ratio > 0: |
| 2811 | vk = vk.resize((max(1, int(vk.width * ratio)), |
| 2812 | max(1, int(vk.height * ratio))), Image.NEAREST) |
| 2813 | image.paste(vk, ((w - vk.width) // 2, top + (band_h - vk.height) // 2)) |
| 2814 | except Exception as e: |
| 2815 | logger.debug(f"viking page render failed: {e}") |
| 2816 | |
| 2817 | def _wardrive_map_points(self, wd=None): |
| 2818 | """Pull the live session's GPS track, located networks and current fix. |
| 2819 | |
| 2820 | Shared by the e-paper map page and the compact LCD map so both plot |
| 2821 | exactly the same data. Returns (track, nets, here) with here=None when |
| 2822 | there is no fix; every point is a (lat, lon) pair. |
| 2823 | """ |
| 2824 | track, nets, here = [], [], None |
| 2825 | try: |
| 2826 | from webapp_modern import _get_wardriving_engine |
| 2827 | engine = _get_wardriving_engine() |
| 2828 | session = getattr(engine, 'session', None) |
| 2829 | wd = wd if wd is not None else (self._get_wardriving_data() or {}) |
| 2830 | gps = (wd or {}).get('gps') or {} |
| 2831 | if gps.get('has_fix'): |
| 2832 | lat, lon = gps.get('latitude'), gps.get('longitude') |
| 2833 | if lat is not None and lon is not None: |
| 2834 | here = (lat, lon) |
| 2835 | if session is not None: |
| 2836 | track = [p for p in (session.get_gps_track() or []) |
| 2837 | if isinstance(p, (list, tuple)) and p[0] is not None and p[1] is not None] |
| 2838 | for n in session.get_networks(limit=2000): |
| 2839 | lat = n.get('best_lat') if n.get('best_lat') else n.get('latitude') |
| 2840 | lon = n.get('best_lon') if n.get('best_lon') else n.get('longitude') |
| 2841 | if lat and lon and not (lat == 0 and lon == 0): |
| 2842 | nets.append((lat, lon)) |
| 2843 | except Exception: |
| 2844 | pass |
| 2845 | return track, nets, here |
| 2846 | |
| 2847 | def _render_wardriving_page(self, image, draw): |
| 2848 | """Render a wardriving status page for EPD e-paper displays.""" |
| 2849 | # Tiny 1.44" ST7735S LCD HAT (128x128): the full stat page won't fit, |
no test coverage detected