Using HTML to output data from my RASPBERRY - python

heello
I build a raspberry temperature sensor. It works well. I can catch the temperature. I made a request on my raspberry file to communicate with my pc. But i got an internal server error :
I can't even go on my root page :
this i my code on my pc :
#app.route ('/')
def hello_world():
measures = []
query_sensor = models.Sensor.query.all ()
print (query_sensor)
for sensor in query_sensor:
query_mes = models.Measure.query.filter(models.Measure.sensor_id == sensor.id).all ()
measures += [{'serial':sensor.serial, 'measures':query_mes}]
print (measures)
return render_template('measures.html', data= query_mes)
#app.route('/data/measure', methods=['GET', 'POST'])
def page_data_measure ():
if request.method == 'POST':
data = request.form.to_dict()
print(data)
if 'serial' in data and 'value' in data and 'date' in data:
# recherche le capteur
sensor = None
query_sensor = models.Sensor.query.filter(models.Sensor.serial == data['serial']).first()
print (query_sensor)
if query_sensor is None:
sensor = models.Sensor (data['serial'])
database.db_session.add(sensor)
database.db_session.commit()
else:
sensor = query_sensor
mes = models.Measure (datetime.strptime(data['date'], '%Y-%m-%d %H:%M:%S.%f'), float(data['value']), sensor.id)
database.db_session.add (mes)
database.db_session.commit ()
else:
return 'Bad value', 422
return render_template('temperatures.html', data=mes)
this is the code with an api on the raspberry(writeme.py) :
import requests
import datetime
import time
from w1thermsensor import W1ThermSensor
sensor = W1ThermSensor()
print ("demarrer avec requete")
while True:
temperature = sensor.get_temperature()
data = {'date':datetime.datetime.now(), 'serial':'12345678', 'value':temperature}
r = requests.post("http://192.168.137.1:5000/data/measure", data=data)
print(r)
print("The temperature is %s celsius" % temperature)
time.sleep(1)
this is request result message :
the command that i run are : flask run -h 0.0.0.0
and on my raspberry are : python run writeme.py
thanks for your help

Related

Why does uploading data from Pi block UART Communication?

I have a waveshare TOF Laser Range Sensor (B) that I am using with my Raspberry Pi 3 Model B+. My main goal is to receive distance from the sensor and upload that data to ThingSpeak cloud platform. The first part of the code works well: I am receiving the distance and timestamp, along with signal status and data check from the sensor. However, when I try to upload the timestamp and distance values to the cloud platform, the sensor's data is is incorrect and will be values that have only 5-7 cm of variation, even though the object is very close to it. I have tried using async requests using the aiohhtp and ayncio libraries, to no avail.
Here is the demo code from the manufacturers of the sensor that I have modified to send async requests.
#coding: UTF-8
import RPi.GPIO as GPIO
import serial
import time
import chardet
import sys
import aiohttp
import asyncio
#ThingSpeak Cloud Write Definitions:
channel_id = "1853890"
write_api_key = "G22BQASFVWJT6T"
TOF_length = 16
TOF_header=(87,0,255)
TOF_system_time = 0
TOF_distance = 0
TOF_status = 0
TOF_signal = 0
TOF_check = 0
ser = serial.Serial('/dev/serial0',921600)
ser.flushInput()
#Async Function to upload Data
async def upload(timer, dist):
async with aiohttp.ClientSession() as session:
upload_url = "https://api.thingspeak.com/update?api_key=G22BQASFVWJT6TOH&field1=" + str(timer) + "&field2=" + str(dist)
async with session.get(upload_url) as res:
print('ok')
def verifyCheckSum(data, len):
#print(data)
TOF_check = 0
for k in range(0,len-1):
TOF_check += data[k]
TOF_check=TOF_check%256
if(TOF_check == data[len-1]):
print("TOF data is ok!")
return 1
else:
print("TOF data is error!")
return 0
while True:
TOF_data=()
timer=0
dist=0
time.sleep(0.01)
if ser.inWaiting() >=32:
for i in range(0,16):
TOF_data=TOF_data+(ord(ser.read(1)),ord(ser.read(1)))
#print(TOF_data)
for j in range(0,16):
if( (TOF_data[j]==TOF_header[0] and TOF_data[j+1]==TOF_header[1] and TOF_data[j+2]==TOF_header[2]) and (verifyCheckSum(TOF_data[j:TOF_length],TOF_length))):
if(((TOF_data[j+12]) | (TOF_data[j+13]<<8) )==0):
print("Out of range!")
else :
print("TOF id is: "+ str(TOF_data[j+3]))
TOF_system_time = TOF_data[j+4] | TOF_data[j+5]<<8 | TOF_data[j+6]<<16 | TOF_data[j+7]<<24
print("TOF system time is: "+str(TOF_system_time)+'ms')
timer = TOF_system_time
TOF_distance = (TOF_data[j+8]) | (TOF_data[j+9]<<8) | (TOF_data[j+10]<<16)
print("TOF distance is: "+str(TOF_distance)+'mm')
dist=TOF_distance
TOF_status = TOF_data[j+11]
print("TOF status is: "+str(TOF_status))
TOF_signal = TOF_data[j+12] | TOF_data[j+13]<<8
print("TOF signal is: "+str(TOF_signal))
#Calling async function to upload data:
asyncio.run(upload(timer, dist))
break
Here is the output when calling upload method:
Here is the output when not calling the upload method:
Can someone please explain what I am doing wrong and correct me?
Thanks!

