Betatest - Renault ZE Services Binding

Hi Lars, Rudi,

okay. 1st step is to get pyze run. Details you can find here. Its very simple
If this runs fine, just add in the src status.py file following code:

    
#    print(
#        tabulate(
#            [v for v in vehicle_table if v is not None]
#        )
#    )

    headers = {'Content-Type': 'text/plain','Accept': 'application/json',}
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_RemainingRange/state', headers=headers, data='{:.1f}'.format(status['batteryAutonomy']))    
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_ChargeLevel/state', headers=headers, data='{}'.format(status['batteryLevel']))
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_RemainingEnergy/state', headers=headers, data='{}'.format(status['batteryAvailableEnergy']))
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_Milage/state', headers=headers, data="{} km".format(mileage['totalMileage']))
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_Location/state', headers=headers, data="{:.8f},{:.8f}".format(location['gpsLatitude'], location['gpsLongitude']))
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_Plugged/state', headers=headers, data=plug_state.name)
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_Charging/state', headers=headers, data=charge_state.name)
    #requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_ChargeRate/state', headers=headers, data="{}".format(status['chargingInstantaneousPower']))
    #requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_RemainingTime/state', headers=headers, data= status['chargingRemainingTime'])
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_ChargingMode/state', headers=headers, data=charge_mode.value if hasattr(charge_mode, 'value') else charge_mode)
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_BatteryTemp/state', headers=headers, data="{}".format(status['batteryTemperature']) )
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_LastUpdate/state', headers=headers, data=status['timestamp'])
    requests.put('http://YOUR_IP:8080/rest/items/RenaultZEServices_Zoe_ExtTemp/state', headers=headers, data="{}".format(hvac['externalTemperature']) )

As you can see, I just simply commented the print command and added some simple lines.
Keep in mind, this is a quick and dirty solution. would be more nice if I create a file with all items etc.

Appropriate items:

Group gZoe "Renault Zoe"
Number      RenaultZEServices_Zoe_ChargeLevel           "Batterielevel [%d %%]"                           
Number      RenaultZEServices_Zoe_RemainingRange        "Restreichweite [%.1f KM]"                        
Number      RenaultZEServices_Zoe_RemainingEnergy       "VerfĂŒgbare Energie [%d kWh]"                    
Number      RenaultZEServices_Zoe_Milage                "Kilometerstand [%.1f KM]"                        
Location    RenaultZEServices_Zoe_Location              "Koordinaten"                                     
String      RenaultZEServices_Zoe_Plugged               "Ladestecker [%s]"                       
String      RenaultZEServices_Zoe_Charging              "Ladezustand [%s]"                 
Number      RenaultZEServices_Zoe_ChargeRate            "Ladeleistung [%.2f W]"            
Number      RenaultZEServices_Zoe_RemainingTime         "Verbleibende Ladezeit [%.1f Min]"                  
String      RenaultZEServices_Zoe_ChargingMode          "Ladeverhalten [%s]"                 
Number      RenaultZEServices_Zoe_BatteryTemp           "Batterietemperatur [%d °C]"                  
Number      RenaultZEServices_Zoe_ExtTemp           "Außentemperatur [%d °C]"                  
DateTime    RenaultZEServices_Zoe_LastUpdate            "Letzter Server Anfrage [%1$tA, %1$td.%1$tm.%1$tY %1$tT]"  
String      RenaultZEServices_Zoe_VIN               "Fahrzeugdetails [%s]"                
String      RenaultZEServices_Zoe_Brand               "Fahrzeugdetails [%s]"                 
String      RenaultZEServices_Zoe_Model               "Fahrzeugdetails [%s]"                 
Switch      RenaultZEServices_Zoe_Refresh              "Server Refresh"                  {autoupdate="false"}

Sitemap:

Frame label="Zoe" {
Text item=RenaultZEServices_Zoe_ChargeLevel
Text item=RenaultZEServices_Zoe_RemainingRange
Text item=RenaultZEServices_Zoe_RemainingEnergy
Text item=RenaultZEServices_Zoe_Milage
Mapview item=RenaultZEServices_Zoe_Location height=10
Text item=RenaultZEServices_Zoe_Plugged
Text item=RenaultZEServices_Zoe_Charging
Text item=RenaultZEServices_Zoe_ChargeRate
Text item=RenaultZEServices_Zoe_RemainingTime
Text item=RenaultZEServices_Zoe_ChargingMode
Text item=RenaultZEServices_Zoe_BatteryTemp
Text item=RenaultZEServices_Zoe_LastUpdate
Text item=RenaultZEServices_Zoe_ExtTemp
Text item=RenaultZEServices_Zoe_VIN
Text item=RenaultZEServices_Zoe_Model
Text item=RenaultZEServices_Zoe_Brand
Switch item=RenaultZEServices_Zoe_Refresh mappings=[ ON="Refresh!" ]
			}

For refresh I added a rule:

rule "RenaultZEService_Zoe_Refresh_server"
when
	Item RenaultZEServices_Zoe_Refresh changed or
	Time cron "0 0 * * * ?" or
	System started
then
 	
    val results = executeCommandLine("sudo -u pi /usr/local/bin/pyze status --km", 100000)
   
    logInfo("results", "results " + results)

end

Note: you have have to add openhab into your sudoers:

sudo visudo -f /etc/sudoers.d/010_pi-nopasswd

and add:

openhab ALL=(ALL) NOPASSWD: ALL

I am still not ready with all items, and to highlight again: this is a quick and dirty solution. I didnt respect any coding rules etc


I will try to finish everything in the comming days and will update this thread.

Try, If you need support, let me know


Regards

3 Likes

Danke an shuo!!

Mit seiner Hilfe hat es jetzt auch bei mir geklappt.
Es muss nach dem hinzufĂŒgen der Zeilen in status.py noch
mit “sudo python3 setup.py install” compiliert werden und schon
rattert das ganze los!!

Ich bin Happy!

thanks a lot @shuo for your idea and code!!

i used some ideas to make pyze run in a docker-container since i don’t like to mess around with too many additional tools on my openHabian Pi. this way i have a clean, encapsulated service for querying the ZE-services and delivering the data to my openHab instance.
i will publish my code soon


@nabossha I am curious about your solution.

If somebody is interested, I added several rules like follows:

var Boolean MessageB = false

rule "RenaultZEService_Zoe_Refresh_server"
when
	Item RenaultZEServices_Zoe_Refresh received command ON or
   	Time cron "0 0/10 * * * ?" or 
	System started
    	
then
 	
    val results_status = executeCommandLine("sudo -u pi /usr/local/bin/pyze status --km", 500000)

    logInfo("resultsStatus", "results_Status " + results_status)
    val results_vehicle = executeCommandLine("sudo -u pi /usr/local/bin/pyze vehicles", 500000)
    logInfo("resultsVehicle", "results_Vehicle " + results_vehicle)
   // with autoupdate=flase should not be necessary, but sometimes it stuck
   Thread::sleep(2)
    postUpdate(RenaultZEServices_Zoe_Refresh,OFF)

end

rule "Zoe Home"
when
    Item RenaultZEServices_Zoe_Location changed  or
	//Time cron "1 * * * * ?" or
	System started

then

    val PointType home_location  = new PointType(new DecimalType(48.xxx), new DecimalType(8.xxx))
    val PointType Zoe_location = RenaultZEServices_Zoe_Location.state as PointType
    val int distance = Zoe_location.distanceFrom(home_location).intValue()
    // specify your preferred radius (in meters)
    if ( distance < 50) {
        zoe_Home.postUpdate(ON)
    } else {
        zoe_Home.postUpdate(OFF)
    }

end

rule "RenaultZEService_Zoe_send_broadcast_if_under_certain_limit"
when
	Time cron "0 0/10 * * * ?" or 
	System started
    	
then
 	if ((RenaultZEServices_Zoe_RemainingRange.state <= 100) && (MessageB == false) ){             
        
        sendBroadcastNotification("Achtung! Restreichweite: " + RenaultZEServices_Zoe_RemainingRange.state +"km Ladestatus: " + RenaultZEServices_Zoe_ChargeLevel.state + "%"  )
        MessageB = true

     } else (RenaultZEServices_Zoe_RemainingRange.state >= 100){
           MessageB = false

     }

end

The first rule simply update the items in either 10 minutes turnus or by using the refresh button.
The second rule is just showing if Zoe is in the garage or en route. (really just gadget)
The last one is sending a broadcast if the remaining range is below 100 km


And finally I added a alexa rule:


rule "Alexa_Status_Zoe"
when
    Item RenaultZEServices_Zoe_Routine changed to ON 

then
    Echo_Living_Room_TTS.sendCommand("Der Batteriestatus von der Zoe betrÀgt" + RenaultZEServices_Zoe_ChargeLevel.state + "Prozent und die Reichweite ist" + RenaultZEServices_Zoe_RemainingRange.state + "Kilometer.")
    RenaultZEServices_Zoe_Routine.sendCommand(OFF)
end

You have to create a item as follows:

Switch      RenaultZEServices_Zoe_Routine             "Routine"                [ "Switchable" ]

You have to add a routine in your Alexa app and simply switch the item.

Many gadgets, I know. But its nice to have:)

Are you using the PyZE script with a ZOE 50?
From the known issues list it seems it only works for ZOE40.
My ZOE 50 will arrive hopefully in October 


I have ZE50 and PYZE is working fine. Please use the updated version, since Renault did change something


1 Like

Hello,

