hello.
strange because telegram custom code version 1 work fine
but this new one, impossible to make it working…
job vas correct, like my_telegramV2.poll
and custom was my_telegramV2
and inside python code, def poll():
all is correct.
also my token and bot_chat id, I put this from old one
you did update from this post ?
strange it is not working…
thanks
me too
not working
but telegram version 1 work fine
strange
What v1 / v2 code are you referring to ?
the v1 is the first one you post there few months ago
v2 is the new one, with gps, co2 and other feature
Ah. So v1 is -
# send message to telegram
#
def bot_sendtext(bot_message):
send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + bot_chatID + '&parse_mode=Markdown&text=' + bot_message
requests.get(send_text)
and v2 -
# send message to telegram
#
def bot_sendtext(bot_message):
send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?' + urllib.urlencode({'chat_id': bot_chatID, 'parse_mode': 'Markdown', 'text': unicode(bot_message).encode('utf-8')})
requests.get(send_text)
So the change is using urllib.urlencode() - the intention here is to encode some characters ( such as the british pound sign ) as per api spec.
Maybe it works less well with other character sets ? Not sure.
What text ( exactly ) are you sending ?
Thanks.
I exactely copy - past your post without change. ``` si this one
Only I put my token and chat_bot ID. The same as V1
import logging
import requests
import pickle
import os
log = logging.getLogger(name)
Telegram tokens - see https://www.mariansauter.de/2018/01/send-telegram-notifications-to-your-mobile-from-python-opensesame/
bot_token = ‘759619847:AAEei0EZ0z7HfGWfaazvI6SAhb2ny-zx2oU’
bot_chatID = ‘735785677’
“”"
Poll to see if car is being charged. If so :
-
Disable auto sleep whilst charging
-
Send Telegram message when charging starts
-
Send Telegram message when charging reaches 80%
-
Send Telegram message when charging reaches 90%
-
Send Telegram message when charging reaches 100%
-
Send Telegram message when charging stops
“”"
def poll():enable sleep in case anything goes wrong below
enable_sleep()
load previous status
persistance = load()
check if we are driving or charging
driving = get_driving()
if driving == 1 or driving == -1:
if persistance[‘charging’] == True:
bot_sendtext(“Charge arrete. Derniere charge connu “+format(persistance[‘SOC’],’.1f’)+”%”)
persistance[‘charging’] = False
save(persistance)
return {“msg”: “Not charging”}now we are charging
disable_sleep()
batt_power = get_charging_power()
soc = get_soc()alert if just started to charge
if persistance[‘charging’] == False:
bot_sendtext("Voiture en charge a "+format(batt_power,’.2f’)+“kW. Etat de la batterie “+format(soc,’.1f’)+”%”)70% alert
#if soc >= 70 and persistance[‘SOC’] < 70:
bot_sendtext("Voiture en charge a "+format(batt_power,’.2f’)+“kW. Etat de la batterie “+format(soc,’.1f’)+”%”)
75% alert
#if soc >= 75 and persistance[‘SOC’] < 75:
bot_sendtext("Voiture en charge a "+format(batt_power,’.2f’)+“kW. Etat de la batterie “+format(soc,’.1f’)+”%”)
80% alert
if soc >= 80 and persistance[‘SOC’] < 80:
bot_sendtext("Voiture en charge a "+format(batt_power,’.2f’)+“kW. Etat de la batterie “+format(soc,’.1f’)+”%”)85% alert
#if soc >= 85 and persistance[‘SOC’] < 85:
bot_sendtext("Voiture en charge a "+format(batt_power,’.2f’)+“kW. Etat de la batterie “+format(soc,’.1f’)+”%”)
90% alert
if soc >= 90 and persistance[‘SOC’] < 90:
bot_sendtext("Voiture en charge a "+format(batt_power,’.2f’)+“kW. Etat de la batterie “+format(soc,’.1f’)+”%”)99.5% alert
if soc >= 99.5 and persistance[‘SOC’] < 99.5:
bot_sendtext("Voiture en charge a "+format(batt_power,’.2f’)+“kW. Etat de la batterie “+format(soc,’.1f’)+”%”)100% alert … not work because 100% is impossible
#if soc >= 100 and persistance[‘SOC’] < 100:
bot_sendtext("Voiture en charge a "+format(batt_power,’.2f’)+“kW. Etat de la batterie “+format(soc,’.1f’)+”%”)
each % alert
#lastsoc = persistance[‘SOC’]
#for level in xrange(1, 100):
#if soc >= level and lastsoc < level:bot_sendtext("Charging now at a rate of "+format(batt_power,’.2f’)+“kW. State of charge now “+format(soc,’.1f’)+”%”)
break
store status for next time
persistance[‘charging’] = True
persistance[‘SOC’] = soc
save(persistance)return {“msg”: "Charging at "+format(batt_power,’.2f’)+“kW, SOC now “+format(soc,’.1f’)+”%”}
send message to telegram
def bot_sendtext(bot_message):
send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + bot_chatID + '&parse_mode=Markdown&text=' + bot_message
log.info ("Sending message with "+bot_message);
requests.get(send_text)
load persistance
def load():
try:
persistance = pickle.load( open( ‘charge_status.p’, ‘rb’ ) )
except:
persistance = { ‘charging’: False, ‘SOC’: 0 }
return persistance
save persistance
def save(persistance):
pickle.dump( persistance, open( “charge_status.p”, “wb” ) )
delete persistance
def delete():
os.remove(“charge_status.p”)
check if we are driving. Returns :
0 - charging
1 - driving
-1 - can’t read data
def get_driving():
try:
args = [‘driving’]
kwargs = {
‘mode’: ‘220’,
‘pid’: ‘101’,
‘header’: ‘7E4’,
‘baudrate’: 500000,
‘formula’: ‘bytes_to_int(message.data[53:54])’,
‘protocol’: ‘6’,
‘verify’: False,
‘force’: True,
}
return (int(salt[‘obd.query’](*args, **kwargs)[‘value’])&4)/4
except:
return -1
get charging power
def get_charging_power():
args = [‘charging_power’]
kwargs = {
‘mode’: ‘220’,
‘pid’: ‘101’,
‘header’: ‘7E4’,
‘baudrate’: 500000,
‘formula’: ‘(twos_comp(bytes_to_int(message.data[13:14])256+bytes_to_int(message.data[14:15]),16)/10.0)((bytes_to_int(message.data[15:16])*256+bytes_to_int(message.data[16:17]))/10.0)/1000.0’,
‘protocol’: ‘6’,
‘verify’: False,
‘force’: True,
}
return salt[‘obd.query’](args, **kwargs)[‘value’]-1.0
get display state of charge
def get_soc():
args = [‘soc’]
kwargs = {
‘mode’: ‘220’,
‘pid’: ‘105’,
‘header’: ‘7E4’,
‘baudrate’: 500000,
‘formula’: ‘bytes_to_int(message.data[34:35])/2.0’,
‘protocol’: ‘6’,
‘verify’: False,
‘force’: True,
}
return salt[‘obd.query’](*args, **kwargs)[‘value’]
enable autopi sleep
def enable_sleep():
args = [‘sleep’]
kwargs = {
‘enable’: True,
}
salt’power.sleep_timer’
disable autopi sleep
def disable_sleep():
args = [‘sleep’]
kwargs = {
‘enable’: False,
}
salt’power.sleep_timer’
I did try the french text from my console with v2 -
peter26@Kona $ my_charge_status.bot_sendtext "Charge arrete. Derniere charge connu 10%"
16e737229d31f230c9d241ab498c8cb8:
return: null
and got the message on my phone.
I also tried a re-copy and paste from github to my autopi config and still got the message on my phone.
So I’m still not sure why the v2 ( ie version on github ) doesn’t work for you.
Anything useful in the logs ?
Ok.
So i will copy past this from GitHub too and doing test do be sure all is ok.
I will see the log too and tell you.
Thanks
Hi,
I’m trying to get this working with the Ioniq but I’m not sure whats wrong…
Am i translating these wrong? 000_Rapid Charge Port CCS Plug 2101 {j:6}
From what I can tell the rapid charge should be 12:13, as in J
And &2^6 as in :6
These 3 all return 1 when the car is charing at a ‘normal’ plug.
def get_charging():
args = ['driving']
kwargs = {
'mode': '21',
'pid': '01',
'header': '7E4',
'baudrate': 500000,
'formula': 'bytes_to_int(message.data[12:13])',
'protocol': '6',
'verify': False,
'force': True,
}
return (int(__salt__['obd.query'](*args, **kwargs)['value'])&128)/128
def get_charging_chademo():
args = ['CCS Plug']
kwargs = {
'mode': '21',
'pid': '01',
'header': '7E4',
'baudrate': 500000,
'formula': 'bytes_to_int(message.data[12:13])',
'protocol': '6',
'verify': False,
'force': True,
}
return (int(__salt__['obd.query'](*args, **kwargs)['value'])&64)/64
def get_charging_normal():
args = ['J1772 Plug']
kwargs = {
'mode': '21',
'pid': '01',
'header': '7E4',
'baudrate': 500000,
'formula': 'bytes_to_int(message.data[12:13])',
'protocol': '6',
'verify': False,
'force': True,
}
return (int(__salt__['obd.query'](*args, **kwargs)['value'])&32)/32
I’ve also had no success with getting the Ignition, that should be:
000_BMS Ignition BMS Ignit. 2101 {ay:2}
def get_carState():
args = ['driving']
kwargs = {
'mode': '21',
'pid': '01',
'header': '7E4',
'baudrate': 500000,
'formula': 'bytes_to_int(message.data[53:54])', # Ignition
'protocol': '6',
'verify': False,
'force': True,
}
return (int(__salt__['obd.query'](*args, **kwargs)['value'])&4)/4
Any tips?
These seem reasonable to my eye.
I would try dumping the whole PID in the different cases. ie in the console -
obd.query test mode=21 pid=01 force=true
I had the same issue upon using the newer version. I watch the logs and discovered that I needed to delete the old persistent data file. Once I did that, it started working.
I do have one remaining issue that I wanted to make time to fix and open a PR for, and that is a bug where if you have multiple charge sessions without using the car between, all is well at the end of the first session, but on the second session you’ll receive a message per minute with incomplete data. I only notice this because I top up with solar power where possible, so don’t always complete a charge in one go.
Good catch, thanks. There is my_charge_status.delete
for this purpose, I added this to the comment block in the script.
I’ve not seen this myself but I’ll keep an eye out for it.
So far I’ve been unable to replicate this -
Turns out that the repeated charge thing was just coincidence. I think the actual issue may be to do with establishing location. Haven’t had a chance to dig in further yet.
I had delete all of charge_status V1.
Now I use only the last version. V2
I will see if it is working or not.
But we have same car, so it should be ;).
Okay, could be related to the location. If you see this again pls get your logs ( especially any stack traces ).
Its possibly worth catching exception on nearest_charger() -
# get nearest charger
#
def nearest_charger():
try:
location = get_location()
for charger in chargers:
lat1 = radians(charger['latitude'])
lon1 = radians(charger['longitude'])
lat2 = radians(location['latitude'])
lon2 = radians(location['longitude'])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
dist = 6373.0 * c
if dist < 0.02:
log.info('found local charger '+charger['msg'])
return charger['msg']
log.info('https://api.openchargemap.io/v3/poi/?output=json&distance=0.1&maxresults=1&latitude='+str(location['latitude'])+'&longitude='+str(location['longitude']))
result = requests.get('https://api.openchargemap.io/v3/poi/?output=json&distance=0.1&maxresults=1&latitude='+str(location['latitude'])+'&longitude='+str(location['longitude']))
for i in result.json():
return i['OperatorInfo']['Title']+', '+i['AddressInfo']['Title']+', '+i['UsageCost']
except:
log.info('Unable to get location')
return 'No local charger found'
i am best than you, lol
look at this ->
i am the best ecologic man in the world
I update now for translation in French:
alslo km. but for this I only change “wltp” value to 449 km
maybe it is ok like that
Caught this in the log today, so I’ll drop in the exception handling you suggested which should catch it:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/utils/schedule.py"
, line 894, in handle_func
ret['return'] = self.functions[func](*args, **kwargs)
File "/opt/autopi/salt/modules/my_charge_status.py", line 110,
in poll
bot_sendtext(nearest_charger())
File "/opt/autopi/salt/modules/my_charge_status.py", line 277,
in nearest_charger
location = get_location()
File "/opt/autopi/salt/modules/my_charge_status.py", line 272,
in get_location
return __salt__['ec2x.gnss_nmea_gga'](*args, **kwargs)
File "/var/cache/salt/minion/extmods/modules/ec2x.py", line 45
8, in gnss_nmea_gga
"utc": obj.timestamp.isoformat(),
AttributeError: 'NoneType' object has no attribute 'isoformat'
Working, but a lots of thing strange: