Skip to content
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

Adjust temperature under usb power #142

Merged
merged 22 commits into from
Feb 12, 2023

Conversation

macifell
Copy link

@macifell macifell commented Jan 17, 2023

The problem:

When running on USB power the enviro indoor reports temperatures that are higher than the true values. This can easily be observed by connecting a battery pack and plugging and unplugging a usb power source, allowing several readings to be taken in each state.

#137
#134

The solution:

This fix allows configuration settings to be used to determine when and by how much to reduce the temperature. It also adjusts the relative humidity as this is dependent on the temperature. Although there are two new config settings, only one is intended to be modified manually - the usb_power_temperature_offset, since I'm not sure how much it will vary between models and under different circumstances.

Some code was added to automatically detect usb vs battery power and update the usb_power config setting, though it may take one reset iteration for the correct value to be used. Writing to the config file multiple times is not ideal, but is a rudimentary solution to persisting state between runs. There might be a better way to easily determine if we're on battery power vs. USB.

I only have access to an enviro indoor at the moment, so I did not attempt to fix the other models - though the same code can theoretically be used.

@macifell
Copy link
Author

I'm not sure what the policy is for adding options to the config file. These changes would either require that a user runs the setup process again or manually adds entries to the config file. A method for detecting and adding missing config settings could be added if it seems like that would be helpful, but for now I'm going to leave that out.

@ZodiusInfuser
Copy link
Member

Thanks for this PR @macifell! I haven't had chance to try this code out on hardware, but from looking over it I have a few comments / questions.

This fix allows configuration settings to be used to determine when and by how much to reduce the temperature. It also adjusts the relative humidity as this is dependent on the temperature.

Nice job! That should help a lot of the people who've been running on USB power, get more accurate readings.

Although there are two new config settings, only one is intended to be modified manually - the usb_power_temperature_offset, since I'm not sure how much it will vary between models and under different circumstances.

Config.py is intended for user configurable settings only. Although I get the idea of using it to store the usb state, the better way to do this (for this project anyway) would be to create a new file, which if present tells you the information you need. You can see several examples of this in the code, such as the one for reattempting upload:

enviro/enviro/__init__.py

Lines 428 to 430 in 8c33384

# write out that we want to attempt a reupload
with open("reattempt_upload.txt", "w") as attemptfile:
attemptfile.write("")

enviro/enviro/__init__.py

Lines 495 to 505 in 8c33384

if helpers.file_exists("reattempt_upload.txt"):
upload_count = cached_upload_count()
if upload_count == 0:
os.remove("reattempt_upload.txt")
return
logging.info(f"> {upload_count} cache file(s) still to upload")
if not upload_readings():
halt("! reading upload failed")
os.remove("reattempt_upload.txt")

That being said...

There might be a better way to easily determine if we're on battery power vs. USB.

At startup you can check the value of vbus_present to determine if the board was powered up from USB. That could help you get around your "one reset iteration" issue. Perhaps this could let you remove the need for file writing at all, but then perhaps knowing both the usb state at the end of the last run, and at the start of the current one, would help in your logic?

I'm not sure what the policy is for adding options to the config file. These changes would either require that a user runs the setup process again or manually adds entries to the config file. A method for detecting and adding missing config settings could be added if it seems like that would be helpful, but for now I'm going to leave that out.

For now, any additions to config.py should be treated as optional features. This is so that users buying new Enviro's are able to update them from factory firmware and have them still function without the need to reprovision. Therefore any new config variables should have try clauses around them to check for their existence. Look at the mqtt file for an example of how to handle this for your usb_power_temperature_offset:

try:
config.mqtt_broker_ca_file
except AttributeError:
config.mqtt_broker_ca_file = None

One thing missing from that mqtt example is any log message to encourage the user to update their config.py. You're welcome to add this to your PR 🙂

Hope this feedback is useful for you.

@@ -549,6 +549,12 @@ def sleep(time_override=None):
rtc.set_alarm(0, minute, hour)
rtc.enable_alarm_interrupt(True)

# always assume we're running on battery power until we know otherwise
if config.usb_power:
logging.debug("assume battery power in config")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor thing, but any logging should be correctly indented for the logs around it, with the appropriate symbol. e.g. logging.debug(" - assume battery power in config")


# compensate for usb power
usb_power = False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usb_power should not be in config.py. See comments within PR

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that makes sense. This started out with the intent that the user would set this, but then I wanted to see if I could change it automatically 🙂

@macifell
Copy link
Author

Thank you for all the comments @ZodiusInfuser ! I'm glad to hear there's a better way to check for battery power and I think that will help simplify this code. The policy on configuration settings also makes perfect sense and I'll update this PR based on your feedback.

@macifell
Copy link
Author

@ZodiusInfuser When you have a chance let me know what you think of these changes.

I put the config setting checks in a central place to see how that would look. Let me know if you think that's a good idea, or if you'd rather keep them separate.

Also, let me know if you'd like me to add the same logic for the other boards. I am reluctant to do this, since I don't have those models and can't test this code on them. It's possible each model might need it's own default offset value, I'm just not sure.

I've been running this code for a few days on my enviro indoor, switching back and forth between battery and usb power and the readings look very consistent to me - both temperature and humidity. They also agree with another sensor I have placed nearby.

main.py Outdated Show resolved Hide resolved
@ZodiusInfuser
Copy link
Member

Thanks for making those changes. I haven't had chance to test the code, but it's looking pretty good to me now. My only thought is if the call to add_missing_config_settings() should be moved up to around line 80, where config is first imported? It doesn't seem to depend on any parameters that get added to the code later on, unless I'm just not seeing it?

@ZodiusInfuser
Copy link
Member

Line 94 perhaps. After the provisioning has taken place?

@macifell
Copy link
Author

Line 94 perhaps. After the provisioning has taken place?

That's a great point. It does seem like this could run during the initial import, instead of in the startup method. I was a bit wary of running this code too early, but I think we should be safe running it right after the provisioning check.

@ZodiusInfuser
Copy link
Member

This is looking good now @macifell! I'll try and make some time to test it next week, but give me a nudge if you don't hear anything.

@macifell
Copy link
Author

macifell commented Feb 7, 2023

Thank you @ZodiusInfuser! Let me know how it goes.

@ZodiusInfuser
Copy link
Member

This has been tested on an enviro in our office and is giving readings that more closely match its neighbouring temperature sensors. I'll go ahead and merge this now. Thanks again @macifell!

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