Skip to content

Enhance fire management and sensor validation, update dependencies#19

Merged
CamSoper merged 17 commits intomainfrom
claude/review-codebase-suggestions-l6WB8
Mar 24, 2026
Merged

Enhance fire management and sensor validation, update dependencies#19
CamSoper merged 17 commits intomainfrom
claude/review-codebase-suggestions-l6WB8

Conversation

@CamSoper
Copy link
Copy Markdown
Owner

@CamSoper CamSoper commented Mar 8, 2026

No description provided.

claude and others added 17 commits March 7, 2026 06:34
When FireMinder detects the fire is out and activates the igniter for
reignition, the Smoker now switches to a minimal feed pattern (3s on,
57s off) instead of the normal cooking feed rate. This prevents
unburned pellets from flooding the firepot, which could cause a
dangerous temperature spike when they finally ignite.

https://claude.ai/code/session_016pJd48GAzYXL4BTXptpHxs
When Sear mode starts from cold, the fire is declared "started" as
soon as temp rises ~10F above ambient, but the fire is really just
smoldering. Sear then runs the auger at 100% duty cycle, flooding
the firepot and suffocating the developing fire. Meanwhile, fire
health monitoring doesn't activate until temp exceeds ~333F, so
nobody notices the fire is dying.

Fix: keep diverting to Smoke-rate feeding until grill temp reaches
the minimum setpoint (180F), giving the fire time to properly
establish before Sear goes full blast.

https://claude.ai/code/session_016pJd48GAzYXL4BTXptpHxs
When an RTD sensor glitches (loose wire, SPI noise, etc.), the raw
ADC value can produce wildly invalid temperatures (e.g., ADC=0
yields Infinity via division by zero). These bad values get averaged
into the 100-sample resistance buffer and flow straight through to
MQTT/Home Assistant, causing massive graph spikes.

Fix: validate each reading against a physically reasonable range
(-20F to 1000F) before enqueuing. Bad readings are silently dropped,
preserving the buffer of good values. If ALL readings are bad
(sustained sensor failure), the queue empties and returns NaN, which
Smoker.Temps already converts to -1 ("Unplugged" on display).

https://claude.ai/code/session_016pJd48GAzYXL4BTXptpHxs
Newtonsoft.Json was only used in SmokerProxy for deserializing the
status API response. Switch to System.Text.Json which is built into
.NET and already used by ASP.NET on the API side. Uses
PropertyNameCaseInsensitive to match ASP.NET's default camelCase
output. Removes the Newtonsoft.Json package reference.

https://claude.ai/code/session_016pJd48GAzYXL4BTXptpHxs
Create Inferno.Tests xUnit project with 32 tests covering:
- RtdArray: ADC-to-resistance conversion, resistance-to-temp math,
  boundary values (ADC=0 → Infinity, ADC=1023)
- Extensions: Clamp (double/int), IsCookingMode for all SmokerModes
- SmokerPid: control variable direction (below/above setpoint),
  NaN guard, setpoint updates
- FireMinder: GetFireCheckTemp for Smoke vs Hold modes, initial
  state, ResetFireStatus

Add GitHub Actions workflow (ci.yml) that runs build + test on push
to main and on PRs.

Also make RtdArray's static math methods internal (were private) and
add InternalsVisibleTo so the test project can access them.

https://claude.ai/code/session_016pJd48GAzYXL4BTXptpHxs
Replaces the Windows batch files with a cross-platform Pulumi
deployment that:
1. Publishes all three .NET projects locally (parallel)
2. Stops running services on the Pi via SSH
3. Copies published artifacts to the Pi via SCP
4. Installs/starts systemd services and enables them on boot

Uses Pulumi.Command provider for remote SSH commands and
CopyToRemote for file transfer. Configurable via Pulumi config
for host, user, remote path, and SSH key path.

Usage:
  cd Inferno.Deploy
  pulumi up

https://claude.ai/code/session_016pJd48GAzYXL4BTXptpHxs
…an up TODOs

- SmokerPid: change dT.Seconds (int, truncated) to dT.TotalSeconds
  (double). The old code divided by zero whenever the control loop
  ran faster than 1Hz, producing NaN/Infinity in the derivative term.

- Smoker constructor: remove accidental type declaration that
  shadowed the _cts field with a local variable, leaving the field
  null until ModeLoop initialized it. A SetMode call during that
  window would NullRef.

- Delete all publish.bat files (replaced by Pulumi deploy project).

- Remove Visual Studio IDisposable template noise (commented-out
  finalizers, "TODO: free unmanaged resources", "Do not change this
  code") from RtdArray, Display, RelayDevice, SmokerProxy, and
  SmokerBridge. Added GC.SuppressFinalize where it was missing.

https://claude.ai/code/session_016pJd48GAzYXL4BTXptpHxs
Installs .NET 10 SDK and restores NuGet packages on session start,
ensuring dotnet build and dotnet test work immediately in remote sessions.

https://claude.ai/code/session_016pJd48GAzYXL4BTXptpHxs
The FileArchive was evaluated eagerly during preview, before the
dotnet publish LocalCommand had run, causing a "no such file or
directory" error. Defer FileArchive creation using Output.Apply
so it's only resolved after the publish command completes.

https://claude.ai/code/session_01HUASjWkHthjtTH4B6sx7vL
Create publish directories upfront before resource registration so
FileArchive can compute hashes during preview. Previously the
directories only existed after dotnet publish ran, which doesn't
happen during preview.

https://claude.ai/code/session_01HUASjWkHthjtTH4B6sx7vL
… services; update service start triggers to depend on file changes
@CamSoper CamSoper merged commit 59ebb30 into main Mar 24, 2026
1 check passed
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