I am trying to set up a raspberry pi which measures the temperature and humidity in my room via a DHT22 sensor. I found a tutorial on youtube where the scripts and everything else is uploaded, but the python script won't work... I am new to python and I really don't know what to do now. I already searched for a solution, especially here on stackoverflow, but I didn't find anything working for me.
The error message looks like this:
python Temperature_Server_DHT.py
Traceback (most recent call last):
File "Temperature_Server_DHT.py", line 49, in <module>
SensorInforations = sensorCheckIfRegistered(Device_ID)
File "Temperature_Server_DHT.py", line 37, in sensorCheckIfRegistered
SensorData = json.loads(data)
File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
And my python script contains the following:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# import sys module
import sys
import json
import urllib
import time
import socket
import Adafruit_DHT
#Conf
BaseURL= "http://127.0.0.1/php/Backend.php"
NameSensor= "DHT22"
#
sensor = Adafruit_DHT.DHT22
ip = [l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")] [:1], [[(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)$
hostname = socket.gethostname()
def insertTempdata(TSensor_ID, Temperature, Humidity):
urllib.urlopen(BaseURL + "?Call=AddTempData&TSensor_ID=" + "\"" + TSensor_ID + "\"" + "&Temperature="+ Temperature + "&Humidity=" + Humidity)
def deviceCheckIfRegistered(IP, Hostname):
DeviceID = urllib.urlopen(BaseURL + "?Call=getDeviceID&IP=" + IP + "&Hostname=" + Hostname ).read()
print (DeviceID)
if(DeviceID != "null"):
return DeviceID
else:
return ""
def sensorCheckIfRegistered(DeviceID):
url= BaseURL + "?Call=getRegisteredTSensors&Device_ID=" + DeviceID
data = urllib.urlopen(url).read()
print (data)
if(data != "null"):
SensorData = json.loads(data)
return SensorData
else:
return ""
def readDHTSensors(TSensor_ID, GPIO):
humidity, temperature = Adafruit_DHT.read_retry(sensor, GPIO)
print 'Temperature: {0:0.1f}*C Humidity: {1:0.1f}%'.format(temperature,humidity)
insertTempdata(TSensor_ID, str(temperature), str(humidity))
if __name__ == '__main__':
Device_ID = deviceCheckIfRegistered(ip, hostname)
SensorInforations = sensorCheckIfRegistered(Device_ID)
if(Device_ID != "" and SensorInforations != ""):
try:
while True:
for element in SensorInforations:
if(str(element['Sensor']) == NameSensor):
readDHTSensors(element['TSensor_ID'], element['GPIO'])
time.sleep(1800)
except (KeyboardInterrupt, SystemExit):
# quit python script
print("Killed")
sys.exit(0)
else:
print("Device not registered")
sys.exit(0)
I hope that you can finally help me, if you need anything else from me just tell me!
Related
I would like to make a script in python that retrieves what I'm listening to in real time on Spotify and allow me to send the information to an Arduino,
But the problem is that my script refuses to run when my Spotify is turned off, knowing that I have other information that passes between my PC and my Arduino and if the script does not run most of the functions I created on my Arduino does not work anymore
So I would like my script to work also when I don't listen to music
Error : `
Traceback (most recent call last):
File "C:\Users\horvik\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\models.py", line 971, in json
return complexjson.loads(self.text, **kwargs)
File "C:\Users\horvik\AppData\Local\Programs\Python\Python310\lib\json\__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "C:\Users\horvik\AppData\Local\Programs\Python\Python310\lib\json\decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\horvik\AppData\Local\Programs\Python\Python310\lib\json\decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\horvik\Desktop\project.py", line 62, in <module>
serialDataToEncode = finishcpu + finishmem + get_current_track(ACCESS_TOKEN)
File "C:\Users\horvik\Desktop\Deskcompanionv1.py", line 25, in get_current_track
json_resp = response.json()
File "C:\Users\horvik\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\models.py", line 975, in json
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
`
I tried to use other entries from the spotify api like 'is_active' or 'is_playing' by adding them in an if/else hoping that I could not go through "response.json()" but I understood that I had to go through this one
there's probably something I'm missing that's why I'm making this post
if someone can help me.
code :
import psutil
import serial
import requests
import time
from pprint import pprint
SPOTIFY_GET_CURRENT_TRACK_URL = 'https://api.spotify.com/v1/me/player/currently-playing'
ACCESS_TOKEN = 'i use token'
serial = serial.Serial()
serial.baudrate = 9600
serial.port = "COM5"
serial.open()
# spotify section
def get_current_track(access_token):
response = requests.get(
SPOTIFY_GET_CURRENT_TRACK_URL,
headers={
"Authorization": f"Bearer {access_token}"
}
)
json_resp = response.json()
if json_resp['is_playing'] == True :
track_name = json_resp['item']['name']
artists = [artist for artist in json_resp['item']['artists']]
artist_names = ', '.join([artist['name'] for artist in artists])
spotifytracksplaying = track_name + " By " + artist_names
else :
spotifytracksplaying = "you are not lisenting music"
return spotifytracksplaying
while(1):
# cpu and ram usage section
cpu = psutil.cpu_percent(interval=1.2)
mem = psutil.virtual_memory().percent
if cpu < 10:
finishcpu = " " + str(cpu)
elif cpu < 100:
finishcpu = " " + str(cpu)
else:
finishcpu = str(cpu)
if mem < 10:
finishmem = " " + str(mem)
elif mem < 100:
finishmem = " " + str(mem)
else:
finishmem = str(mem)
# sending information
serialDataToEncode = finishcpu + finishmem + get_current_track(ACCESS_TOKEN)
serialDatatosend = serialDataToEncode.encode("UTF-8")
serial.write(serialDatatosend)
# Debugging
#print(serialDatatosend)
##print(get_current_track(ACCESS_TOKEN))
serial.close()
You can catch JSONDecodeError if resource by url dont response correct json.
from json.decoder import JSONDecodeError
try:
json_resp = response.json()
except JSONDecodeError:
# Not json. No data. Return err.
Thank you very much for your quick response, it works!
Here is my code now :
def get_current_track(access_token):
response = requests.get(
SPOTIFY_GET_CURRENT_TRACK_URL,
headers={
"Authorization": f"Bearer {access_token}"
}
)
try:
json_resp = response.json()
track_id = json_resp['item']['id']
track_name = json_resp['item']['name']
artists = [artist for artist in json_resp['item']['artists']]
link = json_resp['item']['external_urls']['spotify']
artist_names = ', '.join([artist['name'] for artist in artists])
spotifytracksplaying = track_name + " By " + artist_names
except:
spotifytracksplaying = "No music played"
return spotifytracksplaying
I am trying to make a TCP (Client and Server) in python to download a file that is available on the Server. I am a total beginner in networking in Python, and following a tutorial for this purpose. The problem I am getting is that whenever I try to download a file from the server I get this error:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
self.run()
File "/usr/lib/python3.4/threading.py", line 868, in run
self._target(*self._args, **self._kwargs)
File "fileServer.py", line 8, in RetrFile
sock.send("EXISTS " + str(os.path.getsize(filename)));
TypeError: 'str' does not support the buffer interface
FileServer.py
import socket;
import threading;
import os;
def RetrFile(name,sock):
filename = sock.recv(1024).decode();
if os.path.isfile(filename):
sock.send("EXISTS " + str(os.path.getsize(filename)));
userResponse = sock.recv(1024).decode();
if (userResponse[:2] == 'OK'):
with open(filename,'rb') as f:
bytesToSend = f.read(1024);
sock.send(bytesToSend);
while (bytesToSend != ""):
byteToSend = f.read(1024);
sock.send(bytesToSend);
else:
sock.send("ERR");
sock.close();
def Main():
host = "127.0.0.1";
port = 5003;
s = socket.socket();
s.bind((host,port));
s.listen(5);
print("Server Started.")
while True:
c , addr = s.accept();
print("Client connected ip : " + str(addr));
t = threading.Thread(target = RetrFile,args=("retrThread",c))
t.start();
s.close();
if __name__ == '__main__':
Main();
FileClient.py
import socket
def Main():
host = "127.0.0.1";
port = 5003;
s = socket.socket();
s.connect((host,port));
filename = input("Filename? -> ");
if (filename != "q"):
s.send(filename.encode())
data = s.recv(1024)
if (data[:6] == "EXISTS"):
filesize = long(data[6:])
message = input("File Exists, " + str(fielsize) + "Bytes, download? (Y/N)? -> ");
if (message == "Y"):
s.send("OK")
f = open('new_'+filename,'wb')
data = s.recv(1024)
totalRecv = len(data)
f.write(data)
while(totalRecv < filesize):
data = s.recv(1024);
totalRecv += len(data)
f.write(data)
print("{0:.2f}".format((totalRecv/float(filesize))*100 + "%Done"));
print("Download Complete!");
else:
print("File does not exist!");
s.close();
if __name__ == '__main__':
Main();
You need to be sending bytes to the socket, not a string. You can convert a string to a bytes with .encode() Try:
message = "EXISTS " + str(os.path.getsize(filename))
sock.send(message.encode())
As a side note, you don't need semicolons when using Python, so I would recommend removing them from your code.
I am having issues with this setup. In summary, once the user presses submit on a form then the data is passed to an RQWorker and Redis to process.
The error from rqworker is
23:56:44 RQ worker u'rq:worker:HAFun.12371' started, version 0.5.6
23:56:44
23:56:44 *** Listening on default...
23:56:57 default: min_content.process_feed.process_checks(u'http://www.feedurl.com/url.xml', u'PM', u'alphanumeric', u'domain#domain.com') (9e736730-e97f-4ee5-b48d-448d5493dd6c)
23:56:57 ImportError: No module named min_content.process_feed
Traceback (most recent call last):
File "/var/www/min_content/min_content/venv/local/lib/python2.7/site-packages/rq/worker.py", line 568, in perform_job
rv = job.perform()
File "/var/www/min_content/min_content/venv/local/lib/python2.7/site-packages/rq/job.py", line 495, in perform
self._result = self.func(*self.args, **self.kwargs)
File "/var/www/min_content/min_content/venv/local/lib/python2.7/site-packages/rq/job.py", line 206, in func
return import_attribute(self.func_name)
File "/var/www/min_content/min_content/venv/local/lib/python2.7/site-packages/rq/utils.py", line 150, in import_attribute
module = importlib.import_module(module_name)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
ImportError: No module named min_content.process_feed
Traceback (most recent call last):
File "/var/www/min_content/min_content/venv/local/lib/python2.7/site-packages/rq/worker.py", line 568, in perform_job
rv = job.perform()
File "/var/www/min_content/min_content/venv/local/lib/python2.7/site-packages/rq/job.py", line 495, in perform
self._result = self.func(*self.args, **self.kwargs)
File "/var/www/min_content/min_content/venv/local/lib/python2.7/site-packages/rq/job.py", line 206, in func
return import_attribute(self.func_name)
File "/var/www/min_content/min_content/venv/local/lib/python2.7/site-packages/rq/utils.py", line 150, in import_attribute
module = importlib.import_module(module_name)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
ImportError: No module named min_content.process_feed
23:56:57 Moving job to u'failed' queue
I have tried starting rqworker in a variety of ways
rqworker --url redis://localhost:6379
rqworker
views.py
from min_content import app
from flask import render_template
from .forms import SubmissionForm
from flask import request
from .process_feed import process_checks #this is the function that does the checks
from redis import Redis
from rq import Queue
def process():
feedUrl = request.form['feedUrl']
source = request.form['pmsc']
ourAssignedId = request.form['assignedId']
email_address = request.form['email_address']
conn = redis.StrictRedis('localhost', 6379, 0)
q = Queue(connection=conn)
result = q.enqueue(process_checks, feedUrl,source,ourAssignedId, email_address)
return 'It\'s running and we\'ll send you an email when its done<br /><br />Do another one'
process_feed has a function called process_checks which works as expected.
I know this is working because using the below line, instead of RQ, works fine.
do_it = process_checks(feedUrl,source,ourAssignedId)
The strange thing is that this all worked perfectly well before I closed my SSH connection to the VPS.
Running ps -aux returns this which indicates the redis is running
root 11894 0.1 0.4 38096 2348 ? Ssl Oct25 0:01 /usr/local/bin/redis-server *:6379
Restarting redis does nothing, nor does restarting apache2
sudo service redis_6379 start
sudo service redis_6379 stop
sudo service apache2 restart
I followed this guide exactly and like I said, this worked until I terminated the SSH connection to my VPS
I'm running in a virtual environment if that makes any difference, I am calling this within my WSGI file
min_content.wsgi
#!/usr/bin/python
activate_this = '/var/www/min_content/min_content/venv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/min_content")
from min_content import app as application
application.secret_key = 'blah blah blah
'
I have confirmed that the Redis server is running by adding this to the script
r = redis.StrictRedis('localhost', 6379, 0)
r.set(name='teststring', value='this is a test')
test_string = r.get(name='teststring')
print test_string
Running redis-cli returns 127.0.0.1:6379>
process_feed.py
import requests
import xml.etree.ElementTree as ET
import csv
def process_checks(feedUrl,source,ourAssignedId):
feed_url = feedUrl
source = source
ourAssignedId = ourAssignedId
all_the_data = []
#grab xml from URL
try:
r = requests.get(feed_url)
except Exception as e:
print "Failed to grab from " + feed_url
return "Failed to grab from " + feed_url
root = ET.fromstring(r.text)
for advertiser in root.iter('advertiser'):
assignedId = advertiser.find('assignedId').text
if assignedId==ourAssignedId:
#only process for PMs using our assignedId
for listings in advertiser.iter('listingContentIndexEntry'):
listingUrl = listings.find('listingUrl').text
print "Processing " + listingUrl
#now grab from URL
listing_request = requests.get(listingUrl)
#parse XML from URL
#listing_root = ET.xpath(listing_request.text)
if not ET.fromstring(listing_request.text.encode('utf8')):
print "Failed to load XML for" + listingUrl
continue
else:
listing_root = ET.fromstring(listing_request.text.encode('utf8'))
#'Stayz Property ID','External Reference','User Account External Reference','Provider','Address Line1','Active','Headline','Listing URL'
stayzPropertyId = '' #the property manager enters this into the spreadsheet
if not listing_root.find('.//externalId').text:
print 'No external Id in ' + listingUrl
listingExternalId = 'None'
else:
listingExternalId = listing_root.find('externalId').text
listingExternalId = '"' + listingExternalId + '"'
userAccountExternalReference = assignedId
print userAccountExternalReference
provider = source
addressLine1 = listing_root.find('.//addressLine1').text
active = listing_root.find('active').text
if not listing_root.find('.//headline/texts/text/textValue').text:
print 'No headline in ' + listingExternalId
headline = 'None'
else:
headline = listing_root.find('.//headline/texts/text/textValue').text
headline = headline.encode('utf-8')
if not listing_root.find('.//description/texts/text/textValue').text:
print 'No description in ' + listingExternalId
description = 'None'
else:
description = listing_root.find('.//description/texts/text/textValue').text
#now check the min content
#headline length
headline_length = len(headline)
headline_length_check = 'FAIL'
if headline_length<20:
headline_length_check = 'FAIL'
else:
headline_length_check = 'TRUE'
#description length
description_length_check = 'FAIL'
description_length = len(description)
if description_length<400:
description_length_check = 'FAIL'
else:
description_length_check = 'TRUE'
#number of images
num_images = 0
num_images_check = 'FAIL'
for images in listing_root.iter('image'):
num_images = num_images+1
if num_images <6:
num_images_check = 'FAIL'
else:
num_images_check = 'TRUE'
#atleast one rate
num_rates = 0
num_rates_check = 'FAIL'
for rates in listing_root.iter('rate'):
num_rates = num_rates+1
if num_rates < 1:
num_rates_check = 'FAIL'
else:
num_rates_check = 'TRUE'
#atleast one bedroom
#atleast one bathroom
#a longitude and latitude
#now add to our list of lists
data = {'stayzPropertyId':'','listingExternalId':listingExternalId,'userAccountExternalReference':userAccountExternalReference,'provider':provider,'addressLine1':addressLine1,'active':active,'headline':headline,'listingUrl':listingUrl,'Headline > 20 characters?':headline_length_check,'Description > 400 characters?':description_length_check,'Number of Images > 6?':num_images_check,'At least one rate?':num_rates_check}
#data_dict = ['',listingExternalId,userAccountExternalReference,provider,addressLine1,active,headline,listingUrl]
all_the_data.append(data)
files_location = './files/' + source + '__' + ourAssignedId + '_export.csv'
with open(files_location,'w') as csvFile:
#with open('./files/' + source + '_export.csv','a') as csvFile:
fieldnames = ['stayzPropertyId','listingExternalId','userAccountExternalReference','provider','addressLine1','active','headline','listingUrl','Headline > 20 characters?','Description > 400 characters?','Number of Images > 6?','At least one rate?']
writer = csv.DictWriter(csvFile,fieldnames=fieldnames)
writer.writeheader()
for row in all_the_data:
try:
writer.writerow(row)
except:
print "Failed to write row " + str(row)
continue
#send email via Mailgun
return requests.post(
"https://api.mailgun.net/v3/sandboxablahblablbah1.mailgun.org/messages",
auth=("api", "key-blahblahblah"),
#files=("attachment", open(files_location)),
data={"from": "Mailgun Sandbox <postmaster#.mailgun.org>",
"to": "Me <me#me.com>",
"subject": "Feed Processed for " + ourAssignedId,
"text": "Done",
"html":"<b>Process the file</b>"})
I'm trying to get my RPi to send temp data to Xively and I'm having a horrible time getting my code to work. This is the latest reponse I get when I run the python script...
Traceback (most recent call last):
File "xively1.py", line 11, in <module>
import xively # for Xively
File "/home/pi/xively/xively.py", line 11, in <module>
FEED_ID = os.environ["736915202"]
File "/usr/lib/python2.7/UserDict.py", line 23, in __getitem__
raise KeyError(key)
KeyError: '736915202'
Can someone explain to me what this means and what I need to do to correct? Thanks.
#!/usr/bin/env python
# This program reads two DS18B20 1-wire temperature sensors and sends the values to
# Xively https://xively.com/feeds/360495937
# tempF[0] is the reading from the outdoor tempersture sensor '28-0000059f6ece'
# tempF[1] is the reading from the indoor temperature sensor '28-0000059fa9ce'
outdoor = 0
indoor = 1
import xively # for Xively
import time
import datetime
import os # for 1-wire
import glob # for 1-wire
def read_temp_raw(): #a function that grabs the raw temperatures data from the sensors
f_1 = open(device_file[0], 'r') # first DS18B20
lines_1 = f_1.readlines()
f_1.close()
f_2 = open(device_file[1], 'r') # second DS18B20
lines_2 = f_2.readlines()
f_2.close()
return lines_1 + lines_2
def read_temp(): #a function that checks that the connections were good
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES' or lines[2].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t='), lines[3].find('t=')
tempC = float(lines[1][equals_pos[0]+2:])/1000, float(lines[3] [equals_pos[1]+2:])/1000
tempF = round(tempC[0] * 9.0 / 5.0 + 32.0,1), round(tempC[1] * 9.0 / 5.0 + 32.0,1)
return tempF
def send_to_Xively(TempF):
XIVELY_FEED_ID = "736915202"
XIVELY_API_KEY = "QA6mqStQIqCFLOXtA4tzxiFpv8cqHNaYr1MFjRZdrphGwxYN"
#def send_to_Xively(TempF):
now = datetime.datetime.utcnow()
try:
print "Sending to Xively...",
xivelyapi = xively.XivelyAPIClient(XIVELY_API_KEY)
xivelyfeed = xivelyapi.feeds.get(XIVELY_FEED_ID)
xivelyfeed.datastreams = [
xively.Datastream(id='temp0', current_value=round(TempF[outdoor],1), at=now),
xively.Datastream(id='temp1', current_value=round(TempF[indoor],1), at=now)
]
xivelyfeed.update()
print "OK"
except requests.HTTPError as e:
print "HTTPError({0}): {1}".format(e.errno, e.strerror)
# this part for the 1-wire DS18S20
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
#set up the locations of the sensors in the system
device_folder = glob.glob('/sys/bus/w1/devices/28*')
device_file = [device_folder[0] + '/w1_slave', device_folder[1] + '/w1_slave']
# main program
TempF = read_temp()
send_to_Xively(TempF)
The xively module is expecting the environment variable "736915202" to be set. It's not, so it's throwing an exception.
That seems like a very strange environment variable to have set, though. Is /home/pi/xively/xively.py a third-party module, or did you write it? If you wrote that file, but you expected calling import xively to import a third-party module, you should rename /home/pi/xively/xively.py to something else, and that will probably fix your problem.
public class AnimalPrinter
{
public void printDog()
{
System.out.println("dog");
}
public void printCat()
{
System.out.println("cat");
}
/* constructors not shown */
}
I have my rpi connected up to a digital scales via RS232, a MAX3232 serial port / ttl module connected into the GPIO. Successfully collected the weight data streaming from the scales using this code (data is in blocks of 20 and the weight is at 11 - 14). This prints it out locally in terminal:
import serial
import time
ser = serial.Serial("/dev/ttyAMA0")
read = ser.read(20)
def get_num(read):
return float(''.join(ele for ele in read if ele.isdigit() or ele == '.'))
while True:
print(get_num(read))
time.sleep(2)
This works great but my python code to send datastream to xively isn't so good.
def get_num(read):
return float(''.join(ele for ele in read if ele.isdigit() or ele == '.'))
# function to return a datastream object. This either creates a new datastream,
# or returns an existing one
def get_datastream(feed):
try:
datastream = feed.datastreams.get("(get_num(read))")
return datastream
except:
datastream = feed.datastreams.create("(get_num(read))", tags = "weight")
return datastream
def run():
feed = api.feeds.get(FEED_ID)
datastream = get_datastream(feed)
datastream.max_value = None
datastream.min_value = None
while True:
weight = get_num(read)
datastream.current_value = weight
datastream.at = datetime.datetime.utcnow()
try:
datastream.update()
except requests.HTTPError as e:
print "HTTPError({0}): {1}".format(e.errno, e.strerror)
time.sleep(5)
run()
It checks out OK in IDLE - but when run it generates an error as follows:
Traceback (most recent call last):
File "xivelycodescales.py", line 51, in <module>
run()
File "xivelycodescales.py", line 36, in run
datastream = get_datastream(feed)
File "xivelycodescales.py", line 32, in get_datastream
datastream = feed.datastreams.create("(get_num(read))")
File "/usr/local/lib/python2.7/dist-packages/xively/managers.py", line 416, in create
response.raise_for_status()
File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 773, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 422 Client Error:
I can see what the error type is - and had good help at the RPI forums. But can't figure out where I've gone wrong
Many thanks