Tesla Binding - wake up on demand

Hello everyone,

as far as I understand, it’s only possible with the Tesla binding to define that it always wakes up the car which results in large energy drains or to never wake up the Tesla.
What I would need is the possibility to wake up the Tesla on demand in an rule.

More specifically I have some rules to charge the car dependent on my photovoltaics production (or manual user input). But if the car is not charging it goes to sleep after some minutes and I have to wake it manually to be able to charge it again. Right now I send an notification to my phone when I should wake the car, but it would be way better if the rule simply wake the car automatically.

Had anyone has an idea how I could implement this?

Thanks and best regards :slight_smile:

I don’t have a Tesla but looking at the Binding Readme I see the following Channel

wakeup | Switch | Wake Up Wake up the vehicle from a (deep) sleep

Oh haven’t read this…

The question is, if this also wakes the car if the “allowWakeup” option is disabled that it doesn’t keep the car awake.

I will test it in the next days :slight_smile:

Hey again,

first of all I have to apologize my somewhat dump question, because it was stated in the official documentation…

I had the time to test it and it works like a charm. If the “allowWakeup” option is disabled, it’s still possible to wake the car by the “wakeup” switch.
The only issue I had was during the creation of the token for the car. I wasn’t able to create it in the console, because the username and password input where totally buggy. So I had to use the PaperUI which worked fine.

Thanks again and best regards!

1 Like

Hey Philip,

Would you mind sharing your rule? I plan to do the same and was just thinking which thresholds etc to use best. Cheers. Patrick

Hey Patrick,

of cause I can share my rules. But keep in mind, that I’m also kinda a beginner with OpenHAB and not a professional programmer. So the code definitely isn’t perfect :wink:

So maybe some considerations first:

  1. I’m getting my photovoltaic production values via Modbus from my SMA inverter. I need to know how much power is produced and how much is needed else where in the household
  2. I’m using an GOe-charger, because it’s somewhat cheap and has a quite open API. The only downside is, that it’s not possible to change the amount of phases used for charging via the API. My current solution is to have two plugs for it, one for 1 phase and one for 3 phases. So I have to change the amount manually. Also the amperage can only be changed by 1A steps, beginning with 6A up to 32A (16A for Tesla). This results in roughly 1400W to 3700W for 1 phase operation and 4100W to 11000W for 3 phase operation.
  3. I have an electrical boiler controlled via a smart plug for warm usage water. This is somewhat also considered in the rules.

The rules are divided into 3 parts:

  1. Check every 20 seconds what power is available for the charger
  2. Define the amperage for the charger depending on the check or user input
  3. Wake the Tesla if charging could start

The user inputs are the following (sorry for german variable/item names, the rules weren’t meant to publish :wink: ):

  • ChargerWunschleistungUser: The power the charger should output. -2 means off always, -1 the electrical boiler has priority, 0: Auto, >0 the define the power.
  • ChargerPVEigenverbrauch: How much percentage of the power the charger outputs should be from my own production. Because I pay less during the night, I have to produce at least 40% on my own that it’s worth charging the car. Anyway I have it most of the time on 70% or 90%.

Now to the code with a basic explanation. Please simply ask if you need further descriptions.

Checking each 20 seconds for the available power

First I check if the user input is above -1 which means it’s not turned off. Then I check if a car is connected to the charger. The variable “powerPurchaseAverage” gives the available power. For example if I produce 1000W and 200W is used, it’s 800W. The “Verlustfaktor” I use to somewhat take the power loss due heat generated in the cables. The target of the rule is to define the variable “ChargerSollLeistung” which will then be used in the next rule.

var double verlustFaktor

rule "Elektroauto Sollleistung einstellen"
when
    Time cron "8/20 * * * * ? *"   // alle 20 Sekunden mit 8 Sekunden Offset
