首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Django通道(websocket层使用者)使用来自内部数据库和外部数据源的数据更新网页

使用Django通道(websocket层使用者)使用来自内部数据库和外部数据源的数据更新网页
EN

Stack Overflow用户
提问于 2022-05-25 08:24:40
回答 1查看 593关注 0票数 0

我有以下django通道类,它更新网页网页上的值。该类从屏幕单击中接收数据,执行操作(切换指示中继或为特定用途设置一系列数据),更新数据库,然后通过websocket层更新网页。在我介绍尼娜之前一切都很顺利。这将通过一个curl POST从远程源接收数据(见下文)。一个卷发的帖子会导致失败:'TypeError: nina()缺少一个必需的位置参数:'request',但是如果我删除'self‘,我就不知道如何使用它的数据调用'update_relays’。

代码语言:javascript
复制
import logging
import json

from channels.consumer import SyncConsumer
from asgiref.sync import async_to_sync
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import dbConditions, dbRelays

logger = logging.getLogger(__name__)


class DomeControlConsumer(SyncConsumer):
    """#from https://channels.readthedocs.io/en/latest/topics/consumers.html"""

    def websocket_connect(self, event):
        """Connects to webpage"""
        logger.debug("connected - Event: %s", event)
        async_to_sync(self.channel_layer.group_add)(
            "dome_control_group",
            self.channel_name
            )   # make the group layer for signals to send to
        self.send({
            "type": "websocket.accept"
        })
        self.build_and_send_context()

    def websocket_receive(self, event):
        """recives button presses from webpage
        either 'control_button' or relays 1 through 8"""
        logger.debug("received: %s from %s", event, event["text"])
        self.update_relays(event["text"])
        # if the control button was pressed or if a relay button is pressed

    def websocket_disconnect(self, event):
        """disconnects from webpage"""
        logger.debug("disconnected - Event: %s", event)
        async_to_sync(self.channel_layer.group_discard)(
            "automation_group",
            self.channel_name
            )
            
    def update_relays(self, value):
        """receives values from websocket_receive event
        or nina request and changes relays accordingliy"""
        conditions = dbConditions.objects.last()
        cond_dict = dbConditions.to_dict(conditions)
        control_value = cond_dict["dome_status"]
        logger.info("value is: %s", value)
        if value == "control_button":
            if control_value == "Manual":
                conditions.dome_status = "Auto-Imaging"
            elif control_value == "Auto-Imaging":
                conditions.dome_status = "Auto-Sleep"
            elif control_value == "Auto-Sleep":
                conditions.dome_status = "Manual"
        elif value == "power on":
            conditions.dome_status = "Auto-Imaging"
        elif value == "power off":
            conditions.dome_status = "Auto-Sleep"
        else:
            if conditions.dome_status == "Manual":
                self.toggle_relay(value)

        if conditions.dome_status == "Auto-Imaging":
            for relay in dbRelays.objects.all():
                if relay.relay_label == "USB Hub":
                    relay.current_state = 1
                elif relay.relay_label == "Dome":
                    relay.current_state = 1
                elif relay.relay_label == "MX+":
                    relay.current_state = 1
                elif relay.relay_label == "AAG":
                    relay.current_state = 1
                elif relay.relay_label == "Eagle":
                    relay.current_state = 1
                elif relay.relay_label == "Heater":
                    relay.current_state = 0
                relay.save()
            logger.debug(" updated control_value %s",
                         conditions.dome_status)
        elif conditions.dome_status == "Auto-Sleep":
            for relay in dbRelays.objects.all():
                if relay.relay_label == "USB Hub":
                    relay.current_state = 0
                elif relay.relay_label == "Dome":
                    relay.current_state = 1
                elif relay.relay_label == "MX+":
                    relay.current_state = 0
                elif relay.relay_label == "AAG":
                    relay.current_state = 1
                elif relay.relay_label == "Eagle":
                    relay.current_state = 1
                relay.save()
            logger.debug(" updated control_value %s",
                         conditions.dome_status)
        conditions.save()
        self.build_and_send_context()

    def build_and_send_context(self):
        """updates webpage"""
        try:
            context = self.get_relay_dict()
            condtions = self.get_conditions_dict()
            context.update(condtions)
            context = json.dumps(context)
        except Exception as err:
            logger.exception(err)
        else:
            logger.debug("made context: %s", context)
            self.send({
                "type": "websocket.send",
                "text": context
                })

    def get_relay_dict(self):
        """get dictionary of relays"""
        relay_dict = {}
        dbRelays.setup(dbRelays)
        for relay in dbRelays.objects.order_by("relay_no"):
            relaydict = dbRelays.to_dict(relay)
            relay_dict.update({relay.relay_no: relaydict})
        return relay_dict

    def get_conditions_dict(self):
        """get dictionary of conditions"""
        cond_dict = dbConditions.to_dict(dbConditions.objects.last())
        return cond_dict

    def toggle_relay(self, relay_no):
        """taggles vlaue of relay in database"""
        dbRelays.toggle_relay(dbRelays, relay_no)

    def update_context(self, event):
        """uesed by celery task to update webpage"""
        logger.debug("got data from dome_control.tasks.py: %s", event)
        self.build_and_send_context()

    @csrf_exempt
    def nina(request):
        """RECEIVES DATA FROM NINA"""
        logger.info("request received from nina: %s", request)
        logger.info("data  %s", json.loads(request.body))
        # produces   data  {'type': 'curl.receive', 'text': 'power on'}
        return JsonResponse({'status': 'ok'})
代码语言:javascript
复制
curl -X POST awebsite.com/dome_control/nina/ -H "Content-Type: application/json" -d '{"type": "curl.receive", "text": "power on"}'
EN

回答 1

Stack Overflow用户

发布于 2022-05-28 06:16:45

好的,所以答案是“共享”channel_layer

代码语言:javascript
复制
@csrf_exempt
def nina(request):
    """RECEIVES DATA FROM NINA"""
    logger.info("request received from nina: %s", request)
    logger.info("data  %s", json.loads(request.body))
    incoming_msg = json.loads(request.body)["text"]
    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        "dome_control_group",
        {'type': 'websocket.receive', 'text': incoming_msg}
         )
    return JsonResponse({'status': 'ok'})

在curl请求中也有一个错误(不/在url末尾)。

代码语言:javascript
复制
curl -X POST https://mywebsiteaddress/dome_control/nina/ -H "Content-Type: application/json" -d '{"type": "curl.receive", "text": "power on"}'
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72374249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档