Deb*_*Dey 1 python django webserver
我想设计一个基于 Web 的应用程序,用于显示从基于 Arduino 的设置收集的声音传感器读数(并显示一些分析结果)。为了让我的 arduino 设置工作,我开发了一个名为“ard_sensor_project.py”的 python 程序,它收集读数并存储在 .csv 文件中并创建一个图形。
现在我想显示在 django 网站中生成的读数。为此,我在 django 站点的 views.py 中导入了“ard_sensor_project.py”,并调用了一种方法来实时打印传感器读数。
但是在运行程序时,似乎虽然已经启动了阅读收集模块,但网站还没有启动,我既看不到网页,也看不到任何阅读。
有什么方法可以在 django 网站上显示读数吗?
这是我的ard_sensor_project.py
import matplotlib.pyplot as plt
from datetime import datetime
#necessary declarations
sr = serial.Serial("COM6",9600)
#self declared methods
def getsensordata():
st = list(str(sr.readline(),'utf-8'))
return int(str(''.join(st[:])))
def storedata(fname,val1,val2):
#stores data in a .csv file, will update if required
def plotgraph():
#method for plotting data in a matplotlib graph, will update if required
#codes as part of main execution + function calls
print("------Reading collection starts now------")
while True:
try:
timeNow = datetime.now().strftime("%d-%m-%Y %H:%M:%S")
storedata('op.csv', timeNow, getsensordata())
#plotgraph()
except KeyboardInterrupt:
break
sr.close()
print("------Reading collection ends successfully------")
Run Code Online (Sandbox Code Playgroud)
这是我的 Django 站点的views.py
from django.shortcuts import render
# Create your views here.
from django.template.loader import get_template
from django.http import HttpResponse
from . import ard_sensor_project as ard
def index(request):
return render(request,'start.html',{'noise_level':ard.getsenordata})
Run Code Online (Sandbox Code Playgroud)
所以看起来服务器根本没有运行。当我替换ard.getsensordata为 0(也删除ard导入)时,我得到:
现在,我想要阅读而不是 0。我应该如何进行?
在 Web 应用程序的上下文中,我认为您的数据收集程序必须具有不同的理念。
您会看到,print("------Reading collection starts now------")因为在导入模块时会执行所有顶级代码from . import ard_sensor_project as ard
它会打印消息,但也会打开串行端口并启动while True无限循环。
Web 服务器和这个循环在同一个线程中。所以服务器在循环结束之前不会启动。
你可能有不同的策略
1) 如果从 Arduino 读取速度很快并且您只有一个用户访问
您可以重新组织您的模块并将所有数据读取内容放在一个函数中
def getsensordata():
print("------Reading collection starts now------")
sr = serial.Serial("COM6",9600)
st = list(str(sr.readline(),'utf-8'))
sr.close()
print("------Reading collection ends successfully------")
return int(str(''.join(st[:])))
Run Code Online (Sandbox Code Playgroud)
然后你的 django 视图可以调用这个函数
from . import ard_sensor_project as ard
def index(request):
return render(request, 'start.html', {'noise_level':ard.getsenordata()})
Run Code Online (Sandbox Code Playgroud)
请注意,您ard.getsenordata在示例中忘记了 () 之后,如果是这样,则不会调用该函数
当您访问索引视图时,ard.getsenordata会调用 ,从 Arduino 读取数据并放入您的上下文中。您可以在start.html模板中正确显示
2) 如果从 Arduino 读取速度很快并且您希望数据自动更新,并且您仍然有一个用户访问
在前面的例子中,数据是在页面显示的时候才读取的。如果要刷新它,则需要在浏览器上刷新页面。
如果你想自动更新数据,你需要用ajax实现一些东西
from . import ard_sensor_project as ard
def index(request):
return render(request, 'start.html', {})
def ajax_data(request):
data = {'noise_level':ard.getsenordata()}
json_data = json.dumps(data)
return Response(json_data, mimetypes='application/json')
Run Code Online (Sandbox Code Playgroud)
然后在您的 中start.html,您需要实现一个 javascript 函数,该函数将ajax_data定期使用 AJAX调用此视图
3) 如果从 Arduino 读取速度不快或者您有多个用户访问
前面的代码假设从 Arduino 读取速度很快。您的视图将在发送响应之前等待阅读结束。
如果您有多个人访问同一页面,则必须对 实施锁定,getsensordata否则读取可能会失败。
然后,我建议通过使用数据库来使用另一种策略。
您可以开发一个外部程序,定期收集数据并将其存储到数据库中。将其开发为 Django 命令可能是个好主意,请参阅文档,然后能够通过 Django ORM 访问数据库。
例如,如果您定义了一个MyNoiseLevelModel模型
class Command(BaseCommand):
def handle(self, *args, **options):
while True:
try:
now = datetime.now()
noise_level = getsenordata()
MyNoiseLevelModel.objects.create(timestamp=now(), value=noise_level)
# maybe wait a little bit here
# time.sleep(1) # 1 sec
except KeyboardInterrupt:
break
Run Code Online (Sandbox Code Playgroud)
然后,您可以与 Web 服务器并行运行此命令。它收集数据,您可以在您的视图中查看
def index(request):
return render(request, 'start.html', {})
def ajax_data(request):
values = MyNoiseLevelModel.objects.all().values('value')
json_data = json.dumps(data)
return Response(json_data, mimetypes='application/json')
Run Code Online (Sandbox Code Playgroud)