-
Notifications
You must be signed in to change notification settings - Fork 23
New State of Health #235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New State of Health #235
Conversation
… health pre-repo organization to work with new repo structure)
… for boot count and flags
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
… into new-state-of-health
nateinaction
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a pretty great refactor from the old state of health. Thank you for extracting this functionality from functions.py. This feels like the start of a new "services" layer in pysquared.
While you were still building out the ina219 power monitor manager I remember us talking about how useful the protos could be in creating a generic state of health service. While not as customized as this implementation, in #240 I took a swing at spinning up a generic state of health service just to see what it could look like. How do you think of the generic model compares to what you have here?
Mikefly123
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noticed based on Nate's comments that there should be a slight change to the implementation of the system_voltage() and battery_voltage() calls!
Co-authored-by: JamesDCowley <jcowley04@hotmail.com>
nateinaction
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is on a good track. Talking with Michael, since there is nothing we can do on the satellite to fix an overheating condition we should slim this down so that we only care about battery charge.
|
@nateinaction I think it could go either way with keeping the temperature monitoring in here for flavor or splitting it off into a dedicated thermal manager / interface. It is true that right now there is not actually much we can do in response to our of range temperatures and it is mostly just a nice FYI for the ground operators. If you'd like I can see if someone on my team has some time to address the |
|
@Mikefly123 Just added new |
This appeases the typecheck CI Signed-off-by: Michael Pham <phamlongmichael@gmail.com>
|
Hey @yudataguy I think the updates look good, a few things to take a look at though:
|
Mikefly123
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @yudataguy! This update looks really great. Just one last comment before we go ahead and merge it in.
I was reading through and thinking about error handling / fault tolerance. I think if the power monitors start returning us None values rather than actual numbers we will probably be expecting errors to be thrown because the sensors are not actually reading anything or talking to us. As a result, we should be prepared to have to catch those errors in here and safely return a value that lets the rest of the system know the state of health is unknown.
Let me know what you think about my comments. If you agree with making a few tweaks, we can get this merged in right after they are done!
nateinaction
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good Sam! I had a few small comments about naming and one about removing a logic block that is no longer necessary with your refactor. Great job!
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Adds a new PowerHealth class to aggregate sensor readings and determine battery health states, alongside introducing a degraded_battery_voltage configuration parameter.
- Implements
PowerHealthwith states (NOMINAL,DEGRADED,CRITICAL,UNKNOWN) and extensive unit tests - Adds
degraded_battery_voltageto config loader, schema validation, docs, and test JSON - Updates existing config tests to verify the new parameter
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_power_health.py | New unit tests covering PowerHealth.get() and _avg_reading() |
| tests/unit/test_config.py | Added assertion for degraded_battery_voltage in config tests |
| tests/unit/files/config.test.json | Included degraded_battery_voltage entry in test JSON data |
| pysquared/config/config.py | Loads degraded_battery_voltage and adds schema validation entry |
| pysquared/docs/config.md | Documents the new degraded_battery_voltage config option |
| pysquared/power_health.py | Implements PowerHealth logic and averaging helper |
Comments suppressed due to low confidence (1)
pysquared/config/config.py:40
- Add a check to ensure
degraded_battery_voltagefalls betweencritical_battery_voltageandnormal_battery_voltageto prevent misconfiguration of thresholds.
self.degraded_battery_voltage: float = json_data["degraded_battery_voltage"]
| if reading is None: | ||
| func_name = getattr(func, "__name__", "unknown_function") | ||
| self.logger.warning(f"Couldn't get reading from {func_name}") | ||
| return |
Copilot
AI
Jul 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Explicitly return None instead of relying on an implicit return for clarity and to match the documented return type.
| return | |
| return None |
| return NOMINAL() | ||
|
|
||
| def _avg_reading( | ||
| self, func: Callable[..., float | None], num_readings: int = 50 |
Copilot
AI
Jul 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Consider making the default num_readings configurable or reducing it to improve performance in time-sensitive contexts, as 50 sensor calls per measurement may be high.
Mikefly123
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Sam!
These updates look great to me. Let's get this merged in!
It would be a little tricky to implement this on V4 boards, since not all of them will be connected to power monitors, but if you wanted to create a usage example for the v5x boards it would be pretty cool to see! We can tag up about this at the next software meeting or on Discord.



Summary
Closes #159 (finally). Created a new State of Health class to hold information from a bunch of sensors such as temperatures, voltage, current, etc. Will be used for upcoming Mode Manager to manage power states.
How was this tested
(Power monitor stuff is null but does work with a working battery board, but ours blew up)
Works on v4 flight boards with v2 battery boards. Make sure to import and add the
INA219ManagerandStateOfHealthintomain.pyon whatever version repo.main.pyFor v4 flight + v2 battery (will be added in upcoming PR to v4 and v5 boards):