Python实现NB-IoT模块远程控制

本来想尝试下如果不使用运营商网络应用平台情况下,只是在服务商服务器上是否可以实现对终端完全控制,如果这样可行,那么物联网应用服务端更有灵活性。实际情况下,很难实现和运营商网络对等的处理,用python代码原型确实能够实现参数的变化(如PSM,eDXR等),但是终端分配的IP地址毕竟属于接入网部分,更近似一个局域网,如果采用其他方式访问(如IMSI、IMEI等),还是需要与运营商核心网进行配合。以下是尝试远程控制的实现方法。
主要实现功能
1、使用python pyserial模块通过串口发送AT命令给模组进行参数修改,参考<使用python pyserial模块串口通信>;
2、通过inter网进行控制命令传输,选用UDP进行主机控制,参考
3、直接通过NB-IoT无线网络进行控制命令的传输;
4、python多窗口处理服务器端程序,实现接收和发送同时进行;
远程控制主机脚本
服务器端程序:监测UDP对应的端口号,如果接收到register信息则返回allowed,然后进入命令输入状态,等待命令输入完成,发送给终端,等待终端反馈,并接续下一个命令传送。
#!/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后,等待控制命令,通过串口转发给终端模块,并接收终端模块的反馈消息,返回给服务器侧。
#!/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()
多线程窗口
为了使得服务器端能够实现同时实现接收和发送,可以在服务器端开启两个窗口进行监听,示例如下:
启动代码
#!/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
#!/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()

你可能感兴趣的:(通信系统,python知识)