1、Modbus slave设置从机Modbus TCP参数
设置Modbus TCP协议和地址
模拟软件设置的是 当前电脑的,所以后面 配置Modbus TCP的从机时,就要填当前电脑的ip地址,不要写 bl系列设备的ip地址
设置数据参数
设备地址:22
功能码:04
数据类型:16
起始地址:0
数量:5个
2、设置BL102将Modbus slave从机数据点映射
设置WAN口为Modbus TCP Master模式
设置bl102设备和从机同个网段
添加从机
从机的ip地址,需要填写Modbus slave软件的所在电脑的ip地址,不要填了 bl网关的ip地址
添加数据点
设置MQTT broker(MQTT服务器)信息
查看设备上下行状态
查看下行连接设备和上行连接MQTT服务器状态
3、MQTT客户端设置订阅
客户端设置连接MQTT服务器参数
服务器ip、端口、ID、心跳等。
设置订阅BL102设备的主题
刚才设置BL102设备的发布主题是 test,那么订阅也是 test
查看已收到BL102设备的数据
4、不同编程语言采集数据并写入数据库
以下介绍java和python
Java采集并写入数据库
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.Random;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.eclipse.paho.client.mqttv3.IMqttClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public class MQTTSubscriber {
private static final String BROKER = "tcp://192.168.1.165:1883"; // MQTT Broker地址
private static final String TOPIC = "test"; // 订阅主题名称
private static final String DB_URL = "jdbc:sqlite:plcdata"; // SQLite数据库URL
private static Random random = new Random(); // 用于生成客户端ID的随机数
public static void main(String[] args) throws MqttException {
String clientId = "java-mqtt-" + random.nextInt(100); // 生成客户端ID
IMqttClient mqttClient = new MqttClient(BROKER, clientId, new MemoryPersistence());
// 设置MQTT连接选项
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true); // 不保留会话
options.setAutomaticReconnect(true); // 自动重连
mqttClient.connect(options); // 连接MQTT Broker
// 设置MQTT消息监听器,接收订阅主题的消息
mqttClient.subscribe(TOPIC, new IMqttMessageListener() {
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
LocalDateTime now = LocalDateTime.now();
System.out.println("当前时间:" + now);
String jsonStr = new String(message.getPayload()); // 将MQTT消息转为JSON字符串
System.out.println("收到消息:" + jsonStr);
JsonObject jsonObj = new Gson().fromJson(jsonStr, JsonObject.class); // 将JSON字符串解析为JsonObject对象
// 解析sensorDatas数组中的数据
double lat = 0.0, lng = 0.0;
int signalStrength = 0, reg001 = 0, reg002 = 0, reg003 = 0, reg004 = 0, reg005 = 0;
for (var sensorData : jsonObj.get("sensorDatas").getAsJsonArray()) {
JsonObject sensorDataObj = sensorData.getAsJsonObject();
String flag = sensorDataObj.get("flag").getAsString();
if (flag.equals("GPS")) {
lat = sensorDataObj.get("lat").getAsDouble();
lng = sensorDataObj.get("lng").getAsDouble();
} else if (flag.equals("SIGNAL_STRENGTH")) {
signalStrength = sensorDataObj.get("value").getAsInt();
} else if (flag.equals("REG001")) {
reg001 = sensorDataObj.get("value").getAsInt();
} else if (flag.equals("REG002")) {
reg002 = sensorDataObj.get("value").getAsInt();
} else if (flag.equals("REG} else if (flag.equals("REG001")) {
reg001 = sensorDataObj.get("value").getAsInt();
} else if (flag.equals("REG002")) {
reg002 = sensorDataObj.get("value").getAsInt();
} else if (flag.equals("REG003")) {
reg003 = sensorDataObj.get("value").getAsInt();
} else if (flag.equals("REG004")) {
reg004 = sensorDataObj.get("value").getAsInt();
} else if (flag.equals("REG005")) {
reg005 = sensorDataObj.get("value").getAsInt();
}
该方法用于连接 MQTT 服务器。需要导入java MQTT 客户端库。Java 中有多个可用的 MQTT 客户端库,这里我们将使用 Eclipse Paho Java 客户端库
下面我们将使用 Eclipse Paho Java 客户端库实现 connectMqtt() 方法。首先需要导入相关库:下面我们将使用 Eclipse Paho Java 客户端库实现 connectMqtt() 方法。首先需要导入相关库:
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
然后在 MqttController 类中添加以下代码实现 connectMqtt() 方法:
public static MqttClient connectMqtt() throws MqttException {
// 定义 MQTT 服务器的地址和端口
String broker = "tcp://192.168.1.165:1883";
// 定义 MQTT 客户端 ID,可以随机生成
String clientId = MqttClient.generateClientId();
// 定义连接选项
MqttConnectOptions connOpts = new MqttConnectOptions();
// 设置是否清除会话
connOpts.setCleanSession(true);
// 设置心跳间隔时间
connOpts.setKeepAliveInterval(60);
// 创建 MQTT 客户端
MqttClient client = new MqttClient(broker, clientId, new MemoryPersistence());
// 连接 MQTT 服务器
client.connect(connOpts);
return client;
}
该方法首先定义了 MQTT 服务器的地址和端口,然后生成了一个随机的 MQTT 客户端 ID。接着定义了连接选项,其中设置了是否清除会话和心跳间隔时间等参数。最后创建了一个 MQTT 客户端并连接 MQTT 服务器,返回连接成功的 MQTT 客户端对象。
接下来我们需要在 Java 代码中实现 subscribe() 方法,该方法用于订阅主题并接收数据。首先需要导入相关库:
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.Topic;
然后在 MqttController 类中添加以下代码实现 subscribe() 方法:
public static void subscribe(MqttClient client) throws MqttException {
// 定义订阅主题
String topic = "test";
// 订阅主题并设置消息监听器
client.subscribeWithResponse(topic, new IMqttMessageListener() {
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
// 处理接收到的消息
String jsonStr = new String(message.getPayload(), "UTF-8");
System.out.println("Received message: " + jsonStr);
// TODO: 解析 json 数据并插入数据库
}
});
}
Python采集并写入数据库
# python3.6
import json
import sqlite3
import random
from datetime import datetime
from paho.mqtt import client as mqtt_client
broker = '192.168.1.165'
#broker = 'broker-cn.emqx.io'
port = 1883
topic = "test"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 100)}'
def connect_mqtt() -> mqtt_client:
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
client.on_connect = on_connect
client.connect(broker, port)
return client
#将数据出入数据库
def create_table():
#连接数据库,没有则创建
conn = sqlite3.connect('plcdata')
print('连接数据库成功')
#判断iot表是否存在,不存在则新建。 CREATE TABLE IF NOT EXISTS iot
try:
create_tb_cmd='''
CREATE TABLE IF NOT EXISTS iot
(lat TEXT,
lng TEXT,
signal_strength INT,
REG001 INT,
REG002 INT,
REG003 INT,
REG004 INT,
REG005 INT);
'''
#执行创建数据表语句
conn.execute(create_tb_cmd)
except:
print("Create table failed")
return False
insert_dt_cmd='INSERT INTO iot (lat,lng,signal_strength,REG001,REG002,REG003,REG004,REG005) VALUES '+ strlist + ';'
print(insert_dt_cmd)
# insert_dt_cmd='''
# INSERT INTO iot (lat,lng,signal_strength,REG001,REG002,REG003,REG004,REG005) VALUES (0.000000,0.000000,0,33,8538,234,22,9046);
# '''
conn.execute(insert_dt_cmd)
print('写入数据库成功')
conn.commit()
conn.close()
strlist = ''
def subscribe(client: mqtt_client):
def on_message(client, userdata, msg):
t = datetime.now()
print('当前时间:',t)
#print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
json_data = msg.payload.decode() #解析订阅主题信息,
# print(type(json_data)) #判断data类型,是json字符串
dict_json = json.loads(json_data)
#print(type(dict_json))
#print(dict_json)
sensordatas = dict_json['sensorDatas']
list_data =[]
for i in sensordatas:
#print(type(i),i)
#print(i['flag'],type(i['flag']))
if i['flag'] == 'GPS':
list_data.append(i['lat'])
list_data.append(i['lng'])
#print(list_data)
else:
#print(i['flag'],i['value'])
list_data.append(i['value'])
#print(list_data)
global strlist
strlist = str(tuple(list_data))
print(strlist)
create_table()
client.subscribe(topic)
client.on_message = on_message
def run():
client = connect_mqtt()
subscribe(client)
client.loop_forever()
if __name__ == '__main__':
run()
其他:python发布和订阅
发布
# python 3.6
import random
import time
from paho.mqtt import client as mqtt_client
#broker = '192.168.1.165'
broker = 'broker-cn.emqx.io'
port = 1883
topic = "test"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 1000)}'
def connect_mqtt():
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
client.on_connect = on_connect
client.connect(broker, port)
return client
def publish(client):
msg_count = 0
while True:
time.sleep(1)
msg = f"messages: {msg_count}"
result = client.publish(topic, msg)
# result: [0, 1]
status = result[0]
if status == 0:
print(f"Send `{msg}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
msg_count += 1
def run():
client = connect_mqtt()
client.loop_start()
publish(client)
if __name__ == '__main__':
run()
订阅
# python3.6
import random
from datetime import datetime
from paho.mqtt import client as mqtt_client
#broker = '192.168.1.165'
broker = 'broker-cn.emqx.io'
port = 1883
topic = "test"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 100)}'
def connect_mqtt() -> mqtt_client:
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
client.on_connect = on_connect
client.connect(broker, port)
return client
def subscribe(client: mqtt_client):
def on_message(client, userdata, msg):
t = datetime.now()
print('当前时间:',t)
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
client.subscribe(topic)
client.on_message = on_message
def run():
client = connect_mqtt()
subscribe(client)
client.loop_forever()
if __name__ == '__main__':
run()