将实时数据从外部脚本传递到django视图

时间:2016-04-20 14:35:54

标签: python ajax django django-templates

我有一个django项目,我想要显示每20秒被ping的设备的实时数据。我写了一个外部python脚本,通过在cmd“python manage.py ping”中运行,每20秒ping一次设备。

我的问题是我不太确定如何处理这个问题。我会将返回的数据从外部脚本传递给视图函数,然后从那里发送到客户端吗?

这是我编写的脚本,它将ping设备并获取值

from pymodbus.client.sync import ModbusTcpClient
from pymodbus.exceptions import ModbusException, ConnectionException, ParameterException
from models import *
from devices_models import *
from views import reciever
import datetime
from django.core.management.base import NoArgsCommand
import threading
import time

class Command(NoArgsCommand):
    def handle_noargs(self, **options):
        timerThread = threading.Thread(target=run)
        timerThread.start()

def run():
    next_call = time.time()

    while True:
        print("sending ping..")
        with open("test.txt", "a") as my_file:
            for device in TDevices.objects.all():
                if device.bIsLogging == True:
                    my_file.write("Pinging device: " + device.asDeviceName + " at " + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + '\n')
                    try:
                        config = TModbusConfigs.objects.get(pk=device.ixDevice)
                        client = None
                        if config != None:
                            client = ModbusTcpClient(config.asIPAddressv4, config.iPort)
                            client.connect()
                            response = None

                            my_file.write("\t(dev ID=" + str(device.ixDevice) + ") pinging registers...\n")

                            for register in TDeviceMeasurememts.objects.filter(ixDevice=device.ixDevice):

                                #determine register type by prefix
                                reg_parse = AddressParser(register.iAddress)
                                func_code = reg_parse.get_prefix()
                                reg_addr = reg_parse.get_address()
                                if func_code == 1:
                                    try:
                                        response = client.read_coils(reg_addr, register.iLength, unit=int(config.iSlaveID))
                                        if response != None:
                                            temp = response.bits[0]
                                        else:
                                            raise ParameterException()
                                    except ConnectionException as ex:
                                        LogSysAlert(ex, "Communication")
                                        pass
                                    except ParameterException() as ex:
                                        LogSysAlert(ex, "Communication")
                                        pass
                                    except ModbusException as ex:
                                        LogSysAlert(ex, "Communication")
                                        pass


                                elif func_code == 2:
                                    try:
                                        response = client.read_discrete_inputs(reg_addr, register.iLength, unit=int(config.iSlaveID))
                                        if response != None:
                                            temp = response.bits[0]
                                        else:
                                            raise ParameterException()

                                    except ConnectionException as ex:
                                        LogSysAlert(ex, "Communication")
                                        pass
                                    except ParameterException() as ex:
                                        LogSysAlert(ex, "Communication")
                                        pass
                                    except ModbusException as ex:
                                        LogSysAlert(ex, "Communication")
                                        pass

                                elif func_code == 3:
                                    try:
                                        response = client.read_holding_registers(reg_addr, register.iLength, unit=int(config.iSlaveID))
                                        if response != None:
                                            if hasattr(response, 'registers'):
                                                value = ''
                                                for val in response.registers:
                                                    value += str(val)
                                                if value != None:
                                                    temp = value

                                                    my_file.write("\t\t\t" + device.asDeviceName + " (" + register.asInputID + ") Register(" + str(register.iAddress) + "): " + value + "\n")
                                            else:
                                                my_file.write("\t\t\tNo register Attribute \n")
                                        else:
                                            raise ParameterException("Invalid Parameter")

                                    except ConnectionException as ex:
                                        my_file.write("\t\t\tConnectedException: " + ex.message + " - " + ex.string + "\n")
                                        #LogSysAlert(ex, "Communication")
                                        pass
                                    except ParameterException() as ex:
                                        my_file.write("\t\t\tParameterException: " + ex.message + " - " + ex.string + "\n")
                                        #LogSysAlert(ex, "Communication")
                                        pass
                                    except ModbusException as ex:
                                        my_file.write("\t\t\tModbusException: " + ex.message + " - " + ex.string + "\n")
                                        #LogSysAlert(ex, "Communication")
                                        pass

                                elif func_code == 4:
                                    try:
                                        response = client.read_input_registers(reg_addr, register.iLength, unit=int(config.iSlaveID))
                                        if response != None:
                                            if hasattr(response, 'registers'):
                                                value = ''
                                                for val in response.registers:
                                                    value += str(val)
                                                if value != None:
                                                    temp = value
                                                    my_file.write("(" + device.asDeviceName + ") Register( " + str(register.iAddress) + "): " + value)
                                        else:
                                            raise ParameterException()

                                    except ConnectionException as ex:
                                        my_file.write("\t\t\ConnectionException: " + ex.message + " - " + ex.string + "\n")
                                        #LogSysAlert(ex, "Communication")
                                        pass
                                    except ParameterException() as ex:
                                        my_file.write("\t\t\ParameterException: " + ex.message + " - " + ex.string + "\n")
                                        #LogSysAlert(ex, "Communication")
                                        pass
                                    except ModbusException as ex:
                                        my_file.write("\t\t\ModbusException: " + ex.message + " - " + ex.string + "\n")
                                        #LogSysAlert(ex, "Communication")
                                        pass


                            client.close()

                    except ModbusException as ex:
                        my_file.write("\t\t\ModbusException: " + ex.message + " - " + ex.string + "\n")
                        if client != None:
                            client.close()
                        #log_exception(ex)
                        LogSysAlert(ex, "Communication")
                        pass
                    except AttributeError as ex:
                        my_file.write("\t\t\AttributeError: " + ex.message + " - " + ex.string + "\n")
                        if client != None:
                            client.close()
                        pass
                    except Exception as ex:
                        my_file.write("\t\t\Exception: " + ex.message + " - " + ex.string + "\n")
                        if client != None:
                            client.close()
                        pass
                        #raise Exception(ex)

            my_file.write("...-----------------------------------------------------------------------------------------------ending\n\n\n")
            print("finished...")

            next_call = next_call + 20
            time.sleep(next_call - time.time())

class AddressParser():
    def __init__(self, address):
        self.address = address
        self.prefix = None

    def get_prefix(self):
        self.prefix = str(self.address)[0]
        return int(self.prefix)

    def get_address(self):
        if self.prefix != None:
            return int(str(self.address)[1:])

现在我只将它写入文本文件,但会转换为数组或对象。

这是我查看设备及其寄存器的视图:

@login_required(login_url='/login/')
def devices(request):
    assert isinstance(request, HttpRequest)
    devices = TDevices.objects.all()

    if request.method == "POST":
        for device in devices:
            if "device_" + str(device.ixDevice) in request.POST:
                device.bIsLogging = True
                device.save()
            else:
                device.bIsLogging = False
                device.save()



    return render(request, 'devices.html' , context_instance = RequestContext(request, { 'title':'Device Management', 'sysalerts': TSystemAlerts.objects.all(), 'devices': TDevices.objects.all(), 'counterCheck':  [4,7,10,13,16,19,22]}))

我能想到的一种方法是暂时将数据存储在某处,然后每隔20秒让客户端ajax GET并读取/返回该值。

1 个答案:

答案 0 :(得分:1)

您希望在命令for device in TDevices.objects.all():之后移动所有代码,并使其成为TDevices模型的方法。像

这样的东西
class TDevices(...):
    [...]
    def ping(self):
         if device.bIsLogging == True:
                # collect data, etc
         return dataDict

然后视图调用device.ping()并将返回的数据合成到视图中。对不起,如果它有点抽象,但问题实际上就是放置代码的地方。一旦进入模型,视图就可以轻松访问它。希望你能得到它的要点。