物联网解决方案的实时警报/通知 (DJANGO + UBUNTU)

发布于 2025-01-11 07:13:14 字数 3502 浏览 0 评论 0原文

大家好,我是该员工的新手,愿意寻求任何/所有帮助,

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

此时我做了一些搜索实时通知并查找 websockets、redis 和频道等内容。我在一个温度应用程序中尝试了所有这些,并成功获得了由阈值触发的电子邮件警报,我将在下面分享我的代码。

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

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

我不确定该方法,也许它是错误的,不适合我的情况,所以我愿意接受替代方案,例如我听说过有关 ubuntu cron job 的信息。它适合我的情况吗?

代码________

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 = ['[email protected]']
            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 = ['[email protected]']
            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)]
     }
  }
}

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

Hi everyone i am kinda newbie about that staff and open for any/all help,

Firstly let me shortly summarize that what i want to do and what i have done so far. I am trying to develop a web platform that will be a gui for the users. Users can see their datas which is collected by iot endnodes, as a charts table etc. Also users can set alarm condition, e.g. "if temperature is over 21 send e-mail"

At that point i do some search about live-notification and findout websockets, redis and channels things. I tried all of it together in one temperature application and success to get e-mail alert which is triggered by treshold value i will share my codes below.

The problem is my websocket handshaking working only if client is on page. I mean my users should not keep open the web platform to get alert.

I am using Ubuntu OS and Nginx webserver service. My datas comes from influxdb so i am checking last data on influxdb if the value is over 21 want to trigger the alarm, simple.

I am not sure about the method maybe it is wrong and not suitable for my case so i am open for alternatives for example i heard smth about ubuntu cron job. Can it be suitable for my case ?

CODES________

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 = ['[email protected]']
            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 = ['[email protected]']
            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)]
     }
  }
}

Like i said i am open for any simple suitable solutions.
Thanks a lot from now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

阳光的暖冬 2025-01-18 07:13:14

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

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

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

The job about detect condition and send email can't write in websocket Consumer logic. if the browser close, the websocket disconnect, the job is killed.

You need use Celery to work that job.

  • websocket logic real-time just show temp.
  • celery logic detect condition and send email.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文