Add thermostat house example demonstrating continuous states (#492) - #495
Open
jabrailkhalil wants to merge 1 commit into
Open
Add thermostat house example demonstrating continuous states (#492)#495jabrailkhalil wants to merge 1 commit into
jabrailkhalil wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #492 (idea 5, the thermostat house)
Fresh PR after the review of #494, which was closed by the maintainer: the first version derived the threshold limits from a setpoint by hand-wiring
observe(...)and rewriting the limits manually, while its README claimed the limits were reactive. The claimed mechanism and the code contradicted each other. This version builds the example the other way around.What changed vs #494
heat_on_temp/heat_off_tempare plainObservables, and eachThresholdwatches its limit directly.states.pysubscribes the threshold to its limit observable, so moving a dial mid-run re-arms the projected crossing with no call from the agent - the README now says exactly what the code does, and the derived-setpoint machinery is gone._rearmcorrects that state on the same dial change (heater on below the on-limit, off above the off-limit). The README states this explicitly rather than claiming "no explicit call" anywhere.app.pyexposes the two dials directly as sliders.The example
A single room: temperature as a
ContinuousState(base value + rate, extrapolated analytically), twoThresholds computing the exact crossing times for heater-on/heater-off, no step logic (the onlystep()samples the DataCollector for the plots). Layout follows the tram model:agents.py,model.py,app.py,README.md.What I verified
All of the following ran locally (Windows, Python 3.12, mesa main at commit
a5dfcd6, 2026-09-08):pytest test_examples.py -k ThermostatHouse- PASSED (the repo's auto-runner instantiates the model with no arguments and runsrun_for(10)).python model.py-run_for(50), temperature stays inside[heat_on_temp, heat_off_temp]after the cold-start transient (checked with assert inside the model's__main__).ruff check/ruff format --checkandcodespellclean on the example.app.pyimports cleanly withsolaraandmatplotlibinstalled.The behaviour checks above are the ones I personally ran; TBH on the Falsified-matrix front there is no suite in this repo to falsify against (the auto-runner only steps models), so the dial matrices in the PR are the evidence.
Mesa version
Built against Mesa main commit
a5dfcd6(2026-09-08). The example usesmesa.experimental.*APIs which may change without deprecation. Note: the CIbuild-prejob installs the latest published mesa (3.5.1) wheremesa.experimental.statesdoes not exist; thebuild-mainjob (mesa@main) is the one that exercises this example.AI assistance: this contribution was authored with the help of an AI coding agent (implementation and this description); the local verification listed above was performed by the agent.