Modbus TCP server with Python

I am starting a program using Python. I wanna send some informations of Python to Simply Modbus TCP Client. To be honest I really don't know to use Python, at the same time i`m learning Modbus.
The error messages I am getting is:
runfile('C:/Users/rafa_/OneDrive/Área de Trabalho/TCC_v.0/2/simhvac.py', wdir='C:/Users/rafa_/OneDrive/Área de Trabalho/TCC_v.0/2')
Erro: ("'Hvac' object has no attribute '_server'",)
My code is over there (somebody can help me):
from threading import Thread
from pyModbusTCP.server import DataBank, ModbusServer
from time import sleep
import time
class ServidorMODBUS():
""" Classe Servidor Modbus"""
def __init__(self, host_ip, port):
"""construtor"""
self._server = ModbusServer(host=host_ip, port=port, no_block=True)
self._db = DataBank
class Hvac(Thread):
def __init__(self):
Thread.__init__(self)
self.Ts = 0.5 # Sampling period in seconds
# Initial conditions
self.temperature = 25 # Initial temperature (Celsius degree)
self.co2 = 400 # Initial CO2 concentration (ppm)
self.humity = 33 # Initial Humidity (% RH)
self.number_of_occup = 1
self.co2_air_inlet = 200
self.T_air = 23
self.T_ac = 20
self.H_ac = 90
self.H_air = 90
# CO2 Parameters
self.co2_params = {
'a1': -0.8964,
'kn': 2.108,
'ki': 0.0579,
'kd': self.Ts
}
# Temperature Parameters
self.temperature_params = {
'beta_i1' : -1.179,
'beta_i2' : 0.2567,
'alfa_ac' : 0.0043,
'alfa_air' : 0.0762,
'alfa_0' : 0.0013,
'alfa_1' : -9.96E-4,
'alfa_I' : -3.06E-4
}
# Humity Parameters
self.humity_params = {
'delta_i1' : -1.6696,
'delta_i2' : 0.6844,
'gamma_ac' : -2.83E-4,
'gamma_air' : 0.0147,
'gamma_T' : 2.16E-4,
'gamma_0' : 0.0016,
'gamma_1' : 0.0018,
'gamma_I' : 4.98E-5
}
def run(self):
co2 = [self.co2, self.co2]
temp = [self.temperature, self.temperature]
humity = [self.humity, self.humity]
co2_il = [self.co2_air_inlet, self.co2_air_inlet]
"""Execuçao MODBUS"""
try:
self._server.start()
print("Servidor MODBUS online")
while True:
t = time.time()
# Process CO2, temperature, humity
(a1, kn, ki, kd) = self.co2_params.values()
n = self.number_of_occup
i = self.co2_air_inlet
d = 0 # disturbance
self.co2 = kn*n + ki*i + kd*d - a1*co2[0]
(beta_i1, beta_i2, alfa_ac, alfa_air, alfa_0, alfa_1, alfa_I) = self.temperature_params.values()
T_ac = self.T_ac
T_air = self.T_air
self.temperature = alfa_ac*T_ac+alfa_air*T_air+alfa_0*co2[0]+alfa_1*co2[1]+alfa_I*co2_il[1] - beta_i1*temp[0]-beta_i2*temp[1]
(delta_i1,delta_i2,gamma_ac,gamma_air,gamma_T,gamma_0,gamma_1,gamma_I) = self.humity_params.values()
H_ac = self.H_ac
H_air = self.H_air
self.humity = gamma_ac*H_ac+gamma_air*H_air+gamma_T*self.temperature+gamma_0*co2[0]+gamma_1*co2[1]+gamma_I*co2_il[1]-delta_i1*humity[0]-delta_i2*humity[1]
# Update delays
co2 = [self.co2, co2[0]]
temp = [self.temperature, temp[0]]
humity = [self.humity, humity[0]]
co2_il = [self.co2_air_inlet, co2_il[0]]
print('CO2:', self.co2, 'Temp:', self.temperature, 'Humidity:', self.humity)
time.sleep(self.Ts-(time.time()-t))
self._db.set_words(1000, co2, temp, humity, co2_il)
print("________________")
print("Tabela MODBUS")
print(f'Holding Register \r\n R1000: {self.db.get_words(1000)}\r\n R2000 {self.db.get_words(2000)}')
print(f'Coil \r\n R1000:{self.db.get_bits(1000)}')
sleep(1)
except Exception as e:
print("Erro: ", e.args)
The below screenshots show the error.
When posting a question on Stack overflow its good to include a minimum reproducible example because this makes it easier to for others to quickly assess your issue (and in many cases you will solve the issue yourself when creating the example). The code you pasted (including that in the screenshots) can be reduced to (try here):
from threading import Thread
class Hvac(Thread):
def run(self):
try:
self._server.start()
except Exception as e:
print("Erro: ", e.args)
HvacSim = Hvac()
HvacSim.start()
running this gives the same error you are receiving:
Erro: ("'Hvac' object has no attribute '_server'",)
You can actually simplify this further by removing the try/catch which will result in a different (and more helpful) error message (telling you the line the error occurred etc).
Its likely you are thinking "but I defined _server here":
class ServidorMODBUS():
""" Classe Servidor Modbus"""
def __init__(self, host_ip, port):
"""construtor"""
self._server = ModbusServer(host=host_ip, port=port, no_block=True)
However that is within the class ServidorMODBUS and not Hvac (you don't actually appear to be using ServidorMODBUS at all). It's not really clear what you intend to do with ServidorMODBUS (I would guess you want to create an instance of this in the the __init__ for Hvac).

Flask-Socketio emits only for first message

Using Flask-Socketio and Flask-Mqtt:
#mqtt.on_message()
def handle_mqtt_message(client, userdata, message):
### Extract from Payload ###
payload_list = message.payload.decode().split()
time_list = [int(x) for x in re.split(r'[-T:.]', payload_list[2])]
tstmpObj = datetime(time_list[0], #Year
time_list[1], #Month
time_list[2], #Day
time_list[3], #Hour
time_list[4], #Minute
time_list[5] #Sec
)
### make dict from payload data ###
data = dict(mssid = random.randint(0,10000),
fduid = "FDU-"+message.topic[-6:],
evnty = payload_list[0],
tstmp = tstmpObj.strftime("%a, %d %b %Y - %I:%M:%S %p"),
locur = payload_list[1])
### Print dictionary ###
print(data)
### Real-Time Alert on webpage ###
socketio.emit('mqtt_message', data=data)
### Insert message into database ###
with create_app().app_context():
event = Evntlg(fduid = data['fduid'],
evnty = data['evnty'],
tstmp = tstmpObj,
locur = data['locur'])
db.session.add(event)
db.session.commit()
Socketio.emit() works only on First onMessage() and not after that.
I'm using application factory and also blueprints.
All received messages are still inserted into the database properly.
##EDIT##
Code related to monkey-patching - patching since before the app runs.
import eventlet
eventlet.monkey_patch()
from floodwatch import create_app, socketio
app = create_app()
if __name__ == "__main__":
socketio.run(app, host='localhost', port=5000, debug=True)
I have to CTRL-C in the terminal and start it again to get RT messages again - but that too only for the first time and never again for the same session.

Execute code in background after render page in Django

I have a script with twilio:
from twilio.rest import Client
def wa(testo):
client = Client()
# this is the Twilio sandbox testing number
from_whatsapp_number='whatsapp:+14155238886'
to_whatsapp_number='whatsapp:+39xxxxxxxxxx'
ts = 'Anomalia Rapportino ' + str(testo)
client.messages.create(body=ts,
from_=from_whatsapp_number,
to=to_whatsapp_number)
I imported this script in view and I have this def:
def grazieeprint(request, pk):
intermedio = get_object_or_404(IntermProd, pk=pk)
datilavoro = WhoWork.objects.get(pk=intermedio.work_id)
try:
return render(request, 'FBIsystem/thanksandprint.html', {'pkpreso': pk})
finally:
try:
appo = datilavoro.pezziorastima * 2
if datilavoro.pezziora >= appo:
testo = datilavoro.pk
subprocess.Popen([wa(testo)], shell=True)
except:
pass
I need to run 'wa(testo)' after django load the page because all the process of sending message take approx 15/20 sec.
I try whit 'try and finally' and whit 'subbrocess.Popen' but it send always the message before render the page.
Please help
TY
EDIT:
I try:
finally:
try:
time.sleep(1)
appo = datilavoro.pezziorastima * 2
if datilavoro.pezziora >= appo:
testo = datilavoro.pk
subprocess.Popen([wa(testo)], shell=True)
it load page fast, but not send
EDIT 2:
Trying use Celery, now script is:
from twilio.rest import Client
from celery import shared_task,current_task
#shared_task
def wa(testo):
print 'test'
client = Client()
# this is the Twilio sandbox testing number
from_whatsapp_number='whatsapp:+14155238886'
to_whatsapp_number='whatsapp:+39xxxxxxxxx'
ts = 'Anomalia Rapportino ' + str(testo)
client.messages.create(body=ts,
from_=from_whatsapp_number,
to=to_whatsapp_number)
but not work in parallel...
what is the right way?

Python code for network location using SIM800c GSM module

I am trying to get network location using SIM800c GSM module.
I need python code to get latitude and longitude of network location.
There are existing AT commands to get lat long.
AT+SAPBR=3,1,"Contype","GPRS"
OK
AT+SAPBR=3,1,"APN","AIRTELGPRS.COM"
OK
AT+SAPBR =1,1
OK
AT+SAPBR=2,1
+SAPBR: 1,1,"100.89.157.83"
OK
AT+CIPGSMLOC=1,1
+CIPGSMLOC: 0,73.856689,18.490337,2019/02/14,12:49:57
I just want to get the latitude and longitude from all output in python code.
You could extract the values using regex:
import re
loca = '+CIPGSMLOC: 0,73.856689,18.490337,2019/02/14,12:49:57'
m = re.match('\+CIPGSMLOC: [\d\.]+,([\d\.]+),([\d\.]+)',loca)
if m:
lat = float( m.group(1) )
lon = float( m.group(2) )
print("%f, %f" % (lat,lon))
Here is the code which I have written in order to get only latitude and longitude from the entire Serial Port output.
import time
import serial
import paho.mqtt.client as paho
import logging as log
Connected = False #global variable for the state of the connection
broker_address= "localhost"
port = 1883
topic = 'rusha'
client = paho.Client("rushabh")
client.connect(broker_address, port=port)
log.info("MQTT broker connected\n")
Serial = serial.Serial(
port='/dev/ttyS0',
baudrate = 115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
counter=0
def ConnectGPRS():
SerialWrite('AT\r\n','OK',1,0)
SerialWrite('AT+SAPBR=0,1\r\n','',2,0)
SerialWrite('AT+SAPBR=3,1,"Contype","GPRS"\r\n','OK',2,0)
SerialWrite('AT+SAPBR=3,1,"APN","AIRTELGPRS.COM"\r\n','OK',2,0)
SerialWrite('AT+SAPBR =1,1\r\n','OK',1,0)
SerialWrite('AT+SAPBR=2,1\r\n','+SAPBR',1,0)
print 'Connected to internet successfully'
def GetLocation():
location = ""
location = SerialWrite('AT+CIPGSMLOC=1,1\r\n','+CIPGSMLOC:',1,1)
print location
if location is None:
print 'Cannot Get Location. Retrying...\n'
GetLocation()
SerialWrite('AT+SAPBR=0,1\r\n','',2,0)
try:
list_output = location.splitlines()
print list_output
location_string = parseString(list_output)
print location_string
latitude = location_string[2]
longitude = location_string[1]
print latitude, longitude
data = 'latitude:' + latitude + '&longitude:' + longitude
client.publish(topic,data)
except:
print 'got location\n'
def parseString(list_output):
for i in range(1,len(list_output)):
if '+CIPGSMLOC:' in list_output[i]:
temp = list_output[i]
temp = temp.replace('+CIPGSMLOC: ','')
result = [x.strip() for x in temp.split(',')]
return result
def SerialWrite(command,reply,SleepTime,func):
if(func==1):
Serial.write(command)
time.sleep(SleepTime);
data = ""
data = Serial.read(200);
if reply in data:
return data
else:
SerialWrite(command,reply,SleepTime+1,func)
if(func==0):
Serial.write(command)
time.sleep(SleepTime)
data=""
data = Serial.read(50)
print data
if reply in data:
print 'Reply:success'
else:
print 'Reply:Failed'
SerialWrite(command,reply,SleepTime+1,func)
ConnectGPRS()
GetLocation()
These codes will not work in some countries. So extract MNC,MCC,LAC,CID
Using at command like :
at+CENG=2
Then send to opencell web site for geolocation.

Categories