我想设计一个基于网络的应用程序,用于显示从基于Arduino的设置中收集的声音传感器读数(并显示一些分析结果)。为了使我的arduino设置工作,我开发了一个名为' ard_sensor_project.py'它收集读数并存储在.csv文件中并创建图表。
现在我想显示在django网站上生成的读数。为此,我已经导入了' ard_sensor_project.py'在我的django网站的views.py中,并调用了一种实时打印传感器读数的方法。
但是在运行该程序时,似乎虽然阅读收集模块已经启动,但该网站还没有开始,我既看不到网页,也看不到任何阅读。
有没有办法可以在django网站上显示读数?
这是我的 ard_sensor_project.py
key[0] : 97
key[1] : 98
key[2] : 99
以下是我的django网站的 views.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------")
所以似乎服务器根本没有运行。当我将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})
替换为0(同时删除ard.getsensordata
导入)时,我得到:
现在不是0,我想读书。我该怎么办?
答案 0 :(得分:2)
在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[:])))
然后您的django视图可以调用此函数
from . import ard_sensor_project as ard
def index(request):
return render(request, 'start.html', {'noise_level':ard.getsenordata()})
请注意,您在示例中忘记了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')
然后在start.html
中,您需要实现一个javascript函数,该函数将定期使用AJAX调用此ajax_data
视图
3)如果从Arduino读取速度不快或者您有多个用户访问
之前的代码假设从Arduino读取速度很快。您的视图将在发送响应之前等待读取结束。
如果您有多个人访问同一页面,则必须在getsensordata
上实施锁定,否则读数可能会失败。
然后,我建议使用数据库来使用其他策略。
您可以开发外部程序,定期收集数据并将其存储到数据库中。将它开发为Django命令See the docs然后能够通过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
然后,您可以与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')