Ошибка 400 при отправке файла JSON в ThingSpeakPython

Программы на Python
Ответить
Anonymous
 Ошибка 400 при отправке файла JSON в ThingSpeak

Сообщение Anonymous »

В настоящее время у меня есть программа, которая берет данные с акселерометра, в частности ADXL345 от Adafruit, и записывает их в JSON с частотой дискретизации, определенной пользователем, а затем, по истечении периода времени, также определенного пользователем, отправляет этот файл JSON в ThingSpeak. Я могу изменить частоту дискретизации, изменив переменную update_interval.
Эта программа работает, когда я устанавливаю update_interval = 1. Он может успешно записывать данные акселерометра в файл JSON один раз в секунду, а затем загружать этот файл в ThingSpeak, в данном случае каждые 5 секунд.
Однако данные акселерометра составляют 1 Гц. мне это бесполезно, поэтому я хочу увеличить частоту дискретизации. Когда я устанавливаю update_interval = 0.01, насколько я могу судить, он может успешно записывать данные акселерометра в файл JSON, но затем не может загрузить файл JSON в ThingSpeak. Когда он пытается загрузить файл JSON, он выдает код ошибки 400, что означает, что запрос на загрузку не может быть выполнен из-за «плохого синтаксиса» [1]. Я не понимаю, почему это происходит, поскольку я не изменяю код, относящийся к загрузке файла JSON. Если бы кто-то мог мне помочь, это было бы очень признательно. Я всего лишь простой инженер-механик, впервые пытающийся изучить Python для своего проекта.
[1] https://www.mathworks.com/help/thingspeak/error-codes .html
Полный код:

Код: Выделить всё

#1. Import necessary libraries for the script
import sys
import json
import time
import os
import psutil
import requests
import busio
import board
import adafruit_tca9548a
import adafruit_bme680
import adafruit_adxl34x
import adafruit_sgp40
#import adafruit_ads1x15.ads1015 as ADS
import paho.mqtt.publish as publish
import string
import numpy as np

#from adafruit_ads1x15.analog_in import AnalogIn

i2c = busio.I2C(board.SCL, board.SDA)
tca = adafruit_tca9548a.TCA9548A(i2c)

#Define what channel each of the sensors are plugged into
bme680 = adafruit_bme680.Adafruit_BME680_I2C(tca[0])
accelerometer = adafruit_adxl34x.ADXL345(tca[1])
sgp = adafruit_sgp40.SGP40(tca[2])
#ads = ADS.ADS1015(tca[3])

#Set the sampling rate of the accelerometer to 800 Hz
accelerometer.data_rate = adafruit_adxl34x.DataRate.RATE_100_HZ

bme680.oversample_humidity = 2
bme680.oversample_temperature = 2
bme680.oversample_pressure = 2
bme680.oversample_filter = 2

ADC_CHANNEL = 0
GAIN = 1

#2. Define global variabesl that track the last connection time and last update time. Define time intervals to update the data, and post the data to ThingSpeak
last_connection_time = time.time()  #Track the last connection time
last_update_time = time.time()      #Track the last update time
posting_interval = 5               #Post data once every 5 seconds
update_interval = 0.01              #Write data to a JSON file in a defined amount of time

#3. Deinfe you ThingSpeak write API key and channel ID settings, along with the ThingSpeak server settings
write_api_key = "Y1S2TKIM4XTQHESF"
channel_ID = "2729406"
url = "https://api.thingspeak.com/channels/" + channel_ID + "/bulk_update.json" #ThingSpeak server settings
message_buffer = []

#4. Define the function httpRequest that sends data to ThingSpeak and prints the response code from the server.
#The response code 202 indicates that the server has accepted the request and will process it.
def httpRequest():
#Function to send the POST request to ThingSpeak channel for bulk update.
global message_buffer
bulk_data = json.dumps({'write_api_key':write_api_key,'updates':message_buffer}) #Format the json data buffer
request_headers = {"User-Agent":"mw.doc.bulk-update (Raspberry Pi)","Content-Type":"application/json","Content-Length":str(len(bulk_data))}
"""
# Save JSON data to a file before sending
timestamp = int(time.time())
filename = f"data_to_thingspeak_{timestamp}.json"
with open(filename, "w") as file:
file.write(bulk_data)
print(f"Data saved to {filename}")
"""
#Make the request to ThingSpeak
try:
print(request_headers)
response = requests.post(url,headers=request_headers,data=bulk_data)
print (response) #A 202 indicates that the server has accpeted the request
#input("Press enter to continue...")
except e:
print(e.code) #Print the error code
message_buffer = [] #Reinitialize the message buffer
input("Press enter to continue...")
global last_connection_time
last_connection_time = time.time() #Update the connection time

#5. Define the fucntion getData that returns the data
def getData():
#Function that returns the data from the array of sensors

#bme680
humidity = bme680.relative_humidity
temperature = bme680.temperature
pressure = bme680.pressure
gas_resistance = bme680.gas
#sgp40
#voc = sgp.raw
#adxl345
acc_x, acc_y, acc_z = accelerometer.acceleration
#acc_x, acc_y, acc_z = acceleration_rms()
#spw2430 and ADS1015
#channel = AnalogIn(ads, ADS.P0)
#mic_value = channel.value
return humidity,temperature, pressure, gas_resistance, acc_x, acc_y, acc_z
#6. Define the function updatesJson to continuosuly update the message buffer every 15 seconds

def updatesJson():
#Function to update the message buffer every 1 second with data.
#And then call the httpRequest function every 1 minute.
global last_update_time, last_connection_time

if time.time() - last_update_time >= update_interval:
# Create a message with sensor data
message = {}
message['delta_t'] = int(round(time.time() - last_update_time))
humidity, temperature, pressure, gas_resistance, acc_x, acc_y, acc_z = getData()
#message['field1'] = humidity
#message['field2'] = temperature
#message['field3'] = pressure
#message['field4'] = gas_resistance
message['field5'] = acc_x
message['field6'] = acc_y
message['field7'] = acc_z
#message['field8'] = mic_value
global message_buffer
message_buffer.append(message) #Add to buffer
print(f"Data added to buffer: {message}") #Debugging output
last_update_time = time.time() #Update last update time here
# If posting interval time has crossed 2 minutes update the ThingSpeak channel with your data
if time.time() - last_connection_time >= posting_interval:
httpRequest()
last_update_time = time.time()

#7. Run an infinite loop to continously call the function updatesJson every 15 seconds.

if __name__ == "__main__": #To ensure that this is run directly and does not run when imported
while True:
#If update interval time has crossed 1 second upates the message buffer with data
if time.time() - last_update_time >= update_interval:
updatesJson()
Я пробовал экспериментировать с различными другими частотами дискретизации, чтобы посмотреть, есть ли другие, которые также работают. Когда я устанавливаю update_interval = 0.5, код может успешно загрузить файл JSON в ThingSpeak. Однако если я увеличу частоту дискретизации, уменьшив update_interval, это тоже перестанет работать. Я искал решения в других местах, но безуспешно.

Подробнее здесь: https://stackoverflow.com/questions/792 ... thingspeak
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»