本来想尝试下如果不使用运营商网络应用平台情况下,只是在服务商服务器上是否可以实现对终端完全控制,如果这样可行,那么物联网应用服务端更有灵活性。实际情况下,很难实现和运营商网络对等的处理,用python代码原型确实能够实现参数的变化(如PSM,eDXR等),但是终端分配的IP地址毕竟属于接入网部分,更近似一个局域网,如果采用其他方式访问(如IMSI、IMEI等),还是需要与运营商核心网进行配合。以下是尝试远程控制的实现方法。
主要实现功能
1、使用python pyserial模块通过串口发送AT命令给模组进行参数修改,参考<使用python pyserial模块串口通信>;
2、通过inter网进行控制命令传输,选用UDP进行主机控制,参考<python socket网络接口编程>;
3、直接通过NB-IoT无线网络进行控制命令的传输;
4、python多窗口处理服务器端程序,实现接收和发送同时进行;
远程控制主机脚本
服务器端程序:监测UDP对应的端口号,如果接收到register信息则返回allowed,然后进入命令输入状态,等待命令输入完成,发送给终端,等待终端反馈,并接续下一个命令传送。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#!/usr/bin/python3.6
import socket
import sys
import re
BUFFER_SIZE = 1024
TARGET_ADDR = ''
TARGET_PORT = 60000
TARGET = (TARGET_ADDR,TARGET_PORT)
ss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
ss.bind(TARGET)
print ( "server online!! wait for register!" )
data,addrRsv = ss.recvfrom(BUFFER_SIZE)
if not data:
sys.exit( 0 )
else :
print (data)
if (re.match(b 'register' ,data)):
ss.sendto(b 'allowed' ,addrRsv)
else :
ss.sendto(b 'reject' ,addrRsv)
while True :
#等待命令输入
aa = input ( 'cmd > ' )
if not aa:
break
else :
cmdV = aa + '\r'
ss.sendto(cmdV.encode( 'utf-8' ),addrRsv)
#等待结果返回
data,addrRsv = ss.recvfrom(BUFFER_SIZE)
if not data:
break
else :
print (data)
ss.close()
|
客户主机程序:发送register并成功接收allowed后,等待控制命令,通过串口转发给终端模块,并接收终端模块的反馈消息,返回给服务器侧。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
#!/usr/bin/python3.6
import serial
import sys
import os
import re
import socket
#初始化UART端口
ser = serial.Serial( "COM5" , 9600 ,timeout = 30 )
#选择相应的协议类型UDP
ss = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
BUFFER_SIZE = 1024
TARGET_ADDR = 'IP address'
TARGET_PORT = 60000
TARGET = (TARGET_ADDR,TARGET_PORT)
aa = '开机命令' .encode( 'utf-8' ) #convert to bytes type
ser.write(aa)
while True :
line = ser.readline()
if not line:
print ( "can not get cmd result, release!" )
sys.exit( 0 )
print (line)
if ( re.match(b 'OK' ,line) ):
break
ss.sendto(bytes( 'register' , 'utf-8' ),TARGET)
data,addrRsv = ss.recvfrom(BUFFER_SIZE)
if re.match(b 'allowed' ,data):
print ( 'register successfully!' )
pass
else :
print ( 'register failure' )
sys.exit( 0 )
while True :
data,addrRsv = ss.recvfrom(BUFFER_SIZE)
if not data:
print ( "time out,release now!!" )
break
elif re.match(b 'end' ,data):
print ( "end of process!!" )
break ;
ser.write(data)
while True :
line = ser.readline()
if not line:
print ( "can not get cmd result, release!" )
break
print (line)
if ( re.match(b 'OK' ,line) ):
ss.sendto(bytes( 'OK' , 'utf-8' ),TARGET)
break
elif (re.match(b 'ERROR' ,line)):
ss.sendto(bytes( 'ERROR' , 'utf-8' ),TARGET)
break
else :
pass
ser.close()
|
多线程窗口
为了使得服务器端能够实现同时实现接收和发送,可以在服务器端开启两个窗口进行监听,示例如下:
启动代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#!/usr/bin/python3.6
import threading
import time
import subprocess
import os
import sys
def thread_fun1():
#global vlock
while ( 1 ):
print ( "thread fun1 is running!!!" )
time.sleep( 1 )
#... ...
print ( len (sys.argv))
#vlock = threading.Lock()
t1 = threading.Thread(target = thread_fun1,args = ())
t1.start()
addr = 'IP address'
port = 60000
cmdStr = "python anotherThread.py %s %d" % (addr,port)
#设置creationflags = subprocess.CREATE_NEW_CONSOLE,用来创建新的控制台窗口
subprocess.Popen(cmdStr,creationflags = subprocess.CREATE_NEW_CONSOLE)
|
anotherThread.py
1
2
3
4
5
6
7
8
9
10
|
#!/usr/bin/python3.6
def thread_fun2():
while ( 1 ):
aa = input ( 'cmd > ' )
print ( "thread fun2 is running!!!" )
print (aa)
if (aa = = 'end' ):
break
thread_fun2()
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/dreambitbybit/article/details/79307401