我有以下django通道类,它更新网页网页上的值。该类从屏幕单击中接收数据,执行操作(切换指示中继或为特定用途设置一系列数据),更新数据库,然后通过websocket层更新网页。在我介绍尼娜之前一切都很顺利。这将通过一个curl POST从远程源接收数据(见下文)。一个卷发的帖子会导致失败:'TypeError: nina()缺少一个必需的位置参数:'request',但是如果我删除'self‘,我就不知道如何使用它的数据调用'update_relays’。
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'})curl -X POST awebsite.com/dome_control/nina/ -H "Content-Type: application/json" -d '{"type": "curl.receive", "text": "power on"}'发布于 2022-05-28 06:16:45
好的,所以答案是“共享”channel_layer
@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末尾)。
curl -X POST https://mywebsiteaddress/dome_control/nina/ -H "Content-Type: application/json" -d '{"type": "curl.receive", "text": "power on"}'https://stackoverflow.com/questions/72374249
复制相似问题