# Wio Tracker L1 — Extended Companion Radio Firmware

This branch extends the official MeshCore companion radio firmware for the **Seeed Wio Tracker L1**.

Join the discussion on offical MeshCore discord: https://discord.gg/sdhYArU2jr

## New Features

### Messages Screen

View and send messages using the on-screen keyboard or predefined quick replies. The keyboard supports placeholders that insert live sensor data — `{time}` and `{loc}` are always available; additional placeholders (`{temp}`, `{hum}`, `{pres}`, `{batt}`, `{alt}`, `{lux}`, `{co2}`) appear automatically for sensors that are connected and returning data.

Each message in the history list shows the sender name and a compact age indicator (`3m`, `2h`, `>1d`) in the top-right corner of the entry.

```
╔══════════════════════════════╗
║          #general            ║
╠══════════════════════════════╣
║▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ║  ← selected
║ Alice                   3m   ║
║ Hey, let's meet tomorrow     ║
║┌───────────────────────────┐ ║
║│▓▓▓▓▓▓▓▓▓ Bob      1h ▓▓▓▓ │ ║
║│ Sure, what time works?    │ ║
║└───────────────────────────┘ ║
║[+ send]                      ║
╚══════════════════════════════╝
```

Press Enter on a message to open it in fullscreen. Navigate between messages with left (newer) and right (older). If the message is a reply addressed to someone (`@[nick]`), a **To: nick** bar is shown below the sender name and the body is displayed without the address prefix.

```
╔══════════════════════════════╗
║▓▓ Alice ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ║  ← sender
║▓▓ To: Bob ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ║  ← recipient
╠══════════════════════════════╣
║ Hey Bob, let's meet up       ║
║ tomorrow at 6pm downtown.    ║
║ Will you make it?            ║
║                              ║
║< newer                older >║
╚══════════════════════════════╝
```

Hold Enter on a message to open a context menu. From the list or fullscreen view, select **Reply** to pre-fill the keyboard or a quick message with `@[nick]` so the recipient is clearly addressed. The reply picker title shows the recipient's name.

```
╔══════════════════════════════╗
║           RE:Alice           ║
╠══════════════════════════════╣
║> Custom message...           ║
║  OK, I understand            ║
║  On my way                   ║
║  Be right there              ║
╚══════════════════════════════╝
```

On channel or contact list entries, the context menu also lets you change per-channel notification settings (mute, follow global, or force-on), per-channel melody override (follow global, Melody 1, or Melody 2), or mark messages as read.

### Settings Screen

All settings are saved to flash and restored on next boot.

- **Display**
  - Brightness
  - Auto-off timeout
  - Battery display mode (icon, %, V)
  - Clock seconds (show/hide — hiding reduces display refresh from 1 s to 60 s)
  - Font — **Default** (5×7 Adafruit, ASCII + transliteration) or **Lemon** (native Unicode, available in the `font-switcher` build only)
- **Sound**
  - Buzzer: On / Off / **Auto** — Auto mode silences the device while connected via Bluetooth, and re-enables sound when the connection drops
  - Volume (1–5; preview tone plays on each change)
  - DM Melody — notification sound for incoming private messages: built-in, Melody 1, or Melody 2
  - Channel Melody — notification sound for incoming channel messages: built-in, Melody 1, or Melody 2
- **Home Pages** — toggle visibility of individual home screen pages
- **Radio**
  - TX power
- **System**
  - Timezone (UTC offset in hours)
  - Low battery shutdown threshold
  - Auto-lock — automatically locks the device when the display turns off
- **GPS**
  - Position broadcast interval
- **Contacts**
  - Show all DMs or favourites only
  - Show all room servers or favourites only
- **Messages**
  - Edit up to 10 quick reply templates (Q1–Q10)

### Clock Screen

A dedicated clock page on the home screen shows the current time and date, synchronized from GPS or via Bluetooth. Timezone offset is applied from Settings.

