在 Django 网站中显示传感器读数

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。我应该如何进行?

luc*_*luc 5

在 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)