TLDR: Python request session transmits data to API successfully for six hours and then suddenly only receives ConnectionErrors. Rate limits and other basic errors shouldn't be the issue as the application runs fine in the beginning.
I am using my Raspberry Pi 3 Model B V1.2 with a BME688 sensor to continuously transmit environmental data to openSenseMap. Here is the code of the application:
main.py:
RATE_LIMITS_TIME = 20
def main() -> None:
"""
Runs main process of recording and sending measurements to the OpenSenseMap.
live sensor measurements every ten seconds due to rate limits
"""
# create a single TCP connection
session = requests.Session()
while True:
try:
response = send_measurements_to_server(session)
except requests.exceptions.ConnectionError:
# renew session
session = requests.Session()
response = "-- CONNECTION FAILURE --"
except requests.exceptions.Timeout:
print("Request timed out, skipping this cycle")
response = "-- TIMEOUT --"
print(response,datetime.datetime.now())
time.sleep(RATE_LIMITS_TIME)
send_to_server.py:
def send_measurements_to_server(session: requests.Session) -> int:
opensensemap_url = "https://api.opensensemap.org/boxes/"
adjusted_url = opensensemap_url + SENSE_BOX_ID + "/data"
measurement = record_measurement()
body = {HUMIDITY_SENSOR_ID: [measurement.humidity],
TEMPERATURE_SENSOR_ID: [measurement.temperature],
AIR_PRESSURE_SENSOR_ID: [measurement.pressure],
GAS_RESISTANCE_SENSOR_ID: [measurement.gas_resistance]
}
response = session.post(adjusted_url, json=body, timeout=10)
return response
return_measurement.py:
def record_measurement() -> measurementClass:
"""Records and returns the measurement of the bme680 sensor"""
try:
sensor = bme680.BME680(bme680.I2C_ADDR_SECONDARY)
new_measurement = measurementClass(
sensor.data.temperature,
sensor.data.pressure,
sensor.data.humidity,
sensor.data.gas_resistance)
print(sensor.data.temperature,
sensor.data.pressure,
sensor.data.humidity,
sensor.data.gas_resistance)
except (RuntimeError, IOError):
# if the sensor fails during data collection we use replacement values
print("Sensor connection disrupted -- Using replacement values")
new_measurement = create_artificial_measurement()
return new_measurement
The problem I am having is that for some reason the code runs successfully for pretty much exactly six hours. After this time period each post to the API returns a ConnectionError. This is especially weird since when I then start a second instance of my application, the server can be reached and the requests are accepted (while the first instance is still receiving Errors). This lets me believe that it isn't a network issue either.
Something to point out is that I use randomly generated data points in return_measurement.py if my sensor ever disconnects from the raspberry pi. This is done to ensure that there is always data being sent. This is of interest as it can be seen from the logfile that the sensor reconnects just before the ConnectionErrors start to be thrown:
logfile:
28.2 962.51 33.837 102400000.0
<Response [201]> 2025-05-14 00:38:49.823012
28.15 962.51 33.847 102400000.0
<Response [201]> 2025-05-14 00:39:09.983847
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:39:30.056937
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:39:50.175899
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:40:10.262512
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:40:30.330664
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:40:50.450122
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:41:10.604180
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:41:30.702610
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:41:50.801585
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:42:10.918886
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:42:31.072819
Sensor connection disrupted -- Using replacement values
<Response [201]> 2025-05-14 00:42:51.151268
Sensor connection disrupted -- Using replacement values
Request timed out, skipping this cycle
-- TIMEOUT -- 2025-05-14 00:43:21.174376
28.02 962.53 34.613 102400000.0
-- CONNECTION FAILURE -- 2025-05-14 00:43:41.249583
$ From here on out only Connection Failures $
I have tried lots of variations to get rid of this bug, I have tried to create a new session instance for each request, only using a single session instance for the whole application run, currently I only generate a new session instance when I receive a ConnectionError.
By now I am pretty clueless as to what causes the bug. Is there a possibility that this stems from a garbage collector on the raspberry pi?
Thanks for the help in advance ^_^