Jump to content

Program Unwanted Behavior


DPerovich

Recommended Posts

I cannot, for the life of me, figure out how to get some program logic to work the way I intend it to work.  I want to control a small water pump, plugged into an Outdoor On/Off module.

When the temperature (from openweathermap) is > 40 degrees F, I was the put to run for 5 minutes, every hour, during the hours of 7am to 8pm, daily.

When the temperature is <= 40 degrees F, I would like the pump to run continuously.

The problem I am currently having is the when the temperature is over 40F, the pump runs for 5 minutes minutes, turns off for a brief second, then is switched right back on.

Any thoughts how I can model this logic?

 

Thanks.

Link to comment

@DPerovich

Please copy & pate the program here so somebody can review the logic you're currently using.

Right click on the program in question and select "Copy to clipboard". Then paste it as text into the forum post.

You might be able to do this with one program, but my guess is might be at minimum two programs. 

 

Link to comment

The best way I see is to use a state variable lets call it "sPumpMode" It's init value should be zero for startup.  It will be 1 when the temp is > 40 and 2 when the temp is <= 40

Program 1

If
        Temp > 40
AND $sPumpMode is not 1

then

      $sPumpMode = 1

--------------------------------------------------

 Program 2

if         Temp <=40
   AND $sPumpMode is not 2

then
            $sPumpMode = 2

---------------------------------------------------

Program 3

If
            7:00:00 am
      to  8:00:00 pm  (same day)
AND  $sPumpMode = 1

then

       repeat every 60 minutes
             Set Pump to on
             Wait 5 Min
             set pump to off

-------------------------------------------------------

Program 4

If
            8:00:01 pm
      to  6:59:59 am  (next Day)
AND  $sPumpMode = 1

then
       set pump to off

---------------------------------------------------------------

Program 5

             If $sPumpMode = 2
   AND  Pump is off

then

             Wait 3 seconds
             Set Pump to on.

-------------------------------------------------

Program 5 is written so that if something else turns the pump off it will get turned back on, the 3 second wait is there because without it and there's a program that (in error) keeps turning off the pump the admin console can become unresponsive, the 3 second wait will allow you a chance to stop.   In an emergency you could also set the $sPumpMode variable to anything other than 1 or 2 to momentarily stop the program.


The only other suggestion I have is set the temp a degree or two apart to prevent weirdness when the temp goes up and down between 39 and 41.

 

 

 

Link to comment
57 minutes ago, MrBill said:

The best way I see is to use a state variable lets call it "sPumpMode" It's init value should be zero for startup.  It will be 1 when the temp is > 40 and 2 when the temp is <= 40

Program 1

If
        Temp > 40
AND $sPumpMode is not 1

then

      $sPumpMode = 1

--------------------------------------------------

 Program 2

if         Temp <=40
   AND $sPumpMode is not 2

then
            $sPumpMode = 2

---------------------------------------------------

Program 3

If
            7:00:00 am
      to  8:00:00 pm  (same day)
AND  $sPumpMode = 1

then

       repeat every 60 minutes
             Set Pump to on
             Wait 5 Min
             set pump to off

-------------------------------------------------------

Program 4

If
            8:00:01 pm
      to  6:59:59 am  (next Day)
AND  $sPumpMode = 1

then
       set pump to off

---------------------------------------------------------------

Program 5

             If $sPumpMode = 2
   AND  Pump is off

then

             Wait 3 seconds
             Set Pump to on.

-------------------------------------------------

Program 5 is written so that if something else turns the pump off it will get turned back on, the 3 second wait is there because without it and there's a program that (in error) keeps turning off the pump the admin console can become unresponsive, the 3 second wait will allow you a chance to stop.   In an emergency you could also set the $sPumpMode variable to anything other than 1 or 2 to momentarily stop the program.


The only other suggestion I have is set the temp a degree or two apart to prevent weirdness when the temp goes up and down between 39 and 41.

 

 

 

YIKES!  5 programs to accomplish this.  Bummer that the eventing system makes this use case so complicated!  I'll give it a shot.

Link to comment
1 hour ago, Geddy said:

@DPerovich

Please copy & pate the program here so somebody can review the logic you're currently using.

Right click on the program in question and select "Copy to clipboard". Then paste it as text into the forum post.

You might be able to do this with one program, but my guess is might be at minimum two programs. 

 

Haha...figured I would need to do that, but was on a phone call with my boss while typing the original message.  Here is the latest iteration that I tried:

 

Coop Pump - Summer - [ID 0006][Parent 0001]

If
        From     7:00:00AM
        To       8:00:00PM (same day)
    And 'OpenWeatherMap' Temperature > 40.0°F
 
Then
        Run Program 'Coop Pump - 5min' (Then Path)
 
Else
        - No Actions - (To add one, press 'Action')

 

Coop Pump - 5min - [ID 0014][Parent 0001]

If
   - No Conditions - (To add one, press 'Schedule' or 'Condition')
 
Then
        Repeat Every  1 hour 
           Set 'Chicken Coop / Coop Water Pump' On
           Wait  5 minutes 
           Set 'Chicken Coop / Coop Water Pump' Off
 
Else
   - No Actions - (To add one, press 'Action')

 

Coop Pump - Winter v2 - [ID 0002][Parent 0001]

If
        'OpenWeatherMap' Feels Like <= 40.0°F
 
Then
        Set 'Chicken Coop / Coop Water Pump' On
 
Else
   - No Actions - (To add one, press 'Action')
 


I also tried various other programs too....didn't keep them all.  Even tried some with a state variable.  But I was always getting tripped up by a rapid cycling of the state variable when I used it.

Link to comment

You need some hysteresis in your programs.

Try using 41F to turn on cycling and 39F to turn on 100% run.

When the pump runs the sensor see an immediate temperature rise and the season changes for you programs. Add hysteresis in the form of temperature differential and/or time delays, or use MrBills method with a variable and temperature hysteresis. Either way this is going to take at least two programs to accomplish the differential hysteresis, and one or two cycling programs that don't interfere with each other.

 

Link to comment
14 hours ago, DPerovich said:

YIKES!  5 programs to accomplish this

I'm not sure how to react to that, I could have done it in 4 but the logic is more confusing to follow, you took 3... it's definitely not a one or two program issue because there are essentially 3 possible states.

14 hours ago, DPerovich said:

 

Coop Pump - Summer - [ID 0006][Parent 0001]

If
        From     7:00:00AM
        To       8:00:00PM (same day)
    And 'OpenWeatherMap' Temperature > 40.0°F
 
Then
        Run Program 'Coop Pump - 5min' (Then Path)
 
Else
        - No Actions - (To add one, press 'Action')

 

Coop Pump - 5min - [ID 0014][Parent 0001]

If
   - No Conditions - (To add one, press 'Schedule' or 'Condition')
 
Then
        Repeat Every  1 hour 
           Set 'Chicken Coop / Coop Water Pump' On
           Wait  5 minutes 
           Set 'Chicken Coop / Coop Water Pump' Off
 
Else
   - No Actions - (To add one, press 'Action')

 

The problem here is that every time the temp changes by .1 degree the If in the first program is re-evaluated, which will always interrupt the loop in the second program. 

14 hours ago, DPerovich said:
And 'OpenWeatherMap' Temperature > 40.0°F
14 hours ago, DPerovich said:
'OpenWeatherMap' Feels Like <= 40.0°F

Careful here... you're using two different temps.... "Temperature" and "Feels like", I'd recommend that you use Temperature for both.  "Feels like" is only an expression of human comfort, not the temperature at which water freezes.

Like I pointed out at the end of my original post, and was echo'd by @larryllix the temps should allow for hysteresis to prevent short cycling.   In my program 1 changing the temp to 41 and in program 2 changing to 39 would give it a nice 2 degree spread.

Link to comment

@DPerovich Another option is to use disable and enable. 

Prog1 

IF

temp >40 degrees

THEN:

enable  prog 2

disable prog 3

ELSE: 

Disable prog 2

Enable prog 3

Prog 2

IF

from 7am to 8pm

THEN

Repeat every hour, run pump, wait 5 minute, stop pump (your original coop pump THEN)

ELSE 

Stop coop pump

Prog 3

IF Temp is <=40

RUN Coop Pump

ELSE Stop Coop Pump

Link to comment
29 minutes ago, dbwarner5 said:

@DPerovich Another option is to use disable and enable. 

Prog1 

IF

temp >40 degrees

THEN:

enable  prog 2

disable prog 3

ELSE: 

Disable prog 2

Enable prog 3

Prog 2

IF

from 7am to 8pm

THEN

Repeat every hour, run pump, wait 5 minute, stop pump (your original coop pump THEN)

ELSE 

Stop coop pump

Prog 3

IF Temp is <=40

RUN Coop Pump

ELSE Stop Coop Pump

I started with the enable/disable approach, as people who follow my example programs will know I use the technique frequently.   If taking this approach I'd still recommend breaking Program 1 into two parts, allowing for hysteresis, or temp gap between mode changes-- imagine a cool partly cloudy fall day with the temp hovering around 40, as the sun comes and goes the temp can very by a degree or two, on the other hand I'm not sure how often openweathermap updates the temp, if it only updates hourly that's built in hysteresis by time.

Another point is that if we switch temp ranges, enable/disable does not also run the program, in the case of program 3 being enabled there would be a delay until the next downward temp update before the pump turned on, and it may or may not get the off in the ELSE because there's no guarantee which would run first the "Else in program 3" or the "disable prog 3 in program 1"

As mentioned above to fix this method i would suggest:

Prog1 A

IF

temp >41 degrees

THEN:

disable prog 3
enable  prog 2
run prog 2 (if)

Prog1 B

IF

temp <=39 degrees

THEN:

Disable prog 2
Enable prog 3
Run prog 3 (if)

----------------------------------------------------------------------------------------------

This still leaves a problem tho... which can be solved by eliminating program 3:

Prog1 A

IF

temp >41 degrees

THEN:
enable  prog 2
run prog 2 (if)

Prog1 B

IF

temp <=39 degrees

THEN:

Disable prog 2
Set coop pump on

Prog 2

IF

from 7am to 8pm

THEN

Repeat every hour, run pump, wait 5 minute, stop pump (your original coop pump THEN)

ELSE 

Stop coop pump

--------------------------------

Which gets it done in 3 programs and is actually probably the most efficient solution.

 

Link to comment
4 hours ago, MrBill said:

I'm not sure how to react to that, I could have done it in 4 but the logic is more confusing to follow, you took 3... it's definitely not a one or two program issue because there are essentially 3 possible states.

The problem here is that every time the temp changes by .1 degree the If in the first program is re-evaluated, which will always interrupt the loop in the second program. 

Careful here... you're using two different temps.... "Temperature" and "Feels like", I'd recommend that you use Temperature for both.  "Feels like" is only an expression of human comfort, not the temperature at which water freezes.

Like I pointed out at the end of my original post, and was echo'd by @larryllix the temps should allow for hysteresis to prevent short cycling.   In my program 1 changing the temp to 41 and in program 2 changing to 39 would give it a nice 2 degree spread.

I didn't mean to question the approach, just that if I were coding this in script, I feel it would be so much easier to do.  I honestly don't spend MUCH time at all programming in my ISY...maybe I need to do more.

Your solution, @MrBill is working beautifully thus far.  I appreciate the level of detail in the solution and explanations you have given.  I had to lookup what the heck "hysteresis" was because I don't recall ever hearing the word before.  But it certainly makes 100% sense to me now!

Thank you again, to everyone who provided their input!!

Link to comment
1 hour ago, DPerovich said:

I didn't mean to question the approach, just that if I were coding this in script, I feel it would be so much easier to do.  I honestly don't spend MUCH time at all programming in my ISY...maybe I need to do more.

Your solution, @MrBill is working beautifully thus far.  I appreciate the level of detail in the solution and explanations you have given.  I had to lookup what the heck "hysteresis" was because I don't recall ever hearing the word before.  But it certainly makes 100% sense to me now!

Thank you again, to everyone who provided their input!!

As noted as the thread progressed there's always multiple ways to do things.  But your 100% correct... event based is a much different way of programing, and like all things there's more than one way to attack it.   When I replied last night I was short on time, so I just started typing.... backed up and one point and just did something I knew would work.  Now you have a number of examples!

Link to comment

Archived

This topic is now archived and is closed to further replies.


  • Recently Browsing

    • No registered users viewing this page.
  • Forum Statistics

    • Total Topics
      36.9k
    • Total Posts
      370.2k
×
×
  • Create New...