i installed yesterday pyze and it worked fine till today afternoon.

Now i get the following error when i start pyze status or pyze login:
Traceback (most recent call last):

File “/usr/local/bin/pyze”, line 11, in

load_entry_point('PyZE==0.5.0', 'console_scripts', 'pyze')()                                                                                                                                                                                            

File “/usr/local/lib/python3.6/dist-packages/PyZE-0.5.0-py3.6.egg/pyze/cli/main.py”, line 69, in main

File “/usr/local/lib/python3.6/dist-packages/PyZE-0.5.0-py3.6.egg/pyze/cli/login.py”, line 15, in run

File “/usr/local/lib/python3.6/dist-packages/PyZE-0.5.0-py3.6.egg/pyze/api/credentials.py”, line 26, in inner

File “/usr/local/lib/python3.6/dist-packages/PyZE-0.5.0-py3.6.egg/pyze/api/gigya.py”, line 77, in account_info

File “/usr/local/lib/python3.6/dist-packages/PyZE-0.5.0-py3.6.egg/pyze/api/gigya.py”, line 126, in raise_gigya_errors

RuntimeError: Gigya returned error 403007: Invalid namespace 'accounts' or method 'getAccountInfo' or you do not have the required permissions to call it.

I installed pyze on another container - same problem

Any idea?

Hello,

Today the problem has solved itself. The login is possible again.

My ZOE arrived but I can’t get this to work :joy:
I am using PyZe 0.6.0 and that part is working:

... pyze status --km
--------------------  ------------------------------------------------
Battery level         99%
Available energy      51kWh
Range estimate        321.0 km
Plug state            Unplugged
Charging state        Not charging
Charge rate           0.00kW
Time remaining        0:20
Charge mode           scheduled
AC start at           Unavailable
External temperature  Unavailable
Battery temperature   20°C
Total mileage         289.9 km
Updated at            2020-11-06 11:31:36
Location              53.yx,7.yx as of 2020-11-06 11:31:05

But I am out of luck for the openHAB/Operating system part, the error message is:

sudo: Kein TTY vorhanden und kein »askpass«-Programm angegeben
sudo: no tty present and no askpass program specified

I’ve added openhab ALL=(ALL) NOPASSWD: ALL via visudo and added openhab user to sudoers.

Any ideas what I am missing?

Hi Sihui,

Did you create the items mentioned above?
Did you put the requests above mentioned in the script and compile again?

By excecuting the values should be visible in openhab.

Sudoers staff is just to run pyze automatically


Check the above mentioned points first.

Thx,

Yes, copied from your post.

Yes.

No, I am only seeing status NULL on all items:

Curl

curl -X GET --header "Accept: text/plain" "http://192.168.2.211:8080/rest/items/RenaultZEServices_Zoe_RemainingRange/state"

Request URL

http://192.168.2.211:8080/rest/items/RenaultZEServices_Zoe_RemainingRange/state

Response Body

NULL

Response Code

200

Response Headers

{
  "content-length": "4",
  "content-type": "text/plain",
  "server": "Jetty(9.4.20.v20190813)"
}

Did you compile pyze with your changes again? you have to change the file in src directory status.py and then excecute “python3 setup.py install” again.
What is the output after installation again?

That’s what I did in the first place.
I will start from scratch, how do I uninstall this?

no need to uninstall. just repeat the installation with the modified file. Thats it. Be careful and dont use spaces/tabs.

Thx. I repeated the whole process (with the same files) and now it is working. Thanks for sharing this :+1:

looks good.
Now, I would recommend to call the pyze script via crontab -e every minute

BTW: I used following transform:

OFF=unterwegs
ON=Garage

NULL=unbekannt ?
UNDEF=unbekannt ?
-=unbekannt ?

and the item:

Switch      zoe_Home                                    "Zoe @Home [MAP(zoe.map):%s]"

Looks more nice;)

Just for own purporses: Do you have recently any issues with reaching the Renault server? Since 1 or 2 weeks, its very hard to get an update and I dont know why


I just got the ZOE and am using the servers since one week.
In this first week I did not notice any delays: I am getting updates when the car is started, stopped, plugged in and plugged out. I think it is also updating when pre-conditioning.

thanks and have fun. Its really a nice car :wink:

1 Like

Hi Guys,
IÂŽm writing as a simple user of openhab 2.5 on a raspberry. I
have no idea about programming.
Untill Renauld changed the App for ZOE, i could manage the loading of Battery depending of batterylevel and solar-produktion. Now it ist impossible vor me! The procedure with PYZE seems very complicatet for somebody who has no experiance with programming.
Is there any chance to get a binding for silly users like me?
I know, it is a big wish without any consideration, but may be the corona-lockdown and/or the hollydays give you a little time?

Until that you may use a workaround if you have access to webspace with php support (sorry, German only):

Edit: English script version on github: