2016-04-20 37 views
0

我有一個django項目,我想從每隔20秒ping的設備顯示實時數據。我編寫了一個外部python腳本,通過在cmd「python manage.py ping」中運行來每隔20秒ping設備。將外部腳本的實時數據傳遞給django視圖

我的問題是我不太清楚我將如何處理這個問題。我會將從外部腳本返回的數據傳遞給視圖函數,然後將其從那裏發送到客戶端?

這裏是我寫的劇本,將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]})) 

一種方法我能想到的是暫時存儲數據,那麼地方只是有客戶端AJAX讓每一個20秒的讀/返回該值。

+0

這似乎有點倒退,我不能讓設備ping服務器(而不是其他方式)? – Sayse

+0

你的意思是設備ping服務器是什麼意思?該設備只是一個地方,我正在使用我的腳本使用pymodbus發送讀取請求。不要認爲設備可以做任何事情,但回覆我發送的請求。除非我誤解你的意思 – john

+0

我的意思是讓設備發送一個請求到服務器,我想如果它能響應一個它必須能夠發送一個,但我不知道任何涉及到的內在函數 – Sayse

回答

1

你想從命令中移動for device in TDevices.objects.all():之後的所有代碼,並使其成爲TDevices模型的一個方法。所以像

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

然後視圖調用device.ping()並將返回的數據合成到視圖中。對不起,如果它有點抽象,但問題真的只是在哪裏把你的代碼。一旦它在模型中,視圖就很容易訪問它。希望你能得到它的要點。

+0

其實這很不錯。我認爲這仍然可以與我的threading.timer一起工作? – john

+0

這只是python代碼,所以任何事情都應該工作。最糟糕的是,你必須阻止整個過程。只要您使用多線程的Web服務器來爲不應該成爲問題的頁面提供服務,除非該過程需要很長時間並且最終用戶不滿意。 – nephlm

相關問題