then
    val int chargerWunschleistungUser = (ChargerWunschleistungUser.state as DecimalType).intValue

    if (chargerWunschleistungUser >= -1) {  // Wenn -2 dann immer aus, -1 => Boiler Prio, 0 => Auto, >0 => Manuelle Leistung
        val int chargerCar = (ChargerCar.state as DecimalType).intValue
        if (chargerCar == 1) {  // Kein Auto verbunden

        } else {
            if (chargerWunschleistungUser <= 0) {
                val int powerPurchaseAverage = (PowerPurchase.state as DecimalType).intValue

                // Verlustfaktor berechnen
                verlustFaktor = 1 + (0.035 / Math.pow(16, 2) * Math.pow((ChargerAmpere.state as DecimalType).doubleValue, 2))  // Annahme 3.5% bei 16A, 0% bei 0A. Quadratischer Zusammenhang

                val int chargerLeistung = ((ChargerLeistung.state as DecimalType) * 10 * verlustFaktor).intValue

                var int availableLeistung = powerPurchaseAverage + chargerLeistung

                if (chargerWunschleistungUser == -1 && !Boiler_UserInput.state.toString.contains("OFF")) {  // Bei Boiler Prio wird die verfügbare Leistung reduziert, falls sie höher ist als der Boiler Grenzwert.
                    if (OnOff_Boiler.state == OFF) {
                        var int grenzwertBoiler = (BoilerGrenzwertAuto.state as DecimalType).intValue

                        if (grenzwertBoiler < 11000) {
                            if ((Boiler_UserInputGrenzwert.state as DecimalType).intValue != 0) {
                                // User hat einen manuellen Grenzwert gesetzt
                                grenzwertBoiler = (Boiler_UserInputGrenzwert.state as DecimalType).intValue
                            }

                            if (availableLeistung > grenzwertBoiler) {
                                availableLeistung = availableLeistung - 4400
                            }
                        }
                    }
                }

                if (availableLeistung <= 0) {
                    if (ChargerSollLeistung.state != 0) {
                        ChargerSollLeistung.postUpdate(0)
                    }
                    if (AllowCharging.state == 1) {
                        sendHttpGetRequest("http://192.168.0.20/mqtt?payload=alw=0")
                    }
                } else {
                    ChargerSollLeistung.postUpdate(availableLeistung)
                }
            }
        }
    } else {
        if (AllowCharging.state == 1) {
            sendHttpGetRequest("http://192.168.0.20/mqtt?payload=alw=0")
        }
    }
end

Define the amperage for the charger

Well this may be overly complex, but it’s grown like this and I’m to lazy to optimize it :slight_smile:
So each time the “ChargerSollLeistung” or user input “ChargerWunschleistungUser” is changed, this rule will fire. Basically first it checks how much voltage is connected to the charger, which is used to calculate the power related to the amperage and secondly is used to determine how much phases are connected to the charger. If the power requested is higher than a threshold, it will send me a notification to my phone that I should change the amount of phases (different plug).
Then the code is divided into two scenarios:

  1. I’m below the minimum of 6A
  2. I’m above the 6A
    If it’s below the 6A the percentage needed to start the car charging is modified by 10%. So if it’s set to 60%, the charging will start when I produce 70% and stop when I produce 50%. The intention is to prevent to much starting and stopping of the charging.
    If it’s above 6A then I divide the requested power by the floor amperage. The rest of the division (for example if 7 is divided by 3 the result is 2.33. The 0.33 will be the rest) is compared to the percentage the user has inputted. If it’s below the user input, then the lower amperage is used, if it’s upper, the upper amperage is used.
    At the end the results are send to the charger via HTTP.
rule "Stromstärke am Laderegler Elektroauto eistellen"
when
    Item ChargerSollLeistung changed or
    Item ChargerWunschleistungUser changed
