EV car power management

New code for staying awake for the Ioniq BEV that works better and is smaller, it has to run at shorter intervals than the sleep timer.
I have it running every 2 minutes and the sleep timer is 300 sec (5 min).
The old code had to run at start and then at a longer interval than the sleep timer.
The new one can/should run several times within the sleep timer period.
What it does it just resets the sleep timer everytime it runs if charging or driving.
I think that the disable_sleep() can also be removed, but not 100% sure:

import os
import requests

BOT_TOKEN = '8888888888888888xxxxxxxxxxxx8888888888'
BOT_CHATID = '88888888888'

def poll():
    charging_ccs = get_charging_ccs()
    charging_normal = get_charging_normal()
    soc = get_soc()
    #if charging_ccs == 1 or (charging_normal != 1 and soc != -1):
    if charging_ccs == 1 or charging_normal == 1 or soc != -1:
        disable_sleep()
        enable_sleep()
        #bot_sendtext("sleep timer reset")
        return {"msg": "sleep timer reset"}
    #else:
        #bot_sendtext("sleep timer running")
        #return {"msg": "sleep timer running"}

# enable autopi sleep
def enable_sleep():
    args = ['sleep']
    kwargs = {
        'enable': True,
        'period': 300,
        'reason': 'charge status',
    }
    __salt__['power.sleep_timer'](**kwargs)

# disable autopi sleep
def disable_sleep():
    args = ['sleep']
    kwargs = {
        'enable': False,
    }
    __salt__['power.sleep_timer'](**kwargs)

def get_charging():
    try:
        args = ['charging']
        kwargs = {
        'mode': '21',
        'pid': '01',
        'header': '7E4',
        'baudrate': 500000,
        'formula': 'bytes_to_int(message.data[11:12])',
        'protocol': '6',
        'verify': False,
        'force': True,
        }
        return (int(__salt__['obd.query'](*args, **kwargs)['value'])&128)/128
    except:
        return -1

# get display state of charge
#
def get_soc():
    try:
        args = ['soc']
        kwargs = {
            'mode': '21',
            'pid': '05',
            'header': '7E4',
            'baudrate': 500000,
            'formula': 'bytes_to_int(message.data[33:34])',
            'protocol': '6',
            'verify': False,
            'force': True,
            }
        return __salt__['obd.query'](*args, **kwargs)['value']/2.0
    except:
        return -1

# Get Chrging CCS
def get_charging_ccs():
    try:
        args = ['CCS Plug']
        kwargs = {
        'mode': '21',
        'pid': '01',
        'header': '7E4',
        'baudrate': 500000,
        'formula': 'bytes_to_int(message.data[11:12])',
        'protocol': '6',
        'verify': False,
        'force': True,
        }
        return (int(__salt__['obd.query'](*args, **kwargs)['value'])&64)/64
    except:
        return -1

# Get charging 230V
def get_charging_normal():
    try:
        args = ['J1772 Plug']
        kwargs = {
        'mode': '21',
        'pid': '01',
        'header': '7E4',
        'baudrate': 500000,
        'formula': 'bytes_to_int(message.data[11:12])',
        'protocol': '6',
        'verify': False,
        'force': True,
        }
        return (int(__salt__['obd.query'](*args, **kwargs)['value'])&32)/32
    except:
        return -1

def bot_sendtext(message):
    send_text = 'https://api.telegram.org/bot' + BOT_TOKEN + '/sendMessage?chat_id=' + BOT_CHATID + '&parse_mode=Markdown&text=' + message
    requests.get(send_text)
2 Likes

I’ve copyed your new code and I’ve put my bot token and bot chadid but I can’t save the code when I put the create button in my autopi.

@ricard_ferre_jornet
I have no idea, I have never had any issues with create, save etc. Buttons they open windows and save etc.
Terry with another browser? I have inky used chrome.
You can always mail support, they are good at answering.

Is it the cloud that send out the custom code every time to reset sleep timer ?
or is the code on Autopi after update?
For me it works sometime and sometime it going to sleep anyway.
So i guess that i have could have bad conection when it going to sleep ?
I try now to increase the sleep timer and see if it workd better.

