【问题标题】:Live alert/notifications for iot solutions (DJANGO + UBUNTU)物联网解决方案的实时警报/通知(DJANGO + UBUNTU)
【发布时间】:2022-07-12 23:15:56
【问题描述】:

大家好,我是该员工的新手,欢迎任何/所有帮助,

首先让我简要总结一下我想做什么以及到目前为止我做了什么。我正在尝试开发一个网络平台,它将成为用户的 gui。用户可以查看物联网终端节点收集的数据,例如图表等。用户还可以设置警报条件,例如"如果温度超过 21 发送电子邮件"

那时我会搜索一些关于实时通知的信息,并找出 websockets、redis 和通道的东西。我在一个温度应用程序中尝试了所有这些,并成功获得了由阈值触发的电子邮件警报,我将在下面分享我的代码。

问题是我的 websocket 握手仅在客户端在页面上时才有效。我的意思是我的用户不应该保持打开网络平台来获得警报。

我正在使用 Ubuntu 操作系统和 Nginx 网络服务器服务。我的数据来自 influxdb,所以我正在检查 influxdb 上的最后一个数据,如果值超过 21 想要触发警报,很简单。

我不确定该方法可能是错误的并且不适合我的情况,因此我愿意接受替代方案,例如我听说过有关 ubuntu cron 工作的消息。能适合我的情况吗?

代码________

consumers.py

from channels.generic.websocket import AsyncWebsocketConsumer, WebsocketConsumer
import json
from random import randint
from asyncio import sleep
from influxdb import InfluxDBClient
from itertools import zip_longest
from django.conf import settings
from django.core.mail import send_mail


lora_host = 'My_Server_Adress'

class GraphConsumer(AsyncWebsocketConsumer):
    async def connect(self):
    await self.accept()
    client = InfluxDBClient(host=lora_host, port=8086)
    client.switch_database('loradb')
    temperature = client.query(
        "SELECT * From device_frmpayload_data_Temperature WHERE time > now() - 1d ORDER BY time DESC")
    temperatureDev1 = temperature.get_points(tags={'dev_eui': '000950df9be2733e'})
    dict = []
    dict.append(next(temperatureDev1))
    timePrevious = str(dict).split("'time': '", 1)[1].split(".", 1)[0].split("T")
    timePrev = timePrevious[1]
    xTime = ''
    alertStatus = 0
    while True:
        temperature = client.query("SELECT * From device_frmpayload_data_Temperature WHERE time > now() - 1d ORDER BY time DESC")
        temperatureDev1 = temperature.get_points(tags={'dev_eui': '000950df9be2733e'})
        dict = []
        dict.append(next(temperatureDev1))
        val = float(str(dict).split("'value': ", 1)[1].split("}", 1)[0])
        rTime = str(dict).split("'time': '", 1)[1].split(".", 1)[0]

        if val > 21 and rTime != xTime and alertStatus == 0:
            alertStatus = 1
            xTime = rTime
            subject = 'Alerted'
            message = 'Temperature is too high'
            email_from = settings.EMAIL_HOST_USER
            recipient_list = ['recipient_1@gmail.com']
            send_mail(subject, message, email_from, recipient_list)
        if val < 21 and alertStatus == 1:
            alertStatus = 0
            subject = 'OK'
            message = 'Temperature is fixed'
            email_from = settings.EMAIL_HOST_USER
            recipient_list = ['recipient_1@gmail.com']
            send_mail(subject, message, email_from, recipient_list)

        timeABC = str(dict).split("'time': '", 1)[1].split(".", 1)[0].split("T")

        if timeABC[1] != timePrev:
            timePrev = timeABC[1]
            await self.send(json.dumps({'value': val, 'timeABC': timeABC[1]}))
            await sleep(20)
        else:
            await sleep(20)

Settings.py/Redis-channel

CHANNEL_LAYERS = {
'default': {
    'BACKEND': 'channels_redis.core.RedisChannelLayer',
    'CONFIG': {
        'hosts': [('127.0.0.1', 6379)]
     }
  }
}

就像我说的,我愿意接受任何简单合适的解决方案。 从现在开始非常感谢。

【问题讨论】:

    标签: ubuntu websocket cron django-channels


    【解决方案1】:

    检测条件和发送电子邮件的工作不能写在 websocket 消费者逻辑中。如果浏览器关闭,websocket 断开连接,作业被终止。

    您需要使用 Celery 来完成这项工作。

    • websocket 逻辑实时只显示温度。
    • celery 逻辑检测条件并发送电子邮件。

    【讨论】:

      猜你喜欢
      • 2016-08-03
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      • 1970-01-01
      • 2010-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多