then
    val int spannungL1 = (ChargerSpannungL1.state as DecimalType).intValue
    val int spannungL2 = (ChargerSpannungL2.state as DecimalType).intValue
    val int spannungL3 = (ChargerSpannungL3.state as DecimalType).intValue

    if (verlustFaktor == null) {
        verlustFaktor = 1
    }
    val int summeSpannungen = ((spannungL1 + spannungL2 + spannungL3) * verlustFaktor).intValue
    var int chargerAmpere = (ChargerAmpere.state as DecimalType).intValue
    
    var double wunschleistung = 0
    if (ChargerWunschleistungUser.state > 0) {
        wunschleistung = (ChargerWunschleistungUser.state as DecimalType).doubleValue
    } else {
        wunschleistung = (ChargerSollLeistung.state as DecimalType).doubleValue
    }

    val double notwendigeAmpere = wunschleistung / summeSpannungen
    var double userEigenverbrauch = (ChargerPVEigenverbrauch.state as DecimalType).doubleValue / 100
    var double istEigenverbrauch = 0

    // Checken wie viele Phasen angeschlossen sind und ob etwas geändert werden sollte
    if (userEigenverbrauch >= 0) {
        val Number letzteBenachrichtigung = (LetzteBenachrichtigung.state as DecimalType)
        val Number minutenSeitLetzterBenachrichtigung = (now.millis / 60000) - letzteBenachrichtigung
        if (minutenSeitLetzterBenachrichtigung >= 30) {     // Nur alle 30 Minuten benachrichtigen
            if (summeSpannungen > 600) {  // 3 Phasen sind angeschlossen
                val double einPhasenAmpere = 2 * userEigenverbrauch     // 2 Ampere dreiphasig entsprechen 6 Ampere einphasig
                if (notwendigeAmpere < 5.5 && notwendigeAmpere >= einPhasenAmpere) {
                    Benachrichtigung.postUpdate("Anzahl Phasen auf 1 reduzieren")
                    LetzteBenachrichtigung.postUpdate(now.millis / 60000)
                }
            } else {    // 1 Phase ist angeschlossen
                if (notwendigeAmpere >= 19) {
                    Benachrichtigung.postUpdate("Anzahl Phasen auf 3 erhöhen")
                    LetzteBenachrichtigung.postUpdate(now.millis / 60000)
                }
            }                                                               
        }
    }
    
    
    if (notwendigeAmpere == 0) {
        chargerAmpere = 0
    } else if (notwendigeAmpere <= 6) {

        if (ChargerWunschleistungUser.state <= 0) {

            if (ChargerCar.state != 2) {   // Das Auto wird aktuell nicht geladen.
                userEigenverbrauch = userEigenverbrauch + 0.1
                if (userEigenverbrauch > 1.1) {
                    userEigenverbrauch = 1.1
                }
            } else {                    // Das Auto wird geladen
                userEigenverbrauch = userEigenverbrauch - 0.1
                if (userEigenverbrauch <= 0) {
                    userEigenverbrauch = 0.005
                }
            }

            istEigenverbrauch = wunschleistung / (6 * summeSpannungen)

            if (istEigenverbrauch < userEigenverbrauch) {
                chargerAmpere = 0
            } else {
                chargerAmpere = 6
            }
        } else {
            chargerAmpere = 6
        }

    } else if (notwendigeAmpere < 16) {
        val double restAmpere = notwendigeAmpere - Math.floor(notwendigeAmpere)
        if (restAmpere < userEigenverbrauch) {
            chargerAmpere = (Math.floor(notwendigeAmpere)).intValue
        } else {
            chargerAmpere = (Math.ceil(notwendigeAmpere)).intValue
        }
    } else {
        chargerAmpere = 16
    }

    if (chargerAmpere < 6) {
        if (AllowCharging.state != 0) {
            sendHttpGetRequest("http://192.168.0.20/mqtt?payload=alw=0")
        }
        if (ChargerAmpere.state != 6) {
            sendHttpGetRequest("http://192.168.0.20/mqtt?payload=amp=6")
        }
    } else {
        if (AllowCharging.state != 1) {
            sendHttpGetRequest("http://192.168.0.20/mqtt?payload=alw=1")
        }
        if (ChargerAmpere.state != chargerAmpere) {
            sendHttpGetRequest("http://192.168.0.20/mqtt?payload=amp=" + String.valueOf(chargerAmpere))
        }
    }

