欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-10-29 16:16:53
本来想尝试下如果不使用运营商网络应用平台情况下,只是在服务商服务器上是否可以实现对终端完全控制,如果这样可行,那么物联网应用服务端更有灵活性。实际情况下,很难实现和运营商网...

本来想尝试下如果不使用运营商网络应用平台情况下,只是在服务商服务器上是否可以实现对终端完全控制,如果这样可行,那么物联网应用服务端更有灵活性。实际情况下,很难实现和运营商网络对等的处理,用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,然后进入命令输入状态,等待命令输入完成,发送给终端,等待终端反馈,并接续下一个命令传送。

#!/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() 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。