diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml
index c923a22a6..4f7cbf194 100644
--- a/.github/workflows/main_matrix.yml
+++ b/.github/workflows/main_matrix.yml
@@ -8,7 +8,9 @@ on:
branches:
- master
- develop
+ - pioarduino # Remove when merged // use `feature/` in the future.
- event/*
+ - feature/*
paths-ignore:
- "**.md"
- version.properties
@@ -18,7 +20,9 @@ on:
branches:
- master
- develop
+ - pioarduino # Remove when merged // use `feature/` in the future.
- event/*
+ - feature/*
paths-ignore:
- "**.md"
#- "**.yml"
diff --git a/bin/build-esp32.sh b/bin/build-esp32.sh
index 4e799b30a..d07a09a16 100755
--- a/bin/build-esp32.sh
+++ b/bin/build-esp32.sh
@@ -38,4 +38,4 @@ cp bin/device-install.* $OUTDIR/
cp bin/device-update.* $OUTDIR/
echo "Copying manifest"
-cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
+cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true
diff --git a/bin/build-nrf52.sh b/bin/build-nrf52.sh
index edcc2add2..99187ba0d 100755
--- a/bin/build-nrf52.sh
+++ b/bin/build-nrf52.sh
@@ -49,4 +49,4 @@ if (echo $1 | grep -q "rak4631"); then
fi
echo "Copying manifest"
-cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
+cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true
diff --git a/bin/build-rp2xx0.sh b/bin/build-rp2xx0.sh
index 3ef1c1e34..992a39be7 100755
--- a/bin/build-rp2xx0.sh
+++ b/bin/build-rp2xx0.sh
@@ -30,4 +30,4 @@ echo "Copying uf2 file"
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2
echo "Copying manifest"
-cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
+cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true
diff --git a/bin/build-stm32wl.sh b/bin/build-stm32wl.sh
index 023f3603c..64eb36586 100755
--- a/bin/build-stm32wl.sh
+++ b/bin/build-stm32wl.sh
@@ -30,4 +30,4 @@ echo "Copying STM32 bin file"
cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin
echo "Copying manifest"
-cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
+cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true
diff --git a/bin/platformio-custom.py b/bin/platformio-custom.py
index b6560f35b..90d733ca7 100644
--- a/bin/platformio-custom.py
+++ b/bin/platformio-custom.py
@@ -2,11 +2,12 @@
# trunk-ignore-all(ruff/F821)
# trunk-ignore-all(flake8/F821): For SConstruct imports
import sys
-from os.path import join, basename, isfile
+from os.path import join
import subprocess
import json
import re
from datetime import datetime
+from typing import Dict
from readprops import readProps
@@ -14,8 +15,47 @@ Import("env")
platform = env.PioPlatform()
progname = env.get("PROGNAME")
lfsbin = f"{progname.replace('firmware-', 'littlefs-')}.bin"
+manifest_ran = False
+
+def infer_architecture(board_cfg):
+ try:
+ mcu = board_cfg.get("build.mcu") if board_cfg else None
+ except KeyError:
+ mcu = None
+ except Exception:
+ mcu = None
+ if not mcu:
+ return None
+ mcu_l = str(mcu).lower()
+ if "esp32s3" in mcu_l:
+ return "esp32-s3"
+ if "esp32c6" in mcu_l:
+ return "esp32-c6"
+ if "esp32c3" in mcu_l:
+ return "esp32-c3"
+ if "esp32" in mcu_l:
+ return "esp32"
+ if "rp2040" in mcu_l:
+ return "rp2040"
+ if "rp2350" in mcu_l:
+ return "rp2350"
+ if "nrf52" in mcu_l or "nrf52840" in mcu_l:
+ return "nrf52840"
+ if "stm32" in mcu_l:
+ return "stm32"
+ return None
def manifest_gather(source, target, env):
+ global manifest_ran
+ if manifest_ran:
+ return
+ # Skip manifest generation if we cannot determine architecture (host/native builds)
+ board_arch = infer_architecture(env.BoardConfig())
+ if not board_arch:
+ print(f"Skipping mtjson generation for unknown architecture (env={env.get('PIOENV')})")
+ manifest_ran = True
+ return
+ manifest_ran = True
out = []
board_platform = env.BoardConfig().get("platform")
needs_ota_suffix = board_platform == "nordicnrf52"
@@ -47,14 +87,39 @@ def manifest_gather(source, target, env):
manifest_write(out, env)
def manifest_write(files, env):
+ # Defensive: also skip manifest writing if we cannot determine architecture
+ def get_project_option(name):
+ try:
+ return env.GetProjectOption(name)
+ except Exception:
+ return None
+
+ def get_project_option_any(names):
+ for name in names:
+ val = get_project_option(name)
+ if val is not None:
+ return val
+ return None
+
+ def as_bool(val):
+ return str(val).strip().lower() in ("1", "true", "yes", "on")
+
+ def as_int(val):
+ try:
+ return int(str(val), 10)
+ except (TypeError, ValueError):
+ return None
+
+ def as_list(val):
+ return [item.strip() for item in str(val).split(",") if item.strip()]
+
manifest = {
"version": verObj["long"],
"build_epoch": build_epoch,
- "board": env.get("PIOENV"),
+ "platformioTarget": env.get("PIOENV"),
"mcu": env.get("BOARD_MCU"),
"repo": repo_owner,
"files": files,
- "part": None,
"has_mui": False,
"has_inkhud": False,
}
@@ -69,6 +134,51 @@ def manifest_write(files, env):
if "MESHTASTIC_INCLUDE_INKHUD" in env.get("CPPDEFINES", []):
manifest["has_inkhud"] = True
+ pioenv = env.get("PIOENV")
+ device_meta = {}
+ device_meta_fields = [
+ ("hwModel", ["custom_meshtastic_hw_model"], as_int),
+ ("hwModelSlug", ["custom_meshtastic_hw_model_slug"], str),
+ ("architecture", ["custom_meshtastic_architecture"], str),
+ ("activelySupported", ["custom_meshtastic_actively_supported"], as_bool),
+ ("displayName", ["custom_meshtastic_display_name"], str),
+ ("supportLevel", ["custom_meshtastic_support_level"], as_int),
+ ("images", ["custom_meshtastic_images"], as_list),
+ ("tags", ["custom_meshtastic_tags"], as_list),
+ ("requiresDfu", ["custom_meshtastic_requires_dfu"], as_bool),
+ ("partitionScheme", ["custom_meshtastic_partition_scheme"], str),
+ ("url", ["custom_meshtastic_url"], str),
+ ("key", ["custom_meshtastic_key"], str),
+ ("variant", ["custom_meshtastic_variant"], str),
+ ]
+
+
+ for manifest_key, option_keys, caster in device_meta_fields:
+ raw_val = get_project_option_any(option_keys)
+ if raw_val is None:
+ continue
+ parsed = caster(raw_val) if callable(caster) else raw_val
+ if parsed is not None and parsed != "":
+ device_meta[manifest_key] = parsed
+
+ # Determine architecture once; if we can't infer it, skip manifest generation
+ board_arch = device_meta.get("architecture") or infer_architecture(env.BoardConfig())
+ if not board_arch:
+ print(f"Skipping mtjson write for unknown architecture (env={env.get('PIOENV')})")
+ return
+
+ device_meta["architecture"] = board_arch
+
+ # Always set requiresDfu: true for nrf52840 targets
+ if board_arch == "nrf52840":
+ device_meta["requiresDfu"] = True
+
+ device_meta.setdefault("displayName", pioenv)
+ device_meta.setdefault("activelySupported", False)
+
+ if device_meta:
+ manifest.update(device_meta)
+
# Write the manifest to the build directory
with open(env.subst("$BUILD_DIR/${PROGNAME}.mt.json"), "w") as f:
json.dump(manifest, f, indent=2)
@@ -166,8 +276,12 @@ def load_boot_logo(source, target, env):
if ("HAS_TFT", 1) in env.get("CPPDEFINES", []):
env.AddPreAction(f"$BUILD_DIR/{lfsbin}", load_boot_logo)
-mtjson_deps = ["buildprog"]
-if platform.name == "espressif32":
+board_arch = infer_architecture(env.BoardConfig())
+should_skip_manifest = board_arch is None
+
+# For host/native envs, avoid depending on 'buildprog' (some targets don't define it)
+mtjson_deps = [] if should_skip_manifest else ["buildprog"]
+if not should_skip_manifest and platform.name == "espressif32":
# Build littlefs image as part of mtjson target
# Equivalent to `pio run -t buildfs`
target_lfs = env.DataToBin(
@@ -175,11 +289,27 @@ if platform.name == "espressif32":
)
mtjson_deps.append(target_lfs)
-env.AddCustomTarget(
- name="mtjson",
- dependencies=mtjson_deps,
- actions=[manifest_gather],
- title="Meshtastic Manifest",
- description="Generating Meshtastic manifest JSON + Checksums",
- always_build=False,
-)
+if should_skip_manifest:
+ def skip_manifest(source, target, env):
+ print(f"mtjson: skipped for native environment: {env.get('PIOENV')}")
+
+ env.AddCustomTarget(
+ name="mtjson",
+ dependencies=mtjson_deps,
+ actions=[skip_manifest],
+ title="Meshtastic Manifest (skipped)",
+ description="mtjson generation is skipped for native environments",
+ always_build=True,
+ )
+else:
+ env.AddCustomTarget(
+ name="mtjson",
+ dependencies=mtjson_deps,
+ actions=[manifest_gather],
+ title="Meshtastic Manifest",
+ description="Generating Meshtastic manifest JSON + Checksums",
+ always_build=True,
+ )
+
+ # Run manifest generation as part of the default build pipeline for non-native builds.
+ env.Default("mtjson")
diff --git a/bin/readprops.py b/bin/readprops.py
index 731a3d0d3..4b92d63dd 100644
--- a/bin/readprops.py
+++ b/bin/readprops.py
@@ -18,8 +18,9 @@ def readProps(prefsLoc):
# Try to find current build SHA if if the workspace is clean. This could fail if git is not installed
try:
+ # Pin abbreviation length to keep local builds and CI matching (avoid auto-shortening)
sha = (
- subprocess.check_output(["git", "rev-parse", "--short", "HEAD"])
+ subprocess.check_output(["git", "rev-parse", "--short=7", "HEAD"])
.decode("utf-8")
.strip()
)
diff --git a/boards/t-beam-1w.json b/boards/t-beam-1w.json
new file mode 100644
index 000000000..ac1d1f15e
--- /dev/null
+++ b/boards/t-beam-1w.json
@@ -0,0 +1,50 @@
+{
+ "build": {
+ "arduino": {
+ "ldscript": "esp32s3_out.ld",
+ "memory_type": "qio_opi"
+ },
+ "core": "esp32",
+ "extra_flags": [
+ "-DBOARD_HAS_PSRAM",
+ "-DLILYGO_TBEAM_1W",
+ "-DARDUINO_USB_CDC_ON_BOOT=1",
+ "-DARDUINO_USB_MODE=0",
+ "-DARDUINO_RUNNING_CORE=1",
+ "-DARDUINO_EVENT_RUNNING_CORE=1"
+ ],
+ "f_cpu": "240000000L",
+ "f_flash": "80000000L",
+ "flash_mode": "qio",
+ "psram_type": "opi",
+ "hwids": [
+ [
+ "0x303A",
+ "0x1001"
+ ]
+ ],
+ "mcu": "esp32s3",
+ "variant": "t-beam-1w"
+ },
+ "connectivity": [
+ "wifi",
+ "bluetooth",
+ "lora"
+ ],
+ "debug": {
+ "openocd_target": "esp32s3.cfg"
+ },
+ "frameworks": [
+ "arduino"
+ ],
+ "name": "LilyGo TBeam-1W",
+ "upload": {
+ "flash_size": "16MB",
+ "maximum_ram_size": 327680,
+ "maximum_size": 16777216,
+ "require_upload_port": true,
+ "speed": 921600
+ },
+ "url": "http://www.lilygo.cn/",
+ "vendor": "LilyGo"
+}
\ No newline at end of file
diff --git a/src/configuration.h b/src/configuration.h
index 650e1cc71..ec1b9acc2 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -444,6 +444,18 @@ along with this program. If not, see .
#endif
#endif
+// BME680 BSEC2 support detection
+#if !defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
+#if defined(RAK_4631) || defined(TBEAM_V10)
+
+#define MESHTASTIC_BME680_BSEC2_SUPPORTED 1
+#define MESHTASTIC_BME680_HEADER
+#else
+#define MESHTASTIC_BME680_BSEC2_SUPPORTED 0
+#define MESHTASTIC_BME680_HEADER
+#endif // defined(RAK_4631)
+#endif // !defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
+
// -----------------------------------------------------------------------------
// Global switches to turn off features for a minimized build
// -----------------------------------------------------------------------------
diff --git a/src/graphics/draw/MenuHandler.cpp b/src/graphics/draw/MenuHandler.cpp
index 5687c8620..138995ebe 100644
--- a/src/graphics/draw/MenuHandler.cpp
+++ b/src/graphics/draw/MenuHandler.cpp
@@ -449,13 +449,14 @@ void menuHandler::clockMenu()
}
void menuHandler::messageResponseMenu()
{
- enum optionsNumbers { Back = 0, ViewMode, DeleteAll, DeleteOldest, ReplyMenu, Aloud, enumEnd };
+ enum optionsNumbers { Back = 0, ViewMode, DeleteAll, DeleteOldest, ReplyMenu, MuteChannel, Aloud, enumEnd };
static const char *optionsArray[enumEnd];
static int optionsEnumArray[enumEnd];
int options = 0;
auto mode = graphics::MessageRenderer::getThreadMode();
+ int threadChannel = graphics::MessageRenderer::getThreadChannel();
optionsArray[options] = "Back";
optionsEnumArray[options++] = Back;
@@ -467,6 +468,15 @@ void menuHandler::messageResponseMenu()
optionsArray[options] = "View Chats";
optionsEnumArray[options++] = ViewMode;
+ // If viewing ALL chats, hide “Mute Chat”
+ if (mode != graphics::MessageRenderer::ThreadMode::ALL && mode != graphics::MessageRenderer::ThreadMode::DIRECT) {
+ const uint8_t chIndex = (threadChannel != 0) ? (uint8_t)threadChannel : channels.getPrimaryIndex();
+ auto &chan = channels.getByIndex(chIndex);
+
+ optionsArray[options] = chan.settings.module_settings.is_muted ? "Unmute Channel" : "Mute Channel";
+ optionsEnumArray[options++] = MuteChannel;
+ }
+
// Delete submenu
optionsArray[options] = "Delete";
optionsEnumArray[options++] = 900;
@@ -502,6 +512,14 @@ void menuHandler::messageResponseMenu()
menuHandler::menuQueue = menuHandler::reply_menu;
screen->runNow();
+ } else if (selected == MuteChannel) {
+ const uint8_t chIndex = (ch != 0) ? (uint8_t)ch : channels.getPrimaryIndex();
+ auto &chan = channels.getByIndex(chIndex);
+ if (chan.settings.has_module_settings) {
+ chan.settings.module_settings.is_muted = !chan.settings.module_settings.is_muted;
+ nodeDB->saveToDisk();
+ }
+
// Delete submenu
} else if (selected == 900) {
menuHandler::menuQueue = menuHandler::delete_messages_menu;
diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp
index b7459abe0..78602a9ec 100644
--- a/src/mesh/FloodingRouter.cpp
+++ b/src/mesh/FloodingRouter.cpp
@@ -4,6 +4,7 @@
#include "configuration.h"
#include "mesh-pb-constants.h"
#include "meshUtils.h"
+#include "modules/TextMessageModule.h"
#if !MESHTASTIC_EXCLUDE_TRACEROUTE
#include "modules/TraceRouteModule.h"
#endif
@@ -35,6 +36,10 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
return true; // we handled it, so stop processing
}
+ if (!seenRecently && !wasUpgraded && textMessageModule) {
+ seenRecently = textMessageModule->recentlySeen(p->id);
+ }
+
if (seenRecently) {
printPacket("Ignore dupe incoming msg", p);
rxDupe++;
diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp
index a74b33abf..22e3bd1e3 100644
--- a/src/mesh/RadioInterface.cpp
+++ b/src/mesh/RadioInterface.cpp
@@ -246,7 +246,8 @@ uint32_t RadioInterface::getPacketTime(const meshtastic_MeshPacket *p, bool rece
/** The delay to use for retransmitting dropped packets */
uint32_t RadioInterface::getRetransmissionMsec(const meshtastic_MeshPacket *p)
{
- size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded);
+ size_t numbytes =p->which_payload_variant == meshtastic_MeshPacket_decoded_tag ?
+ pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded) : p->encrypted.size+MESHTASTIC_HEADER_LENGTH;
uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader));
// Make sure enough time has elapsed for this packet to be sent and an ACK is received.
// LOG_DEBUG("Waiting for flooding message with airtime %d and slotTime is %d", packetAirtime, slotTimeMsec);
diff --git a/src/mesh/SX126xInterface.cpp b/src/mesh/SX126xInterface.cpp
index e1f07a32b..2d7996a13 100644
--- a/src/mesh/SX126xInterface.cpp
+++ b/src/mesh/SX126xInterface.cpp
@@ -62,6 +62,11 @@ template bool SX126xInterface::init()
digitalWrite(LORA_PA_TX_EN, LOW);
#endif
+#ifdef RF95_FAN_EN
+ digitalWrite(RF95_FAN_EN, HIGH);
+ pinMode(RF95_FAN_EN, OUTPUT);
+#endif
+
#if ARCH_PORTDUINO
tcxoVoltage = (float)portduino_config.dio3_tcxo_voltage / 1000;
if (portduino_config.lora_sx126x_ant_sw_pin.pin != RADIOLIB_NC) {
@@ -85,6 +90,13 @@ template bool SX126xInterface::init()
power = -9;
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
+
+#ifdef SX126X_PA_RAMP_US
+ // Set custom PA ramp time for boards requiring longer stabilization (e.g., T-Beam 1W needs >800us)
+ if (res == RADIOLIB_ERR_NONE) {
+ lora.setPaRampTime(SX126X_PA_RAMP_US);
+ }
+#endif
// \todo Display actual typename of the adapter, not just `SX126x`
LOG_INFO("SX126x init result %d", res);
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND || res == RADIOLIB_ERR_SPI_CMD_FAILED)
diff --git a/src/modules/SystemCommandsModule.cpp b/src/modules/SystemCommandsModule.cpp
index 51543eab6..1da756366 100644
--- a/src/modules/SystemCommandsModule.cpp
+++ b/src/modules/SystemCommandsModule.cpp
@@ -45,9 +45,9 @@ int SystemCommandsModule::handleInputEvent(const InputEvent *event)
// Mute
case INPUT_BROKER_MSG_MUTE_TOGGLE:
if (moduleConfig.external_notification.enabled && externalNotificationModule) {
- externalNotificationModule->setMute(externalNotificationModule->getMute());
+ externalNotificationModule->setMute(!externalNotificationModule->getMute());
IF_SCREEN(if (!externalNotificationModule->getMute()) externalNotificationModule->stopNow(); screen->showSimpleBanner(
- externalNotificationModule->getMute() ? "Notifications\nEnabled" : "Notifications\nDisabled", 3000);)
+ externalNotificationModule->getMute() ? "Notifications\nDisabled" : "Notifications\nEnabled", 3000);)
}
return 0;
// Bluetooth
diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp
index 41062662b..843d7b8d5 100644
--- a/src/modules/Telemetry/EnvironmentTelemetry.cpp
+++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp
@@ -53,7 +53,7 @@ extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const c
#include "Sensor/LTR390UVSensor.h"
#endif
-#if __has_include()
+#if __has_include(MESHTASTIC_BME680_HEADER)
#include "Sensor/BME680Sensor.h"
#endif
@@ -214,7 +214,7 @@ void EnvironmentTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner)
#if __has_include()
addSensor(i2cScanner, ScanI2C::DeviceType::LTR390UV);
#endif
-#if __has_include()
+#if __has_include(MESHTASTIC_BME680_HEADER)
addSensor(i2cScanner, ScanI2C::DeviceType::BME_680);
#endif
#if __has_include()
diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp
index 95f3dc5f0..22330ca75 100644
--- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp
+++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp
@@ -1,6 +1,6 @@
#include "configuration.h"
-#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include()
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(MESHTASTIC_BME680_HEADER)
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "BME680Sensor.h"
@@ -10,6 +10,7 @@
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
+#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
int32_t BME680Sensor::runOnce()
{
if (!bme680.run()) {
@@ -17,10 +18,13 @@ int32_t BME680Sensor::runOnce()
}
return 35;
}
+#endif // defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
status = 0;
+
+#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
if (!bme680.begin(dev->address.address, *bus))
checkStatus("begin");
@@ -42,12 +46,25 @@ bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
if (status == 0)
LOG_DEBUG("BME680Sensor::runOnce: bme680.status %d", bme680.status);
+#else
+ bme680 = makeBME680(bus);
+
+ if (!bme680->begin(dev->address.address)) {
+ LOG_ERROR("Init sensor: %s failed at begin()", sensorName);
+ return status;
+ }
+
+ status = 1;
+
+#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
+
initI2CSensor();
return status;
}
bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
+#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
if (bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal == 0)
return false;
@@ -65,9 +82,27 @@ bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
// Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms)
measurement->variant.environment_metrics.iaq = bme680.getData(BSEC_OUTPUT_IAQ).signal;
updateState();
+#else
+ if (!bme680->performReading()) {
+ LOG_ERROR("BME680Sensor::getMetrics: performReading failed");
+ return false;
+ }
+
+ measurement->variant.environment_metrics.has_temperature = true;
+ measurement->variant.environment_metrics.has_relative_humidity = true;
+ measurement->variant.environment_metrics.has_barometric_pressure = true;
+ measurement->variant.environment_metrics.has_gas_resistance = true;
+
+ measurement->variant.environment_metrics.temperature = bme680->readTemperature();
+ measurement->variant.environment_metrics.relative_humidity = bme680->readHumidity();
+ measurement->variant.environment_metrics.barometric_pressure = bme680->readPressure() / 100.0F;
+ measurement->variant.environment_metrics.gas_resistance = bme680->readGas() / 1000.0;
+
+#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
return true;
}
+#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
void BME680Sensor::loadState()
{
#ifdef FSCom
@@ -144,5 +179,6 @@ void BME680Sensor::checkStatus(const char *functionName)
else if (bme680.sensor.status > BME68X_OK)
LOG_WARN("%s BME68X code: %d", functionName, bme680.sensor.status);
}
+#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
#endif
diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h
index f4ead95f7..9bef56e1e 100644
--- a/src/modules/Telemetry/Sensor/BME680Sensor.h
+++ b/src/modules/Telemetry/Sensor/BME680Sensor.h
@@ -1,23 +1,40 @@
#include "configuration.h"
-#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include()
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(MESHTASTIC_BME680_HEADER)
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
+
+#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
+#include
#include
+#else
+#include
+#include
+#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis()
+#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
const uint8_t bsec_config[] = {
#include "config/bme680/bme680_iaq_33v_3s_4d/bsec_iaq.txt"
};
-
+#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
class BME680Sensor : public TelemetrySensor
{
private:
+#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
Bsec2 bme680;
+#else
+ using BME680Ptr = std::unique_ptr;
+
+ static BME680Ptr makeBME680(TwoWire *bus) { return std::make_unique(bus); }
+
+ BME680Ptr bme680;
+#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
protected:
+#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
const char *bsecConfigFileName = "/prefs/bsec.dat";
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
uint8_t accuracy = 0;
@@ -34,10 +51,13 @@ class BME680Sensor : public TelemetrySensor
void loadState();
void updateState();
void checkStatus(const char *functionName);
+#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
public:
BME680Sensor();
+#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
virtual int32_t runOnce() override;
+#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
diff --git a/src/modules/TextMessageModule.cpp b/src/modules/TextMessageModule.cpp
index 7f889e087..d94701c6b 100644
--- a/src/modules/TextMessageModule.cpp
+++ b/src/modules/TextMessageModule.cpp
@@ -17,6 +17,9 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp
auto &p = mp.decoded;
LOG_INFO("Received text msg from=0x%0x, id=0x%x, msg=%.*s", mp.from, mp.id, p.payload.size, p.payload.bytes);
#endif
+ // add packet ID to the rolling list of packets
+ textPacketList[textPacketListIndex] = mp.id;
+ textPacketListIndex = (textPacketListIndex + 1) % TEXT_PACKET_LIST_SIZE;
// We only store/display messages destined for us.
devicestate.rx_text_message = mp;
@@ -47,3 +50,13 @@ bool TextMessageModule::wantPacket(const meshtastic_MeshPacket *p)
{
return MeshService::isTextPayload(p);
}
+
+bool TextMessageModule::recentlySeen(uint32_t id)
+{
+ for (size_t i = 0; i < TEXT_PACKET_LIST_SIZE; i++) {
+ if (textPacketList[i] != 0 && textPacketList[i] == id) {
+ return true;
+ }
+ }
+ return false;
+}
\ No newline at end of file
diff --git a/src/modules/TextMessageModule.h b/src/modules/TextMessageModule.h
index e719f1abc..42900a78e 100644
--- a/src/modules/TextMessageModule.h
+++ b/src/modules/TextMessageModule.h
@@ -1,6 +1,7 @@
#pragma once
#include "Observer.h"
#include "SinglePortModule.h"
+#define TEXT_PACKET_LIST_SIZE 50
/**
* Text message handling for Meshtastic.
@@ -19,6 +20,8 @@ class TextMessageModule : public SinglePortModule, public Observable
+
+#define USB_VID 0x303a
+#define USB_PID 0x1001
+
+static const uint8_t TX = 43;
+static const uint8_t RX = 44;
+
+// I2C for OLED and sensors
+static const uint8_t SDA = 8;
+static const uint8_t SCL = 9;
+
+// Default SPI mapped to Radio/SD
+static const uint8_t SS = 15; // LoRa CS
+static const uint8_t MOSI = 11;
+static const uint8_t MISO = 12;
+static const uint8_t SCK = 13;
+
+// SD Card CS
+#define SDCARD_CS 10
+
+#endif /* Pins_Arduino_h */
diff --git a/variants/esp32s3/t-beam-1w/platformio.ini b/variants/esp32s3/t-beam-1w/platformio.ini
new file mode 100644
index 000000000..54ddb6c3e
--- /dev/null
+++ b/variants/esp32s3/t-beam-1w/platformio.ini
@@ -0,0 +1,14 @@
+; LilyGo T-Beam-1W (1 Watt LoRa with external PA)
+[env:t-beam-1w]
+extends = esp32s3_base
+board = t-beam-1w
+board_build.partitions = default_8MB.csv
+board_check = true
+
+lib_deps =
+ ${esp32s3_base.lib_deps}
+
+build_flags =
+ ${esp32s3_base.build_flags}
+ -I variants/esp32s3/t-beam-1w
+ -D T_BEAM_1W
diff --git a/variants/esp32s3/t-beam-1w/variant.h b/variants/esp32s3/t-beam-1w/variant.h
new file mode 100644
index 000000000..01404afcb
--- /dev/null
+++ b/variants/esp32s3/t-beam-1w/variant.h
@@ -0,0 +1,97 @@
+// LilyGo T-Beam-1W variant.h
+// Configuration based on LilyGO utilities.h and RF documentation
+
+// I2C for OLED display (SH1106 at 0x3C)
+#define I2C_SDA 8
+#define I2C_SCL 9
+
+// GPS - Quectel L76K
+#define GPS_RX_PIN 5
+#define GPS_TX_PIN 6
+#define GPS_1PPS_PIN 7
+#define GPS_WAKEUP_PIN 16 // GPS_EN_PIN in LilyGO code
+#define HAS_GPS 1
+#define GPS_BAUDRATE 9600
+
+// Buttons
+#define BUTTON_PIN 0 // BUTTON 1
+#define BUTTON_PIN_ALT 17 // BUTTON 2
+
+// SPI (shared by LoRa and SD)
+#define SPI_MOSI 11
+#define SPI_SCK 13
+#define SPI_MISO 12
+#define SPI_CS 10
+
+// SD Card
+#define HAS_SDCARD
+#define SDCARD_USE_SPI1
+#define SDCARD_CS SPI_CS
+
+// LoRa Radio - SX1262 with 1W PA
+#define USE_SX1262
+
+#define LORA_SCK SPI_SCK
+#define LORA_MISO SPI_MISO
+#define LORA_MOSI SPI_MOSI
+#define LORA_CS 15
+#define LORA_RESET 3
+#define LORA_DIO1 1
+#define LORA_BUSY 38
+
+// CRITICAL: Radio power enable - MUST be HIGH before lora.begin()!
+// GPIO 40 powers the SX1262 + PA module via LDO
+#define SX126X_POWER_EN 40
+
+// TX power offset for external PA (0 = no offset, full SX1262 power)
+#define TX_GAIN_LORA 10
+
+#ifdef USE_SX1262
+#define SX126X_CS LORA_CS
+#define SX126X_DIO1 LORA_DIO1
+#define SX126X_BUSY LORA_BUSY
+#define SX126X_RESET LORA_RESET
+
+// RF switching configuration for 1W PA module
+// DIO2 controls PA (via SX126X_DIO2_AS_RF_SWITCH)
+// CTRL PIN (GPIO 21) controls LNA - must be HIGH during RX
+// Truth table: DIO2=1,CTRL=0 → TX (PA on, LNA off)
+// DIO2=0,CTRL=1 → RX (PA off, LNA on)
+#define SX126X_DIO2_AS_RF_SWITCH
+#define SX126X_RXEN 21 // LNA enable - HIGH during RX
+
+// TCXO voltage - required for radio init
+#define SX126X_DIO3_TCXO_VOLTAGE 1.8
+
+#define SX126X_MAX_POWER 22
+#endif
+
+// LED
+#define LED_PIN 18
+#define LED_STATE_ON 1 // HIGH = ON
+
+// Battery ADC
+#define BATTERY_PIN 4
+#define ADC_CHANNEL ADC1_GPIO4_CHANNEL
+#define BATTERY_SENSE_SAMPLES 30
+#define ADC_MULTIPLIER 2.9333
+
+// NTC temperature sensor
+#define NTC_PIN 14
+
+// Fan control
+#define FAN_CTRL_PIN 41
+// Meshtastic standard fan control pin macro
+#define RF95_FAN_EN FAN_CTRL_PIN
+
+// PA Ramp Time - T-Beam 1W requires >800us stabilization (default is 200us)
+// Value 0x05 = RADIOLIB_SX126X_PA_RAMP_800U
+#define SX126X_PA_RAMP_US 0x05
+
+// Display - SH1106 OLED (128x64)
+#define USE_SH1106
+#define OLED_WIDTH 128
+#define OLED_HEIGHT 64
+
+// 32768 Hz crystal present
+#define HAS_32768HZ 1
diff --git a/variants/esp32s3/t-deck-pro/platformio.ini b/variants/esp32s3/t-deck-pro/platformio.ini
index b97d7ac3f..28fef86ba 100644
--- a/variants/esp32s3/t-deck-pro/platformio.ini
+++ b/variants/esp32s3/t-deck-pro/platformio.ini
@@ -1,4 +1,15 @@
[env:t-deck-pro]
+custom_meshtastic_hw_model = 102
+custom_meshtastic_hw_model_slug = T_DECK_PRO
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = LILYGO T-Deck Pro
+custom_meshtastic_images = tdeck_pro.svg
+custom_meshtastic_tags = LilyGo
+custom_meshtastic_requires_dfu = true
+custom_meshtastic_partition_scheme = 16MB
+
extends = esp32s3_base
board = t-deck-pro
board_check = true
diff --git a/variants/esp32s3/t-deck/platformio.ini b/variants/esp32s3/t-deck/platformio.ini
index c8f3c8d5e..58335796a 100644
--- a/variants/esp32s3/t-deck/platformio.ini
+++ b/variants/esp32s3/t-deck/platformio.ini
@@ -1,5 +1,16 @@
; LilyGo T-Deck
[env:t-deck]
+custom_meshtastic_hw_model = 50
+custom_meshtastic_hw_model_slug = T_DECK
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = LILYGO T-Deck
+custom_meshtastic_images = t-deck.svg
+custom_meshtastic_tags = LilyGo
+custom_meshtastic_requires_dfu = true
+custom_meshtastic_partition_scheme = 16MB
+
extends = esp32s3_base
board = t-deck
board_check = true
diff --git a/variants/esp32s3/t-watch-s3/platformio.ini b/variants/esp32s3/t-watch-s3/platformio.ini
index 9785119b5..7d7b07ff6 100644
--- a/variants/esp32s3/t-watch-s3/platformio.ini
+++ b/variants/esp32s3/t-watch-s3/platformio.ini
@@ -1,5 +1,15 @@
; LilyGo T-Watch S3
[env:t-watch-s3]
+custom_meshtastic_hw_model = 51
+custom_meshtastic_hw_model_slug = T_WATCH_S3
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 3
+custom_meshtastic_display_name = LILYGO T-Watch S3
+custom_meshtastic_images = t-watch-s3.svg
+custom_meshtastic_tags = LilyGo
+custom_meshtastic_partition_scheme = 8MB
+
extends = esp32s3_base
board = t-watch-s3
board_check = true
diff --git a/variants/esp32s3/tbeam-s3-core/platformio.ini b/variants/esp32s3/tbeam-s3-core/platformio.ini
index 5522e1d37..c0a32c49c 100644
--- a/variants/esp32s3/tbeam-s3-core/platformio.ini
+++ b/variants/esp32s3/tbeam-s3-core/platformio.ini
@@ -1,5 +1,16 @@
; The 1.0 release of the LilyGo TBEAM-S3-Core board
[env:tbeam-s3-core]
+custom_meshtastic_hw_model = 12
+custom_meshtastic_hw_model_slug = LILYGO_TBEAM_S3_CORE
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = LILYGO T-Beam Supreme
+custom_meshtastic_images = tbeam-s3-core.svg
+custom_meshtastic_tags = LilyGo
+custom_meshtastic_requires_dfu = true
+custom_meshtastic_partition_scheme = 8MB
+
extends = esp32s3_base
board = tbeam-s3-core
board_build.partitions = default_8MB.csv
diff --git a/variants/esp32s3/tlora-pager/platformio.ini b/variants/esp32s3/tlora-pager/platformio.ini
index 98b9f51f5..3a7afb016 100644
--- a/variants/esp32s3/tlora-pager/platformio.ini
+++ b/variants/esp32s3/tlora-pager/platformio.ini
@@ -1,5 +1,16 @@
; LilyGo T-Lora-Pager
[env:tlora-pager]
+custom_meshtastic_hw_model = 103
+custom_meshtastic_hw_model_slug = T_LORA_PAGER
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = LILYGO T-LoRa Pager
+custom_meshtastic_images = lilygo-tlora-pager.svg
+custom_meshtastic_tags = LilyGo
+custom_meshtastic_requires_dfu = true
+custom_meshtastic_partition_scheme = 16MB
+
extends = esp32s3_base
board = t-deck-pro ; same as T-Deck Pro
board_check = true
diff --git a/variants/esp32s3/tlora_t3s3_epaper/platformio.ini b/variants/esp32s3/tlora_t3s3_epaper/platformio.ini
index 18b9e136e..fdf3f7814 100644
--- a/variants/esp32s3/tlora_t3s3_epaper/platformio.ini
+++ b/variants/esp32s3/tlora_t3s3_epaper/platformio.ini
@@ -1,4 +1,14 @@
[env:tlora-t3s3-epaper]
+custom_meshtastic_hw_model = 16
+custom_meshtastic_hw_model_slug = TLORA_T3_S3
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = LILYGO T-LoRa T3-S3 E-Ink
+custom_meshtastic_images = tlora-t3s3-epaper.svg
+custom_meshtastic_tags = LilyGo
+custom_meshtastic_requires_dfu = true
+
extends = esp32s3_base
board = tlora-t3s3-v1
board_check = true
diff --git a/variants/esp32s3/tlora_t3s3_v1/platformio.ini b/variants/esp32s3/tlora_t3s3_v1/platformio.ini
index 7a5e3df4b..95686e417 100644
--- a/variants/esp32s3/tlora_t3s3_v1/platformio.ini
+++ b/variants/esp32s3/tlora_t3s3_v1/platformio.ini
@@ -1,4 +1,14 @@
[env:tlora-t3s3-v1]
+custom_meshtastic_hw_model = 16
+custom_meshtastic_hw_model_slug = TLORA_T3_S3
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = LILYGO T-LoRa T3-S3
+custom_meshtastic_images = tlora-t3s3-v1.svg
+custom_meshtastic_tags = LilyGo
+custom_meshtastic_requires_dfu = true
+
extends = esp32s3_base
board = tlora-t3s3-v1
board_check = true
diff --git a/variants/esp32s3/tracksenger/platformio.ini b/variants/esp32s3/tracksenger/platformio.ini
index 73212c546..419a3539b 100644
--- a/variants/esp32s3/tracksenger/platformio.ini
+++ b/variants/esp32s3/tracksenger/platformio.ini
@@ -1,4 +1,13 @@
[env:tracksenger]
+custom_meshtastic_hw_model = 48
+custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 3
+custom_meshtastic_display_name = TrackSenger (small TFT)
+custom_meshtastic_requires_dfu = true
+custom_meshtastic_partition_scheme = 8MB
+
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv
@@ -16,6 +25,15 @@ lib_deps =
lovyan03/LovyanGFX@1.2.7
[env:tracksenger-lcd]
+custom_meshtastic_hw_model = 48
+custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = false
+custom_meshtastic_support_level = 3
+custom_meshtastic_display_name = TrackSenger (big TFT)
+custom_meshtastic_requires_dfu = true
+custom_meshtastic_partition_scheme = 8MB
+
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv
@@ -33,6 +51,14 @@ lib_deps =
lovyan03/LovyanGFX@1.2.7
[env:tracksenger-oled]
+custom_meshtastic_hw_model = 48
+custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 3
+custom_meshtastic_display_name = TrackSenger (big OLED)
+custom_meshtastic_partition_scheme = 8MB
+
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv
diff --git a/variants/esp32s3/unphone/platformio.ini b/variants/esp32s3/unphone/platformio.ini
index 6c638af29..28be1f3e1 100644
--- a/variants/esp32s3/unphone/platformio.ini
+++ b/variants/esp32s3/unphone/platformio.ini
@@ -1,6 +1,15 @@
; platformio.ini for unphone meshtastic
[env:unphone]
+custom_meshtastic_hw_model = 59
+custom_meshtastic_hw_model_slug = UNPHONE
+custom_meshtastic_architecture = esp32-s3
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 3
+custom_meshtastic_display_name = unPhone
+custom_meshtastic_requires_dfu = true
+custom_meshtastic_partition_scheme = 8MB
+
extends = esp32s3_base
board = unphone
board_build.partitions = partition-table-8MB.csv
diff --git a/variants/native/portduino.ini b/variants/native/portduino.ini
index 76520091c..cc6c39aa2 100644
--- a/variants/native/portduino.ini
+++ b/variants/native/portduino.ini
@@ -34,6 +34,8 @@ lib_deps =
adafruit/Adafruit seesaw Library@1.7.9
# renovate: datasource=git-refs depName=RAK12034-BMX160 packageName=https://github.com/RAKWireless/RAK12034-BMX160 gitBranch=main
https://github.com/RAKWireless/RAK12034-BMX160/archive/dcead07ffa267d3c906e9ca4a1330ab989e957e2.zip
+ # renovate: datasource=custom.pio depName=adafruit/Adafruit BME680 Library packageName=adafruit/library/Adafruit BME680
+ adafruit/Adafruit BME680 Library@^2.0.5
build_flags =
${arduino_base.build_flags}
diff --git a/variants/nrf52840/ELECROW-ThinkNode-M1/platformio.ini b/variants/nrf52840/ELECROW-ThinkNode-M1/platformio.ini
index 25f1b78b2..041d3b76f 100644
--- a/variants/nrf52840/ELECROW-ThinkNode-M1/platformio.ini
+++ b/variants/nrf52840/ELECROW-ThinkNode-M1/platformio.ini
@@ -1,5 +1,14 @@
; First prototype eink/nrf52840/sx1262 device
[env:thinknode_m1]
+custom_meshtastic_hw_model = 89
+custom_meshtastic_hw_model_slug = THINKNODE_M1
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = ThinkNode M1
+custom_meshtastic_images = thinknode_m1.svg
+custom_meshtastic_tags = Elecrow
+
extends = nrf52840_base
board = ThinkNode-M1
board_check = true
diff --git a/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini b/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini
index 0ed46896f..bf9492075 100644
--- a/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini
+++ b/variants/nrf52840/ELECROW-ThinkNode-M3/platformio.ini
@@ -1,8 +1,17 @@
[env:thinknode_m3]
+custom_meshtastic_support_level = 1
+custom_meshtastic_images = thinknode_m3.svg
+custom_meshtastic_tags = Elecrow
+
extends = nrf52840_base
board = ThinkNode-M3
board_check = true
debug_tool = jlink
+custom_meshtastic_hw_model = 115
+custom_meshtastic_hw_model_slug = THINKNODE_M3
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_display_name = Elecrow ThinkNode M3
+custom_meshtastic_actively_supported = true
build_flags =
${nrf52840_base.build_flags}
-Ivariants/nrf52840/ELECROW-ThinkNode-M3
diff --git a/variants/nrf52840/ELECROW-ThinkNode-M6/platformio.ini b/variants/nrf52840/ELECROW-ThinkNode-M6/platformio.ini
index 18108df83..413eb4fab 100644
--- a/variants/nrf52840/ELECROW-ThinkNode-M6/platformio.ini
+++ b/variants/nrf52840/ELECROW-ThinkNode-M6/platformio.ini
@@ -1,5 +1,14 @@
; ThinkNode M6 - Outdoor Solar Power nrf52840/sx1262 device
[env:thinknode_m6]
+custom_meshtastic_hw_model = 120
+custom_meshtastic_hw_model_slug = THINKNODE_M6
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = false
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = ThinkNode M6
+custom_meshtastic_images = thinknode_m6.svg
+custom_meshtastic_tags = Elecrow
+
extends = nrf52840_base
board = ThinkNode-M6
board_check = true
diff --git a/variants/nrf52840/canaryone/platformio.ini b/variants/nrf52840/canaryone/platformio.ini
index 1be04c9aa..a2cf55972 100644
--- a/variants/nrf52840/canaryone/platformio.ini
+++ b/variants/nrf52840/canaryone/platformio.ini
@@ -1,5 +1,13 @@
; Public Beta oled/nrf52840/sx1262 device
[env:canaryone]
+custom_meshtastic_hw_model = 29
+custom_meshtastic_hw_model_slug = CANARYONE
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 3
+custom_meshtastic_display_name = Canary One
+custom_meshtastic_tags = Canary
+
extends = nrf52840_base
board = canaryone
debug_tool = jlink
diff --git a/variants/nrf52840/diy/nrf52_promicro_diy_tcxo/platformio.ini b/variants/nrf52840/diy/nrf52_promicro_diy_tcxo/platformio.ini
index ca8f1777e..006f5c875 100644
--- a/variants/nrf52840/diy/nrf52_promicro_diy_tcxo/platformio.ini
+++ b/variants/nrf52840/diy/nrf52_promicro_diy_tcxo/platformio.ini
@@ -1,5 +1,15 @@
; Promicro + E22(0)-xxxM / HT-RA62 modules board variant - DIY - with TCXO
[env:nrf52_promicro_diy_tcxo]
+custom_meshtastic_hw_model = 63
+custom_meshtastic_hw_model_slug = NRF52_PROMICRO_DIY
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 3
+custom_meshtastic_display_name = NRF52 Pro-micro DIY
+custom_meshtastic_images = promicro.svg
+custom_meshtastic_tags = DIY
+custom_meshtastic_requires_dfu = true
+
extends = nrf52840_base
board = promicro-nrf52840
build_flags = ${nrf52840_base.build_flags}
diff --git a/variants/nrf52840/heltec_mesh_node_t114/platformio.ini b/variants/nrf52840/heltec_mesh_node_t114/platformio.ini
index 7971e33c6..a39872205 100644
--- a/variants/nrf52840/heltec_mesh_node_t114/platformio.ini
+++ b/variants/nrf52840/heltec_mesh_node_t114/platformio.ini
@@ -1,5 +1,14 @@
; First prototype nrf52840/sx1262 device
[env:heltec-mesh-node-t114]
+custom_meshtastic_hw_model = 69
+custom_meshtastic_hw_model_slug = HELTEC_MESH_NODE_T114
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = Heltec Mesh Node T114
+custom_meshtastic_images = heltec-mesh-node-t114.svg, heltec-mesh-node-t114-case.svg
+custom_meshtastic_tags = Heltec
+
extends = nrf52840_base
board = heltec_mesh_node_t114
board_level = pr
diff --git a/variants/nrf52840/heltec_mesh_pocket/platformio.ini b/variants/nrf52840/heltec_mesh_pocket/platformio.ini
index 4d3610fda..4dc8b78e7 100644
--- a/variants/nrf52840/heltec_mesh_pocket/platformio.ini
+++ b/variants/nrf52840/heltec_mesh_pocket/platformio.ini
@@ -1,8 +1,20 @@
; First prototype nrf52840/sx1262 device
[env:heltec-mesh-pocket-5000]
+custom_meshtastic_support_level = 1
+custom_meshtastic_images = heltec_mesh_pocket.svg
+custom_meshtastic_tags = Heltec
+
extends = nrf52840_base
board = heltec_mesh_pocket
debug_tool = jlink
+custom_device_hw_model = 94
+custom_meshtastic_hw_model = 94
+custom_meshtastic_hw_model_slug = HELTEC_MESH_POCKET
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_display_name = Heltec Mesh Pocket
+custom_meshtastic_actively_supported = true
+custom_meshtastic_variant = 5000mAh
+custom_meshtastic_key = heltec_mesh_pocket
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
build_flags = ${nrf52840_base.build_flags}
@@ -31,6 +43,13 @@ lib_deps =
[env:heltec-mesh-pocket-5000-inkhud]
extends = nrf52840_base, inkhud
board = heltec_mesh_pocket
+custom_meshtastic_hw_model = 94
+custom_meshtastic_hw_model_slug = HELTEC_MESH_POCKET
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_display_name = Heltec Mesh Pocket
+custom_meshtastic_actively_supported = true
+custom_meshtastic_variant = 5000mAh InkHUD
+custom_meshtastic_key = heltec_mesh_pocket
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_pocket> ${inkhud.build_src_filter}
build_flags =
${inkhud.build_flags}
@@ -45,9 +64,20 @@ lib_deps =
; First prototype nrf52840/sx1262 device
[env:heltec-mesh-pocket-10000]
+custom_meshtastic_support_level = 1
+custom_meshtastic_images = heltec_mesh_pocket.svg
+custom_meshtastic_tags = Heltec
+
extends = nrf52840_base
board = heltec_mesh_pocket
debug_tool = jlink
+custom_meshtastic_hw_model = 94
+custom_meshtastic_hw_model_slug = HELTEC_MESH_POCKET
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_display_name = Heltec Mesh Pocket
+custom_meshtastic_actively_supported = true
+custom_meshtastic_variant = 10000mAh
+custom_meshtastic_key = heltec_mesh_pocket
# add -DCFG_SYSVIEW if you want to use the Segger systemview tool for OS profiling.
build_flags = ${nrf52840_base.build_flags}
@@ -76,6 +106,13 @@ lib_deps =
[env:heltec-mesh-pocket-10000-inkhud]
extends = nrf52840_base, inkhud
board = heltec_mesh_pocket
+custom_meshtastic_hw_model = 94
+custom_meshtastic_hw_model_slug = HELTEC_MESH_POCKET
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_display_name = Heltec Mesh Pocket
+custom_meshtastic_actively_supported = true
+custom_meshtastic_variant = 10000mAh InkHUD
+custom_meshtastic_key = heltec_mesh_pocket
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_pocket> ${inkhud.build_src_filter}
build_flags =
${inkhud.build_flags}
diff --git a/variants/nrf52840/heltec_mesh_solar/platformio.ini b/variants/nrf52840/heltec_mesh_solar/platformio.ini
index fa8965a64..2ad699544 100644
--- a/variants/nrf52840/heltec_mesh_solar/platformio.ini
+++ b/variants/nrf52840/heltec_mesh_solar/platformio.ini
@@ -19,6 +19,15 @@ lib_deps =
bblanchon/ArduinoJson@6.21.4
[env:heltec-mesh-solar]
+custom_meshtastic_hw_model = 108
+custom_meshtastic_hw_model_slug = HELTEC_MESH_SOLAR
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = false
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = Heltec MeshSolar
+custom_meshtastic_images = heltec-mesh-solar.svg
+custom_meshtastic_tags = Heltec
+
extends = heltec_mesh_solar_base
build_flags = ${heltec_mesh_solar_base.build_flags}
-DSPI_INTERFACES_COUNT=1
diff --git a/variants/nrf52840/muzi_base/platformio.ini b/variants/nrf52840/muzi_base/platformio.ini
index 29d93d1cd..52c558ff1 100644
--- a/variants/nrf52840/muzi_base/platformio.ini
+++ b/variants/nrf52840/muzi_base/platformio.ini
@@ -1,4 +1,13 @@
[env:muzi-base]
+custom_meshtastic_hw_model = 93
+custom_meshtastic_hw_model_slug = MUZI_BASE
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = muzi BASE
+custom_meshtastic_images = muzi_base.svg
+custom_meshtastic_tags = muzi
+
extends = nrf52840_base
board = muzi-base
build_flags = ${nrf52840_base.build_flags}
diff --git a/variants/nrf52840/nano-g2-ultra/platformio.ini b/variants/nrf52840/nano-g2-ultra/platformio.ini
index 5952029fd..0748b7e38 100644
--- a/variants/nrf52840/nano-g2-ultra/platformio.ini
+++ b/variants/nrf52840/nano-g2-ultra/platformio.ini
@@ -1,5 +1,14 @@
; First prototype eink/nrf52840/sx1262 device
[env:nano-g2-ultra]
+custom_meshtastic_hw_model = 18
+custom_meshtastic_hw_model_slug = NANO_G2_ULTRA
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 2
+custom_meshtastic_display_name = Nano G2 Ultra
+custom_meshtastic_images = nano-g2-ultra.svg
+custom_meshtastic_tags = B&Q
+
extends = nrf52840_base
board = nano-g2-ultra
debug_tool = jlink
diff --git a/variants/nrf52840/r1-neo/platformio.ini b/variants/nrf52840/r1-neo/platformio.ini
index af3cd052d..85fe49cf1 100644
--- a/variants/nrf52840/r1-neo/platformio.ini
+++ b/variants/nrf52840/r1-neo/platformio.ini
@@ -1,5 +1,14 @@
; The R1 Neo board
[env:r1-neo]
+custom_meshtastic_hw_model = 101
+custom_meshtastic_hw_model_slug = MUZI_R1_NEO
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = muzi R1 Neo
+custom_meshtastic_images = muzi_r1_neo.svg
+custom_meshtastic_tags = muzi
+
extends = nrf52840_base
board = r1-neo
board_check = true
diff --git a/variants/nrf52840/rak2560/platformio.ini b/variants/nrf52840/rak2560/platformio.ini
index 21b3776f8..1703a13ae 100644
--- a/variants/nrf52840/rak2560/platformio.ini
+++ b/variants/nrf52840/rak2560/platformio.ini
@@ -1,5 +1,14 @@
; Firmware for the WisMesh HUB RAK2560, including a onewire module to talk to the RAK 9154 solar battery.
[env:rak2560]
+custom_meshtastic_hw_model = 22
+custom_meshtastic_hw_model_slug = WISMESH_HUB
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = RAK WisMesh Repeater
+custom_meshtastic_images = rak2560.svg
+custom_meshtastic_tags = RAK
+
extends = nrf52840_base
board = wiscore_rak4631
board_check = true
diff --git a/variants/nrf52840/rak3401_1watt/platformio.ini b/variants/nrf52840/rak3401_1watt/platformio.ini
index 268274b13..bb8fa28df 100644
--- a/variants/nrf52840/rak3401_1watt/platformio.ini
+++ b/variants/nrf52840/rak3401_1watt/platformio.ini
@@ -1,5 +1,15 @@
; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921
[env:rak3401-1watt]
+custom_meshtastic_hw_model = 117
+custom_meshtastic_hw_model_slug = RAK3401
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = RAK3401 1W
+custom_meshtastic_images = rak3401.svg
+custom_meshtastic_tags = RAK
+custom_meshtastic_requires_dfu = true
+
extends = nrf52840_base
board = wiscore_rak4631
board_check = true
diff --git a/variants/nrf52840/rak4631/platformio.ini b/variants/nrf52840/rak4631/platformio.ini
index ed30692be..4a96fc8d9 100644
--- a/variants/nrf52840/rak4631/platformio.ini
+++ b/variants/nrf52840/rak4631/platformio.ini
@@ -1,5 +1,14 @@
; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921
[env:rak4631]
+custom_meshtastic_hw_model = 9
+custom_meshtastic_hw_model_slug = RAK4631
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = RAK WisBlock 4631
+custom_meshtastic_images = rak4631.svg, rak4631_case.svg
+custom_meshtastic_tags = RAK
+
extends = nrf52840_base
board = wiscore_rak4631
board_level = pr
diff --git a/variants/nrf52840/rak4631_nomadstar_meteor_pro/platformio.ini b/variants/nrf52840/rak4631_nomadstar_meteor_pro/platformio.ini
index 500242c24..07d763df3 100644
--- a/variants/nrf52840/rak4631_nomadstar_meteor_pro/platformio.ini
+++ b/variants/nrf52840/rak4631_nomadstar_meteor_pro/platformio.ini
@@ -1,5 +1,14 @@
; NomadStar Meteor Pro based on RAK4631 with RGBW LED LP5562 support
[env:rak4631_nomadstar_meteor_pro]
+custom_meshtastic_hw_model = 96
+custom_meshtastic_hw_model_slug = NOMADSTAR_METEOR_PRO
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = NomadStar Meteor Pro
+custom_meshtastic_images = meteor_pro.svg
+custom_meshtastic_tags = NomadStar
+
extends = nrf52840_base
board = wiscore_rak4631
board_check = true
diff --git a/variants/nrf52840/rak_wismeshtag/platformio.ini b/variants/nrf52840/rak_wismeshtag/platformio.ini
index 1cc00e253..1e6e63e60 100644
--- a/variants/nrf52840/rak_wismeshtag/platformio.ini
+++ b/variants/nrf52840/rak_wismeshtag/platformio.ini
@@ -1,8 +1,17 @@
; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921
[env:rak_wismeshtag]
+custom_meshtastic_support_level = 1
+custom_meshtastic_images = rak_wismesh_tag.svg
+custom_meshtastic_tags = RAK
+
extends = nrf52840_base
board = wiscore_rak4631
board_check = true
+custom_meshtastic_hw_model = 105
+custom_meshtastic_hw_model_slug = WISMESH_TAG
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_display_name = RAK WisMesh Tag
+custom_meshtastic_actively_supported = true
build_flags = ${nrf52840_base.build_flags}
-I variants/nrf52840/rak_wismeshtag
-D WISMESH_TAG
diff --git a/variants/nrf52840/rak_wismeshtap/platformio.ini b/variants/nrf52840/rak_wismeshtap/platformio.ini
index 485b7174f..f058d9153 100644
--- a/variants/nrf52840/rak_wismeshtap/platformio.ini
+++ b/variants/nrf52840/rak_wismeshtap/platformio.ini
@@ -1,5 +1,14 @@
; The very slick RAK wireless RAK10701 Field Tester device. Note you will have to flash to Arduino bootloader to use this firmware. Be aware touch is not currently working.
[env:rak_wismeshtap]
+custom_meshtastic_hw_model = 84
+custom_meshtastic_hw_model_slug = WISMESH_TAP
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = RAK WisMesh Tap
+custom_meshtastic_images = rak-wismeshtap.svg
+custom_meshtastic_tags = RAK
+
extends = nrf52840_base
board = wiscore_rak4631
build_flags = ${nrf52840_base.build_flags}
diff --git a/variants/nrf52840/seeed_solar_node/platformio.ini b/variants/nrf52840/seeed_solar_node/platformio.ini
index 5a2518331..18894c049 100644
--- a/variants/nrf52840/seeed_solar_node/platformio.ini
+++ b/variants/nrf52840/seeed_solar_node/platformio.ini
@@ -1,4 +1,13 @@
[env:seeed_solar_node]
+custom_meshtastic_hw_model = 95
+custom_meshtastic_hw_model_slug = SEEED_SOLAR_NODE
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = Seeed SenseCAP Solar Node
+custom_meshtastic_images = seeed_solar.svg
+custom_meshtastic_tags = Seeed
+
board = seeed_solar_node
extends = nrf52840_base
;board_level = extra
diff --git a/variants/nrf52840/seeed_wio_tracker_L1/platformio.ini b/variants/nrf52840/seeed_wio_tracker_L1/platformio.ini
index d11ad0ab9..d5b56b7bf 100644
--- a/variants/nrf52840/seeed_wio_tracker_L1/platformio.ini
+++ b/variants/nrf52840/seeed_wio_tracker_L1/platformio.ini
@@ -1,4 +1,14 @@
[env:seeed_wio_tracker_L1]
+custom_meshtastic_hw_model = 99
+custom_meshtastic_hw_model_slug = SEEED_WIO_TRACKER_L1
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = Seeed Wio Tracker L1
+custom_meshtastic_images = wio_tracker_l1_case.svg
+custom_meshtastic_tags = Seeed
+custom_meshtastic_requires_dfu = true
+
board = seeed_wio_tracker_L1
extends = nrf52840_base
build_flags = ${nrf52840_base.build_flags}
diff --git a/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini b/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini
index 3007a8c7b..6b36a79c3 100644
--- a/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini
+++ b/variants/nrf52840/seeed_wio_tracker_L1_eink/platformio.ini
@@ -1,4 +1,13 @@
[env:seeed_wio_tracker_L1_eink]
+custom_meshtastic_hw_model = 100
+custom_meshtastic_hw_model_slug = SEEED_WIO_TRACKER_L1_EINK
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = Seeed Wio Tracker L1 E-Ink
+custom_meshtastic_images = wio_tracker_l1_eink.svg
+custom_meshtastic_tags = Seeed
+
board = seeed_wio_tracker_L1
extends = nrf52840_base
;board_level = extra
diff --git a/variants/nrf52840/seeed_xiao_nrf52840_kit/platformio.ini b/variants/nrf52840/seeed_xiao_nrf52840_kit/platformio.ini
index 079cd5c52..68be47622 100644
--- a/variants/nrf52840/seeed_xiao_nrf52840_kit/platformio.ini
+++ b/variants/nrf52840/seeed_xiao_nrf52840_kit/platformio.ini
@@ -1,5 +1,14 @@
; Seeed Xiao BLE: https://wiki.seeedstudio.com/XIAO_BLE/
[env:seeed_xiao_nrf52840_kit]
+custom_meshtastic_hw_model = 88
+custom_meshtastic_hw_model_slug = XIAO_NRF52_KIT
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = Seeed Xiao NRF52840 Kit
+custom_meshtastic_images = seeed_xiao_nrf52_kit.svg
+custom_meshtastic_tags = Seeed
+
extends = nrf52840_base
board = xiao_ble_sense
board_level = pr
diff --git a/variants/nrf52840/t-echo-lite/platformio.ini b/variants/nrf52840/t-echo-lite/platformio.ini
index 217b76a2d..c873dea37 100644
--- a/variants/nrf52840/t-echo-lite/platformio.ini
+++ b/variants/nrf52840/t-echo-lite/platformio.ini
@@ -1,5 +1,14 @@
; Using original screen class
[env:t-echo-lite]
+custom_meshtastic_hw_model = 109
+custom_meshtastic_hw_model_slug = T_ECHO_LITE
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = false
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = LILYGO T-Echo Lite
+custom_meshtastic_images = techo_lite.svg
+custom_meshtastic_tags = LilyGo
+
extends = nrf52840_base
board = t-echo
board_check = true
diff --git a/variants/nrf52840/t-echo/platformio.ini b/variants/nrf52840/t-echo/platformio.ini
index 4244419b7..a8fc027c8 100644
--- a/variants/nrf52840/t-echo/platformio.ini
+++ b/variants/nrf52840/t-echo/platformio.ini
@@ -1,5 +1,14 @@
; Using original screen class
[env:t-echo]
+custom_meshtastic_hw_model = 7
+custom_meshtastic_hw_model_slug = T_ECHO
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 1
+custom_meshtastic_display_name = LILYGO T-Echo
+custom_meshtastic_images = t-echo.svg
+custom_meshtastic_tags = LilyGo
+
extends = nrf52840_base
board = t-echo
board_level = pr
diff --git a/variants/nrf52840/tracker-t1000-e/platformio.ini b/variants/nrf52840/tracker-t1000-e/platformio.ini
index 86d74f68a..43ba7a8b4 100644
--- a/variants/nrf52840/tracker-t1000-e/platformio.ini
+++ b/variants/nrf52840/tracker-t1000-e/platformio.ini
@@ -1,7 +1,16 @@
[env:tracker-t1000-e]
+custom_meshtastic_support_level = 1
+custom_meshtastic_images = tracker-t1000-e.svg
+custom_meshtastic_tags = Seeed
+
extends = nrf52840_base
board = tracker-t1000-e
board_level = pr
+custom_meshtastic_hw_model = 71
+custom_meshtastic_hw_model_slug = TRACKER_T1000_E
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_display_name = Seeed SenseCAP T1000-E
+custom_meshtastic_actively_supported = true
build_flags = ${nrf52840_base.build_flags}
-Ivariants/nrf52840/tracker-t1000-e
-Isrc/platform/nrf52/softdevice
diff --git a/variants/nrf52840/wio-tracker-wm1110/platformio.ini b/variants/nrf52840/wio-tracker-wm1110/platformio.ini
index b3513a242..515712062 100644
--- a/variants/nrf52840/wio-tracker-wm1110/platformio.ini
+++ b/variants/nrf52840/wio-tracker-wm1110/platformio.ini
@@ -1,5 +1,15 @@
; The red tracker Dev Board with the WM1110 module
[env:wio-tracker-wm1110]
+custom_meshtastic_hw_model = 21
+custom_meshtastic_hw_model_slug = WIO_WM1110
+custom_meshtastic_architecture = nrf52840
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 3
+custom_meshtastic_display_name = Seeed Wio WM1110 Tracker
+custom_meshtastic_images = wio-tracker-wm1110.svg
+custom_meshtastic_tags = Seeed
+custom_meshtastic_requires_dfu = true
+
extends = nrf52840_base
board = wio-tracker-wm1110
build_flags = ${nrf52840_base.build_flags}
diff --git a/variants/rp2040/rak11310/platformio.ini b/variants/rp2040/rak11310/platformio.ini
index 3234d3b99..2c2b2a4bf 100644
--- a/variants/rp2040/rak11310/platformio.ini
+++ b/variants/rp2040/rak11310/platformio.ini
@@ -1,4 +1,14 @@
[env:rak11310]
+custom_meshtastic_hw_model = 26
+custom_meshtastic_hw_model_slug = RAK11310
+custom_meshtastic_architecture = rp2040
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 2
+custom_meshtastic_display_name = RAK WisBlock 11310
+custom_meshtastic_images = rak11310.svg
+custom_meshtastic_tags = RAK
+custom_meshtastic_requires_dfu = true
+
extends = rp2040_base
board = rakwireless_rak11300
board_level = pr
diff --git a/variants/rp2040/rp2040-lora/platformio.ini b/variants/rp2040/rp2040-lora/platformio.ini
index a85869260..f1e0b9af6 100644
--- a/variants/rp2040/rp2040-lora/platformio.ini
+++ b/variants/rp2040/rp2040-lora/platformio.ini
@@ -1,4 +1,13 @@
[env:rp2040-lora]
+custom_meshtastic_hw_model = 30
+custom_meshtastic_hw_model_slug = RP2040_LORA
+custom_meshtastic_architecture = rp2040
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 2
+custom_meshtastic_display_name = RP2040 LoRa
+custom_meshtastic_tags = Waveshare
+custom_meshtastic_requires_dfu = true
+
extends = rp2040_base
board = rpipico
upload_protocol = picotool
diff --git a/variants/rp2040/rpipico/platformio.ini b/variants/rp2040/rpipico/platformio.ini
index 953aee625..4ae134b28 100644
--- a/variants/rp2040/rpipico/platformio.ini
+++ b/variants/rp2040/rpipico/platformio.ini
@@ -1,4 +1,14 @@
[env:pico]
+custom_meshtastic_hw_model = 47
+custom_meshtastic_hw_model_slug = RPI_PICO
+custom_meshtastic_architecture = rp2040
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 3
+custom_meshtastic_display_name = Raspberry Pi Pico
+custom_meshtastic_images = pico.svg
+custom_meshtastic_tags = RPi, DIY
+custom_meshtastic_requires_dfu = true
+
extends = rp2040_base
board = rpipico
board_level = pr
diff --git a/variants/rp2040/rpipicow/platformio.ini b/variants/rp2040/rpipicow/platformio.ini
index 00b7b1f01..99e02a1aa 100644
--- a/variants/rp2040/rpipicow/platformio.ini
+++ b/variants/rp2040/rpipicow/platformio.ini
@@ -1,4 +1,14 @@
[env:picow]
+custom_meshtastic_hw_model = 47
+custom_meshtastic_hw_model_slug = RPI_PICO
+custom_meshtastic_architecture = rp2040
+custom_meshtastic_actively_supported = true
+custom_meshtastic_support_level = 3
+custom_meshtastic_display_name = Raspberry Pi Pico W
+custom_meshtastic_images = rpipicow.svg
+custom_meshtastic_tags = RPi, DIY
+custom_meshtastic_requires_dfu = true
+
extends = rp2040_base
board = rpipicow
board_level = pr