end

Wake the tesla

Should be pretty straight forward.

rule "Tesla bei Bedarf aufwecken"
when
    Item AllowCharging changed or 
    Item TeslaState changed or
    Item TeslaChargeLimit changed or
    Item TeslaChargingState changed
then
    if (TeslaState != "online" && AllowCharging.state == 1 && TeslaChargingState.state != "Disconnected") {
        if ((TeslaChargeLimit.state as DecimalType).intValue > (TeslaBatteryLevel.state as DecimalType).intValue) {
            TeslaWakeup.sendCommand(ON)
        }
    }
end

rule "Tesla aufwecken deaktivieren"
when
    Item TeslaState changed or 
    Item TeslaWakeup changed
then
    if (TeslaWakeup.state == ON) {
        if (TeslaState.state == "online") {
            TeslaWakeup.sendCommand(OFF)
        }
    }
end

Remarks

I only own the Tesla for 2 month which where winter time. So I couldn’t test it if I have a lot of power left. Most of the time it was to cloudy to really fully charge the car. But in the times I had some power, it worked like a charm.
The other thing is that the adjustments of the amperage a bit delayed. I plan to add a trend to the script knows a bit better how the power of the photovoltaic will be change to better set the amperage. This should be quite simple by using averageSince and calculate a linear trend. But I hadn’t the time for it yet.

I hope this helps. If any questions, please ask.

1 Like

I’m looking to implement a similar thing but don’t have the car to test it.
Basically my question is how to limit the amperage the car draws from your home/PV attached wallbox. Will it only work for a wallbox that has an open API (so in principle it would work with any car) ?
Or would that work by defining the chargecurrent or any other channel on the Tesla ? Is that a RW parameter after all that does what I want ? Or do those only work with a supercharger ?

Hey

I’m using a Go-e charger. There you have an API (http requests) to set the maximum allowed amperage. I never tested the Tesla API if it’s possible to set the amperage there, but if you are really interested, I could try it.
But I know that at the Tesla mobile app you only see the current charging amperage but can’t set a maximum. Changing the maximum amperage is only possible directly in the car, so I suspect the API is also read only.

Best regards

Ps.: It would be rather annoying if it would be possible with the Tesla API, because the main reason for my wallbox was to be able to charge the car in respect to the PV power. But at least with the wallbox I can also charge with 11kW if needed :slight_smile:

Please do if that’s not asked too much. I’ve just installed an openWB that can do this as well but I think it’s of widespread interest if you are free in choosing a wallbox or not. Your Go-e was a proper choice in any case as you can overrule whatever your Tesla does (they don’t always do what you want, do they … see their autopilot problems :expressionless: ) so no need to feel annoyed even if it worked. And it’s cheap so a good choice.

So, I defined the following items:

Number                 TeslaBatteryCurrent        {channel="tesla:model3:account:XXXX:batterycurrent"}
Number:ElectricCurrent TeslaChargeCurrent         {channel="tesla:model3:account:XXXX:chargecurrent"}
Number:ElectricCurrent TeslaChargeMaxCurrent      {channel="tesla:model3:account:XXXX:chargemaxcurrent"}
Number:ElectricCurrent TeslaChargerCurrent        {channel="tesla:model3:account:XXXX:chargercurrent"}
Number:ElectricCurrent TeslaChargerMaxCurrent     {channel="tesla:model3:account:XXXX:chargermaxcurrent"}

To check the current values I’ve put them into a sitemap:

Frame label="TeslaTest" {
	Default   item=TeslaBatteryCurrent    
	Default   item=TeslaChargeCurrent     
	Default   item=TeslaChargeMaxCurrent  
	Default   item=TeslaChargerCurrent    
	Default   item=TeslaChargerMaxCurrent 
}

All the values where 8.0 A currently, except TeslaBatteryCurrent which had no value (- A).
I created the rule to change everything to 6.0 A to test if the charging rate changes:

rule "TestingTesla"
when
    Item TestSwitch received update
then
    TeslaBatteryCurrent.sendCommand(6)
    TeslaChargeCurrent.sendCommand(6)
    TeslaChargeMaxCurrent.sendCommand(6)
    TeslaChargerCurrent.sendCommand(6)
    TeslaChargerMaxCurrent.sendCommand(6)
end

If I now change the TestSwitch all values change to 6.0 A as expected, but the car still charged with 8.0 A. So it seems, as supposed, that these values are just read-only and can’t be used to change the actual current used :disappointed:
After the next refresh, the values switched back to 10.0 A because the sun came out, except of TeslaBatteryCurrent which is most likely unsupported from the Model 3.

If I should try something else, please feel free to ask :slight_smile:

A pity, thanks though.

Is this still the case?
For some weeks now it is possible to set the charge current from the Tesla app too. This presumably is based on the same api.

Have you tried this since introduction of this featue into the app?

Hey Curlyel

no I haven’t tried it since, because it works quite well by setting the amperage with the GoE-charger. I also have some issues with the Tesla binding, that it’s quite unreliable and loses the connection way too often.

Thanks Philip,
meanwhile I’ve managed to get the Tesla binding connecting to the API. I had issues retrieving the required token… seems to be broken in openHAB (as in many other 3rd party applications too) since another API authentication change :frowning:

Anyway - I can answer myself now:
The charging current seems still read only. While the charge limit can be controlled from the binding the charge current can not.

When changing the allowed current via the Tesla app, the corresponding channel in the Tesla car thing within openHAB will be updated but not vice versa…

Seems like the current Tesla binding doesn’t support this.
But this “feature” is registred on github now.

[Tesla] Tesla add “set_charging_amps” from 2021.36 · Issue #11483 · openhab/openhab-addons · GitHub

to clearify/explain: the new feature to set the charging current via api is not yet implemented in the binding, (since its quite new and the binding seems to have not been touched in the last year). you can check out a more current set of features and api calls in the link from the Github issue, or in the teslapy REpo (GitHub - tdorssers/TeslaPy: A Python module to use the Tesla Motors Owner API).
I personally might rather try implementing a Teslapy script then trying to reprogram the Binding, but if someone else does it i will gladly support them in any way i can :-).

Greetings, Lukas

P.S: thanks Phuong for the mention, i tried searching for a matching openhab thread, but didnt find this one :smiley: .

3 Likes

Hello,
I do have problem connecting my Tesla3 to OH 3.2. Reading all the above - is it working or broken? I am not quite clear on that.

Hey @JoachimStrobel

no, overall the Tesla Binding works just fine for reading data from the vehicle.

But there are two issues which I’m aware of:

  1. Since recently, it’s possible to set the charging amperage from the Tesla App, so this should also be possible from the API and therefore with the Openhab Binding. Currently, this isn’t implemented.
  2. The Binding sometimes loses the connection and fails to reconnect automatically. If stopped and started manually, everything works fine again.

Regarding 1.
Tesla has some issues with setting the charging current from the app. For some reason mine is set for 15A, and no matter how many times I change it to 16A from the app, it will “reset” back to 15A again after finished charging.
If I change the current setting from the car, there is no issues.

So I wouldnt count on having current set to work from OH, untill Tesla has fixed it…
My TM3 has version 2021.44.30.11. App is the latest Android version.

Interesting, I see absolutely no issue when changing the charging current with the App with my Model 3.

There is an PullRequest ( https://github.com/openhab/openhab-addons/pull/12029 ) from Kai on GitHub which claims to solve this issue, so that it’s possible from setting the current in Openhab. I tried the latest Snapshot version of Openhab yesterday and it didn’t work, but maybe it’s not in the Snapshot version yet.