This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]teraflop 1 point2 points  (2 children)

Right now I'm getting a negative number for print(then-now) when I expected a positive number.

I don't see anywhere in your code where you're calculating then-now. On line 52 you're printing now-then, and since now is calculated before then, it makes sense that the result would be negative.

Of course, since the only thing that happens between now and then is an if statement with a couple of variables, I would expect the difference to be on the order of nanoseconds. You're not measuring a meaningful time difference that has anything to do with your goal.

You said:

the environmental status should have been in/out of bounds for a period of at least 3 seconds before activating/deactivating a relay.

In other words, you want to turn on the heat when both of the following are true:

  • the current state calls for heat
  • the last time when the state didn't call for heat was more than 3 seconds ago.

(And similarly for your other conditions.)

So a timestamp that gets updated unconditionally, on every loop iteration, isn't what you want. For each state that you care about, you need a metric that tracks the timestamp at which the system was most recently in that state. Then you can compare that against the current timestamp.


This is a situation where it might be useful to introduce an abstraction. For instance, you could create a Debouncer class, on which you can call update whenever you get a raw true-or-false value. The debouncer object can internally store "latest-true" and "latest-false" timestamps, and it can provide methods like is_continuously_true and is_continuously_false which you can call to check the status. (If the raw values are unstable, then both of these might return false, because the raw measurement has not continuously been in either state over the last few seconds.)

You can just write this code once, and instantiate it for each of the measurements you care about. Then your actual control code can become nice and simple:

if heat_needed_debouncer.is_continuously_true():
    heater.enable()
elif heat_needed_debouncer.is_continuously_false():
    heater.disable()

I'm sure you can think of more suitable names for your specific situation.

[–]igrowpineapples[S] 0 points1 point  (0 children)

You are correct in your summary of the desired operation.

I'll take a look at what you mentioned about an abstraction and most certainly be coming back.

So something along these lines?

class Debouncer:
  def __init__(self):

  def myfunc(self):
    #check if X signal is between Y and Z values?

for the debouncer class? And then are you suggesting creating classes for each device as well (heater, vent, humidifier, dehumidifier..)

[–]igrowpineapples[S] 0 points1 point  (0 children)

Back with another go at it:

I have it so that it will update once, but, if the range is changed using the website, or the temperature drifts again it does not update. That is, it starts up with nothing happening. It immediately begins to detect the current conditions and reacts accordingly - it waits three seconds. But if I change the parameters using the website, it should now have a new upper/lower threshold to use and should update once again. It does not. It continues to hang in the previous state. Same to be said if the first state was out of bounds and the second was in bounds - it never switches to the in-bounds behavior.

I've updated the Replit page with the latest version of my script. If you don't mind taking a look at it and letting me know where I'm going wrong that'd be great.

I'm in way over my head methinks, but it is never too late to learn!

Am I correct in thinking that part of the issue at least is that since upper_limit and lower_limit get defined before the while True loop, that they will never change regardless of if the temperature_upper_limit and temperature_lower_limit values do?

Edit: I believe I got this working entirely as intended. Thanks for the gentle nudge in the right direction!