12-06-2022, 09:00 PM
12-07-2022, 01:13 PM
Mods, please pin such threads to the top of the "API" section!
03-05-2024, 09:39 AM
Hello guys,
sorry for the silly question but where can I see the working example? Is it a link somewhere or code embedded into JonLBs Post? I can’t see anything :S Thanks!!
03-06-2024, 03:45 AM
(03-05-2024, 09:39 AM)Pakiki Wrote: Hello guys, I was looking for some examples also, the only ones I have found so far are here: https://github.com/bluewave-studio/opena...les/python
03-06-2024, 08:04 AM
Looks like JonLB remove the contect of his post. You try to reach him directly.
03-14-2024, 06:40 PM
I have not removed the post content. When I click to edit the post, all of the content is there, but it will no longer be presented on the forum. This seems to be an issue with the forum software.
03-15-2024, 06:15 AM
Thank you for reporting. I've copy-paste it:
With the introduction of API support in OAP 15.0 and a few questions on the forum of how they can be used, I thought I'd share one small script that utilizes the API. I, like others, have a need for supporting multiple temperature sensors. In my case, I want to know the outside air temperature and the engine bay temperature so I have two 1-wire probes in those locations. The beauty of the 1-wire sensors is they each have a unique ID. So, I configured one of the descriptors in .openauto/config/openauto_system.ini to show up in the top bar. The second, I'm utilizing the API to inject my own OBD information. In addition, I wanted to have the RaspberryPi CPU temperature display on a dashboard. First, I created two gauges in .openauto/config/openauto_obd_gauges.ini. [ObdGauge_14] MinValue=-40 MaxValue=215 Limit=160 Formula=getPidValue(13) Label=°F Engine Bay Precision=0 [ObdGauge_15] MinValue=-40 MaxValue=120 Limit=80 Formula=getPidValue(14) Label=°C CPU Temp Precision=1 In the gauges, the formula is to get the PID value for PID 13 and 14 respectively. However, these PIDs are not defined in openauto_obd_pids.ini nor are they required, but we now have two PIDs we can update via the API. Then I created two dashboards with the gauges I want displayed. [ObdDashboard_0] Name=Topbar Title=Topbar Type=5 GaugeIndex_0=11 GaugeIndex_1=12 GaugeIndex_2=4 GaugeIndex_3=14 ... [ObdDashboard_3] Name=Detailed Title=Detailed dashboard Type=1 GaugeIndex_0=1 GaugeIndex_1=2 GaugeIndex_2=0 GaugeIndex_3=3 GaugeIndex_4=12 GaugeIndex_5=4 GaugeIndex_6=14 GaugeIndex_7=15 GaugeIndex_3 is set to my new Gauge ID of 14 (Engine bay temperature) and GaugeIndex_7 is set to ID 15 (CPU Temperature). I duplicated the ObdInject.py example script and modified it for my needs. #!/usr/bin/python3 # # Copyright © BlueWave Studio - All Rights Reserved # # Modified by JonLB for additional temperature probing # # Import common functions import sys import threading import time import common.Api_pb2 as oap_api from gpiozero import CPUTemperature from common.Client import Client, ClientEventHandler # Set global and tracking variables TEMPERATURE_SENSOR_DESCRIPTOR = '/sys/bus/w1/devices/28-012062ead71c/w1_slave' t_injecting_active = True def read_temp_raw(): f = open(TEMPERATURE_SENSOR_DESCRIPTOR, 'r') lines = f.readlines() f.close() return lines def read_temp(): lines = read_temp_raw() while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = read_temp_raw() equals_pos = lines[1].find('t=') if equals_pos != -1: temp_string = lines[1][equals_pos+2:] temp_c = float(temp_string) / 1000.0 temp_f = temp_c * 1.8 + 32.0 return temp_f def inject_obd_gauge_formula_value(client): obd_inject_gauge_formula_value = oap_api.ObdInjectGaugeFormulaValue() while t_injecting_active: for desc, formula, min_value, max_value in [("engine_bay_temp", "getPidValue(13)", -40, 215), ("cpu_temp", "getPidValue(14)", -40, 120)]: obd_inject_gauge_formula_value.formula = formula if desc == "engine_bay_temp": obd_inject_gauge_formula_value.value = read_temp() elif desc == "cpu_temp": cpu = CPUTemperature() obd_inject_gauge_formula_value.value = cpu.temperature else: obd_inject_gauge_formula_value.value = 0 client.send(oap_api.MESSAGE_OBD_INJECT_GAUGE_FORMULA_VALUE, 0, obd_inject_gauge_formula_value.SerializeToString()) time.sleep(30) class EventHandler(ClientEventHandler): def on_hello_response(self, client, message): threading.Thread(target=inject_obd_gauge_formula_value, args=(client, )).start() def main(): client = Client("obd inject example") event_handler = EventHandler() client.set_event_handler(event_handler) client.connect('127.0.0.1', 44405) active = True while active: try: active = client.wait_for_message() except KeyboardInterrupt: break global t_injecting_active t_injecting_active = False client.disconnect() if __name__ == "__main__": main() The script opens a TCP socket to the OAP API and stays open while the script runs in an infinite loop reading values and sending them to the API. Let's break it down a bit. Here we import additional libraries and set the temperature sensor descriptor to be used for the engine bay temperature gauge: # Import common functions import sys import threading import time import common.Api_pb2 as oap_api from gpiozero import CPUTemperature from common.Client import Client, ClientEventHandler # Set global and tracking variables TEMPERATURE_SENSOR_DESCRIPTOR = '/sys/bus/w1/devices/28-012062ead71c/w1_slave' I added two functions for reading the temperature sensor data and parsing it for injection: def read_temp_raw(): f = open(TEMPERATURE_SENSOR_DESCRIPTOR, 'r') lines = f.readlines() f.close() return lines def read_temp(): lines = read_temp_raw() while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = read_temp_raw() equals_pos = lines[1].find('t=') if equals_pos != -1: temp_string = lines[1][equals_pos+2:] temp_c = float(temp_string) / 1000.0 temp_f = temp_c * 1.8 + 32.0 return temp_f This next function sends the data to the API. It can be used to send OBD data for multiple PIDs simply by looping over an array/list: def inject_obd_gauge_formula_value(client): obd_inject_gauge_formula_value = oap_api.ObdInjectGaugeFormulaValue() while t_injecting_active: for desc, formula, min_value, max_value in [("engine_bay_temp", "getPidValue(13)", -40, 215), ("cpu_temp", "getPidValue(14)", -40, 120)]: obd_inject_gauge_formula_value.formula = formula if desc == "engine_bay_temp": obd_inject_gauge_formula_value.value = read_temp() elif desc == "cpu_temp": cpu = CPUTemperature() obd_inject_gauge_formula_value.value = cpu.temperature else: obd_inject_gauge_formula_value.value = 0 client.send(oap_api.MESSAGE_OBD_INJECT_GAUGE_FORMULA_VALUE, 0, obd_inject_gauge_formula_value.SerializeToString()) time.sleep(30) Since these particular temperatures don't change very frequently, nor do I need them to, I put a 30-second sleeper in between iterations. I then created a service file with the following (mine is /home/pi/scripts/openauto-pro-api/service/obd-inject.service): [Unit] Description=OAP ODB2 Injection Service ConditionPathExists=/home/pi/scripts/openauto-pro-api/bin/ObdInject.py StartLimitIntervalSec=60 StartLimitBurst=10 [Service] Type=simple ExecStart=/usr/bin/python3 /home/pi/scripts/openauto-pro-api/bin/ObdInject.py Restart=on-failure RestartSec=5 User=pi [Install] WantedBy=multi-user.target Then enable and start the service so the script runs at boot time and in the background. sudo systemctl enable /home/pi/scripts/openauto-pro-api/service/obd-inject.service sudo systemctl daemon-reload sudo systemctl start obd-inject.service Since I have OAP configured to display a Topbar OBD dashboard, the engine bay temperature shows in that space. My "Detailed Dashboard" now shows the engine bay temperature, CPU temperature, and any other gauges I've defined. |
|