Greenhouse heater temperature control not reliable

Hi - I’m quite new to HA and ESPs so am still finding my way around. I have an ESP32 with DS1820B and attempting temperature control of a fan heater with a Shelly Plus 1 (factory configuration). Although the code below works (even though it generates errors in interrupting polling of the DS1820B), the use of ‘on_value_range’ is unreliable as the http call is a ‘one-shot’ and the greenhouse is at the bottom of the garden so wi-fi communication is not robust. I’ve spent days, literally, trying to find an alternative method (if/then/else) with two temperature values and separate actions, without success. I want to avoid involving HA as this should be a trivial problem and shouldn’t require use of the cavalry. I would prefer to avoid lamdas for the same reason (and this is also outside my area of knowledge). Please can anyone offer any solutions?

sensor:
  - platform: dallas
    address: 0x9d3ce1e380c92628
    name: "Greenhouse temperature"
    on_value_range:
      - above: 11.0
        then:
         - http_request.post:
            url: http://192.168.0.150/relay/0?turn=off
      - below: 9.0
        then:
         - http_request.post:
            url: http://192.168.0.150/relay/0?turn=on

Its not really that its unreliable, thats how it works and the docs describe it. You know there are esphome docs, right? I assume you spent days looking anywhere and everywhere but there, right? There is an example in the on_value_range section that does exactly what you say your looking for. You can do as many above/below w/seperate actions as you need… your not smoking the stuff in your greenhouse are you??

If the problem is that the http command doesn’t always work, perhaps use an on_value trigger instead, then separate if blocks for above 11 or below 9.

That way, your ESP will keep sending the command (e.g. on if it’s cold) — so long as your relay doesn’t mind being told to turn on when it is already on, that should improve reliability.

Obviously, totally untested:

sensor:
  - platform: dallas
    address: 0x9d3ce1e380c92628
    name: "Greenhouse temperature"
    on_value:
      then:
        - if:
            condition:
              lambda: 'return x > 11;'
            then:
              - http_request.post:
                  url: http://192.168.0.150/relay/0?turn=off
            else:
              - if:
                  condition:
                    lambda: 'return x < 9;'
                  then:
                    - http_request.post:
                        url: http://192.168.0.150/relay/0?turn=on

You do know there is a thermostat and climate component? If you want to trigger fans or heat/cool, whatever, this is probably what you want for your greenhouse.

Indeed - it’s the OTA one-shot trigger that is unreliable. The greenhouse is at the end of the garden where closer neighbours blast-out their ssids. It usually takes a few attempts to upload new ESP code down there by wi-fi but the protocol is designed to be robust. I thought of continually sending http requests while the temperature was over 11 or under 9 but I couldn’t find a way of configuring 2 conditions under one ‘on_value’. Two 'if’s don’t pass validation. I also tried ‘sensor.in_range’ unsuccessfully.

Are you saying my code doesn’t compile?

@Fallingaway24 Thanks. I didn’t know. I’ll investigate.

@Troon That’s the result I wanted. A very basic requirement so I would have expected to be able to do it without resorting to a lamda.

My other attempts didn’t pass the ESPHome device code validation before trying to compile and download

You can do multiple if statements but it all goes under a single “if”. The problem with your code is when it is it only sends an http once and only if its below the upper number and then crosses above it. You could easily do something where if it goes above X then send http every 60 seconds while its above that number.

You could certainly do it with sensor.in_range instead if you have some sort of ideological exception to lambdas:

The key is not using the top-level on_value_range though, because that only fires once at the threshold transition.

If it doesnt compile and you get errors, then post it here.

@Troon I tried sensor.in_range.

@Fallingaway24 I suspect the thermostat component will have another ‘one-shot’ limitation from reading the documentation.
I would have no problem repeating the Shelly instruction every minute (a bit of a waste, but never mind !), the problem I can’t solve is how to define two thresholds & actions.

Yet again I ask: did my code above not compile?

No, not necessarily. You can have it repeat sending your alert eirher a number of times or on a time interval. I posted a picture of an example for doing exactly that. Multiple ranges and actions.

Yet again, you ask if YOUR code compiled?

Thats what im asking you! Its your code, on your computer, that your trying to flash on your esp board plugged into that computer. How the F would i know? Did i say something that made you think im psychic?

When you try to flash the esp board does it compile and finish flashing the board? One of the clues is it will say “100% Complete”

That will only trigger once, though, on the value crossing the threshold:

Just off the top of your screenshot:

And like i said, you can repeat the action either a specific number of times or on a time interval or for as long as its above the threshold. Theres a trigger and an action. The trigger is crossing the threshold and the action is sending the http. Changing that code around around a little bit and using some automations, you can do whatever youd like.

Thanks for trying to help, but I can’t keep up with you both. Who’s replying to who? Two conversations (at least) going on. I can only try one thing at a time and give a result.
@Troon Sorry - I didn’t spot the else/if construct. I’ll try that.
@Fallingaway24 - I’m not sure what you’re trying to tell me regarding on_value_range. I can’t see how to keep sending my http request AND have 2 thresholds. Maybe I’ve been staring at the problem too long.

(More replies landing before I get chance to comment on earlier ones :crazy_face: :crazy_face:)

Its as easy as adding a ‘while’ condition. While the value is above X then do 1.2.3.4

Heres while and repeat.

@Troon his was the result of if/else if

Thanks. Try my edit, which indents the else block. Non-intuitively, else isn’t on the same level as if.