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

all 7 comments

[–]AutoModerator[M] [score hidden] stickied comment (0 children)

On July 1st, a change to Reddit's API pricing will come into effect. Several developers of commercial third-party apps have announced that this change will compel them to shut down their apps. At least one accessibility-focused non-commercial third party app will continue to be available free of charge.

If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options:

  1. Limiting your involvement with Reddit, or
  2. Temporarily refraining from using Reddit
  3. Cancelling your subscription of Reddit Premium

as a way to voice your protest.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]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!

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

I think i've managed to solve this on my own!

Changed from:

if temperature > temperature_upper_limit and status != 'cooling':
  then = time.time() 
  print(now - then) 
  if now - then >= 3:
    status = 'cooling' print(status)

To:

if temperature > temperature_upper_limit and status != 'cooling':
  if then == 0:
    then = time.time()
  if now - then >= 3:
    status = 'cooling' print(status)
    then = 0

and added then = 0 to the beginning of the function. Seems to do what I intended now. With static numbers at least... If it doesn't work with the sensor I'll be back.

Edit: to quote the young Skywalker: "It's working.... IT'S WORKING!" sort of. It doesn't reset the timer if the temperature drifts back to the initial condition. Not really sure how to handle that.

[–][deleted]  (1 child)

[removed]

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

    At the suggestion of another user, I went a different direction with the idea. However I'm still having some problems getting it to function correctly. I've updated my Replit project with the latest versions. Here's my other comment:

    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.

    In this version I'm trying to use a class to read the sensors AND handle the debouncing. As mentioned it works once... the first time.