我有一個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秒的讀/返回該值。
這似乎有點倒退,我不能讓設備ping服務器(而不是其他方式)? – Sayse
你的意思是設備ping服務器是什麼意思?該設備只是一個地方,我正在使用我的腳本使用pymodbus發送讀取請求。不要認爲設備可以做任何事情,但回覆我發送的請求。除非我誤解你的意思 – john
我的意思是讓設備發送一個請求到服務器,我想如果它能響應一個它必須能夠發送一個,但我不知道任何涉及到的內在函數 – Sayse