@jorgeli
I think it is all in the dongle, the code is saved to the dongle and executed there with local jobs.
With the new code the job needs to run at a much shorter interval than the sleep timer, the sleep timer is set in the code to 300 (5 min), what the code does is just resetting the sleep timer as defined in the code, see below.
If resetting the sleep timer without having the period defined it sets it to default which is I believe is 30 minutes
I have the job running every 2 minutes to make sure that it resets it at least twice in the sleep timer time span.

def enable_sleep():
    args = ['sleep']
    kwargs = {
        'enable': True,
        'period': 300,

The setting in the configuration of the dongle for the sleep timer is overwritten when the script is running.

Well is it local on the dongle ti don´t now what is wrong :roll_eyes:
I have the job for 2 min to ,but it’s like it doesn’t update every time and then it is power down?

Same when i test charge with only type 2 it is powering down ( have not test with CCS yet)

@jorgeli
Did you try to enter the command custom_code_name.poll e.g. my_sleep_reset.poll in the command prompt? What do you get then?
You should get ‘sleep timer reset
If you are driving or charging.

Hi
I have problem before when autopi is on but not conection to the cloud, and i think this was the problem this time to.
Because i take the sim card out and take the auto pi out from the car a while, and take it back again.
Now when i get to work it was online all the way and the position map show all the trip.

I will try today if the charge is reset the timer to :pray::pray::pray:

Have test the telegram message with no success.
But maybe this work to if the GSM modul is working now :smiley:

Thanks for all help .
I appreciate it very much :+1::+1::+1:

@AndersO and @el93mon how do I get the bot_chatid from telegram?
I found a echo bot that can tell me my own chatid, but can not figure out how to get the chatid for the bot?!?

Thx.

@Mikael_Madsen
Hi, when i did it I followed the steps in the guides.
Telegram (https://web.telegram.org ).
Check out the following to create a bot: https://www.sohamkamani.com/blog/2016/09/21/making-a-telegram-bot/

This is what you get from Telegram in the process:
You can also share your telegram contact to @get_id_bot to reveal their chat_id or forward a message, or send file or sticker to get their file ID
If you have any question or anything, please feel free to contact get_id_bot creator on @fredykardian, or join my channel @fredykardianchannel thanks.
Please Subscribe and leave any comments at my mini tutorial about telegram bot on Youtube https://www.youtube.com/watch?v=RO_W_EVCvt4

Thx. I did find the chatid :slightly_smiling_face:
I tested in a browser, pasting the api call, and it worked.
But I still can’t get it working in autopi. How can I test telegram in the terminal?
Or any other way to test…

Thx. :slight_smile:

Got it up and running now :slight_smile:

My Autopi has been on repair for 1 month,but now back in my Hyundai Ioniq electric again :slight_smile:
I have the stay awake code and for telegram when charging from AndersO.
But now it has been a few updates with new futures that the stay awake code is not optimal anymore?

Have some one find out another solution for Ioniq after updates to stay awake the autopi when driving?

Regard Jörgen

@jorgeli
Hi, I noticed the same.
I disabled the script I was using and instead configured the power management. It works ok, not perfect but most of the time it is kept awake correctly.
Supress sleep event regex i set to:
^vehicle/(obd|battery|battery)/(interface_connected|charging|charging_slow)

I tried changing the go to sleep event, but it doesn’t work as it resets it everytime the event happens. Instead i set the Critical level Voltage to 12.5 (and safety cut out to 12.4) so it goes to sleep when the car is not running or charging as the voltage drops below 12.5 almost immediatly.

Thanks :slight_smile:
I have tried that now but Autopi stay awake all the time anyway when set the Critical level Voltage to 12.5 (and safety cut out to 12.4).

Or maybe i miss something else in the power managment?
Think i get back to the stay awake script and see for another solution .
Regard Jörgen

@jorgeli
It should cut out when it goes under those levels, maybe your battery is better than mine. I looked at the battery levels and it never goes below around 12.9 when driving or charging and when not it drops pritty quickly to around 12.3 on my car. I assume that it will differ between 12V batteries in different cars.

@Malte
Could that be a solution for EV power management. To have an optional setting that disregards the other power settings and only checks the 12V battery voltage;
“12V battery power wake/sleep limit”: default 12.8 if above autopi on if below autopi sleep.

Regards
Anders

After testing over weeks I am happy with my solution for the Hyundai Kona:
I created the new events “vehicle/pwr/on” and “vehicle/pwr/off” and put them into the settings.

Custom code “my_powerevent” (run by cronjob every 1 minute but not on startup!):

import logging
import shelve
import time

log = logging.getLogger(__name__)

#started by cronjob every minute
def powerevent():
    #load global variables
    sh = shelve.open("ManfredsPowerEvent.slv")
    #read bms-relay from OBD
    try:
        args = ['Relay_BMS']
        kwargs = {
        'mode': '220',
        'pid': '101',
        'header': '7E4',
        'bytes': 64,
        'baudrate': 500000,
        'formula': 'bytes_to_int(message.data[12:13])',
        'protocol': '6',
        'verify': False,
        'force': True,
        }
        sh["bms"]=(int(__salt__['obd.query'](*args, **kwargs)['value'])&1)/1
    except:
        sh["bms"]=-1
    tnow=time.time()
    tdiff=tnow-sh["pwr_lastcall"]
    #reset power-state to unknown when last call was more than 7000sec
    #better to have more "power off" events than an empty battery!
    if tdiff>7000:
        sh["power_state"]=-1
    #check power status
    if sh["bms"]==1 and sh["power_state"]!=1:
        sh["power_state"]=1
        sh["cnt_power"] = 0
        __salt__["event.fire"]({}, "vehicle/pwr/on")
    if sh["bms"]!=1 and sh["power_state"]!=0:
        sh["cnt_power"] += 1
        #give me 10 minutes before power off event
        if sh["cnt_power"] >= 10:
            sh["power_state"]=0
            __salt__["event.fire"]({}, "vehicle/pwr/off")
    #close global variables
    #ret = {"bms":sh["bms"],"cnt_power":sh["cnt_power"], "power_state":sh["power_state"], "last_call":tdiff}
    ret = {"power_state":sh["power_state"],"call_duration":(time.time()-tnow)}
    sh["pwr_lastcall"]=tnow
    sh.close()
    return (ret)

Custom code “my_autostart” (run by cronjob on startup and once every month)

import logging
import shelve

log = logging.getLogger(__name__)


# autostart is cronjob only on startup (and 1 time every month)
def autostart():
    dummy = init_powershelf()
    return 1


# initialize global variables
# otherwise error if you read it and they are not present
def init_powershelf():
    try:
        sh = shelve.open("ManfredsPowerEvent.slv")
        sh["bms"] = -1
        sh["cnt_power"] = 0
        sh["pwr_lastcall"] = 14000.2
        # power state -1 is "unknown" -> on every reboot power event on or off will be fired
        sh["power_state"] = -1
        sh.close
    except:
        pass
    return 1

I am using the following under “settings/advanced/power”:

Critical Level
    Duration = 180
    Voltage = 12.3
Safety Cut-out
    Duration = 150
    Voltage = 12.20
Event Driven
    Delay = 120
    Event Regex = ^vehicle/pwr/off
    Period = 600
Suppress
    Event Regex = ^vehicle/pwr/on
Wake Trigger
    Voltage Change = +0.40
    Voltage Change Duration = 2000ms
    Voltage Level > 13.30
2 Likes

Hi Manfred,

I’m testing out your custom code on my Kona Ev, but I’m struggling in getting the cronjobs work: could you post/send me your configuration parameters for those as well?

Thanks for your time, cheers.

Hi,

image

image

Manfred

1 Like

Thanks, I’ll give it a try tomorrow: I guess I should see the cronjob description inside the events log, correct?

Update01: thanks a lot Manfred, I tested it and it works like a charm while driving, I’m testing with a charge in a couple of hours.

Update02: It’s working great during charging as well!

Great sharing from your side!

1 Like