Up to three configurable data fields are displayed below the clock. Available fields: battery voltage, temperature, humidity, pressure, GPS coordinates, altitude, luminosity, CO₂, contact count, and total unread message count.

### Screen Lock

Hold **Back** and press **Enter** three times to lock or unlock the device. While locked:

- The display turns off and ignores incoming keypresses
- A brief button press shows the lock screen: current time, date, and up to two sensor values (reuses the Dashboard Config fields)
- A hint popup guides through the unlock sequence
- **Auto-lock** (configurable in Settings → System) locks automatically when the display turns off

### Nearby Nodes

Browse nodes that have recently advertised on the mesh. Filter by category (Favourites, All, Companion, Repeater, Room, Sensor). Select a node to see its coordinates, distance, bearing with cardinal direction, type, and last-heard time.

```
╔══════════════════════════════╗
║▓▓▓▓▓ WioTracker-Alice ▓▓▓▓▓▓ ║  ← node name
╠══════════════════════════════╣
║ Lat: 50.06190                ║
║ Lon: 19.94090                ║
║ Dist: 2.3km                  ║
║ Az: 145d (SE)                ║
║ Type: Companion              ║
║ Seen: 5m ago                 ║
╚══════════════════════════════╝
```

Use **Send my advert** (hold Enter → context menu) to broadcast your position and prompt nearby nodes to respond with theirs.

### Tools Screen

#### Auto-Advert

Periodically broadcasts a 0-hop advert with your GPS position so nearby nodes can track your location automatically. Configurable interval: off / 1 min / 2 min / 5 min / 10 min / 30 min / 1 h.

A blinking **A** indicator appears in the status bar while Auto-Advert is active.

#### Ringtone Editor

A step sequencer for composing custom notification melodies stored on the device. Two independent melody slots are available — **Melody 1** and **Melody 2** — switchable from within the editor. Each melody supports up to 32 notes with adjustable pitch (C–B + pause), octave (4–7), duration (whole / half / quarter / eighth), and BPM (60 / 90 / 120 / 150 / 180). Playback preview is available directly from the editor.

Melodies can be assigned as notification sounds per message type (DM / channel) in Settings, and individually overridden per channel or per contact from the message screen context menu.

#### Auto-Reply Bot

Automatically replies to incoming messages that contain a configured trigger word (case-insensitive).

- **DM mode** — when enabled, the bot listens to all incoming private messages and replies with the DM reply text.
- **Channel mode** — optionally, select a channel for the bot to monitor. When a trigger is matched, it replies with a separate channel reply text.
- Both modes can be active simultaneously and share the same trigger word but use independent reply texts.
- Replies support placeholders (`{time}`, `{loc}`).
- A 10-second cooldown prevents repeated replies in quick succession.

---

## Font Switcher Build

An alternative firmware build is available (`font-switcher` in the filename). It includes both the default 5×7 Adafruit font and the [Lemon bitmap font](https://github.com/cmvnd/fonts), switchable at runtime in **Settings → Display → Font** without reflashing. The selected font is saved to flash and takes effect immediately.

The Lemon font offers:

- **Native Unicode rendering** — Latin Extended, Greek, and Cyrillic characters (U+0020–U+04FF) are displayed directly without transliteration, covering Polish, Czech, Slovak, German, French, Scandinavian, Hungarian, Romanian, Croatian, Turkish, Baltic, Russian, and Greek scripts.
- **Pixel-accurate word wrap** — text wraps based on actual glyph widths rather than a fixed character count.
- **Slightly taller glyphs** — the font uses a 10 px line height compared to 8 px for the default font.

Prebuilt `.uf2` files for the font-switcher variant are included in each release alongside the standard builds and are identified by `font-switcher` in the filename.

---

Feel free to explore, share feedback and feature requests!

## Development

This fork tracks the upstream [MeshCore](https://github.com/ripplebiz/MeshCore) repository. To prevent upstream changes from overwriting this README during merges, `README.md` is protected via `.gitattributes`. After cloning, run once:

```sh
git config merge.ours.driver true
```
