The app now connects to devices that are not Nyquist hardware and carry their own, separate firmware. It still offers them the Nyquist firmware release, because the outdated-check compares versions without ever looking at what the device is.
Concretely: a Gloor IAQ board (ESP32-S3, device_pn not Nq*, own firmware versioning) connects over TCP and serial and gets flagged as having outdated firmware — because its version string sorts below the latest Nyquist release. Accepting that offer would flash PIC32 Nyquist firmware onto an ESP32-S3.
Where
IsFirmwareOutdated is set in two places, and neither considers device type:
Daqifi.Desktop/ViewModels/DaqifiViewModel.cs:1469
connectedDevice.IsFirmwareOutdated =
FirmwareVersion.Compare(DeviceVersion, latestFirmwareVersion) < 0;
Daqifi.Desktop/Device/Firmware/FirmwareUpdateCoordinator.cs:845
var updateCheck = await _firmwareDownloadService.CheckForUpdateAsync(
device.DeviceVersion ?? string.Empty, includePreRelease: true);
device.IsFirmwareOutdated = updateCheck.UpdateAvailable;
The only existing guard is at DaqifiViewModel.cs:1458 — skip if the device has no DeviceVersion property. That filters devices with no version at all, not devices with a version from a different product line. Any device reporting a version gets compared against the Nyquist release feed.
Suggested fix
IStreamingDevice.DeviceType already exists (IStreamingDevice.cs:64) and DeviceTypeDetector.DetectFromPartNumber maps only nq1/nq2/nq3 to Nyquist1/2/3, everything else to Unknown. So the gate is available at both call sites — no new plumbing:
// The firmware feed is Nyquist-only. A device from another product line has
// its own firmware and must never be offered this one.
if (device.DeviceType is not (DeviceType.Nyquist1 or DeviceType.Nyquist2 or DeviceType.Nyquist3))
{
device.IsFirmwareOutdated = false;
continue;
}
Worth deciding explicitly how DeviceType.Unknown should behave. Defaulting Unknown → no update offered is the safe direction: a device the app cannot identify is precisely the one that should not be flashed with Nyquist firmware. It does mean a genuine Nyquist that fails to report its part number stops being offered updates, which is a visible-but-harmless regression, versus the current failure mode of offering a cross-family flash.
Also worth checking the UI: if the update affordance keys off IsFirmwareOutdated alone, the fix above is sufficient; if anything else can reach the flash path (a manual "update firmware" button that ignores the flag), that needs the same gate.
Why now
This will get worse rather than better — more non-Nyquist devices are coming, each with independent firmware and versioning. A per-device-family firmware source is the eventual shape, but the immediate need is just: do not offer a Nyquist image to something that is not a Nyquist.
Reproducing
Connect a Gloor IAQ board (TacunaDevelopment/Gloor_IAQ, firmware reports device_pn = "ESP32-S3", device_fw_rev = "0.1") over TCP :9760 or manual serial, and observe the firmware-update offer.
The app now connects to devices that are not Nyquist hardware and carry their own, separate firmware. It still offers them the Nyquist firmware release, because the outdated-check compares versions without ever looking at what the device is.
Concretely: a Gloor IAQ board (ESP32-S3,
device_pnnotNq*, own firmware versioning) connects over TCP and serial and gets flagged as having outdated firmware — because its version string sorts below the latest Nyquist release. Accepting that offer would flash PIC32 Nyquist firmware onto an ESP32-S3.Where
IsFirmwareOutdatedis set in two places, and neither considers device type:Daqifi.Desktop/ViewModels/DaqifiViewModel.cs:1469Daqifi.Desktop/Device/Firmware/FirmwareUpdateCoordinator.cs:845The only existing guard is at
DaqifiViewModel.cs:1458— skip if the device has noDeviceVersionproperty. That filters devices with no version at all, not devices with a version from a different product line. Any device reporting a version gets compared against the Nyquist release feed.Suggested fix
IStreamingDevice.DeviceTypealready exists (IStreamingDevice.cs:64) andDeviceTypeDetector.DetectFromPartNumbermaps onlynq1/nq2/nq3toNyquist1/2/3, everything else toUnknown. So the gate is available at both call sites — no new plumbing:Worth deciding explicitly how
DeviceType.Unknownshould behave. Defaulting Unknown → no update offered is the safe direction: a device the app cannot identify is precisely the one that should not be flashed with Nyquist firmware. It does mean a genuine Nyquist that fails to report its part number stops being offered updates, which is a visible-but-harmless regression, versus the current failure mode of offering a cross-family flash.Also worth checking the UI: if the update affordance keys off
IsFirmwareOutdatedalone, the fix above is sufficient; if anything else can reach the flash path (a manual "update firmware" button that ignores the flag), that needs the same gate.Why now
This will get worse rather than better — more non-Nyquist devices are coming, each with independent firmware and versioning. A per-device-family firmware source is the eventual shape, but the immediate need is just: do not offer a Nyquist image to something that is not a Nyquist.
Reproducing
Connect a Gloor IAQ board (
TacunaDevelopment/Gloor_IAQ, firmware reportsdevice_pn = "ESP32-S3",device_fw_rev = "0.1") over TCP:9760or manual serial, and observe the firmware-update offer.