基于MQTT智能插座api接口进行软件二次开发实现通断控制与电流电压采集

本文介绍了如何利用MQTT协议和智能插座技术,通过云端服务如GeekOpen实现农业大棚、水泵控制以及远程电力管理。通过MqttClient进行设备连接和消息传递,简化了施工过程,提高了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近两年时常有市场对技术的咨询,关于各种场景下的智能控制,例如农业大棚的水帘风机控制如何实现,抽水泵如何远程操作控制,应急仓库的带电池的设备如何保障电量长期为90%以上以便应急使用,后面都采用了最经济的方案,通过对智能插座的控制与电流采集+业务软件定制开发得以实现,满足了大部分的业务要求,包括对暖通设备的控制,民宿酒店房间用电的控制等,由传统的施工布线变为快速改造即可实现,降低了对现场施工的要求,加快了施工进度。

开发前准备

pom.xml 应用MQTT包

<!-- MQTT -->
<dependency>
	<groupId>org.eclipse.paho</groupId>
	<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
	<version>1.2.5</version>
</dependency>

智能插座配网连接到GeekOpen云端MQTT服务

配网操作请参考教程 智能插座配网教程

没有设备的朋友,请点击此处点击此处查看参数是否满足现场要求

创建MQTT客户端连接,对智能插座进行管理

MqttService.java
package com.geekopen.iot.demo.service;

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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Arrays;

/**
 * MQTT消息收发服务
 */
@Service
public class MqttService {


    private static final Logger log = LoggerFactory.getLogger(MqttService.class);
    private static MqttClient client;

    /**
     *
     */
    private static final String CLIENT_ID = "myDemo123";
    /**
     *
     */
    private static final Boolean CLEAN_SESSION = false;

    // 以下配置信息为 GeekOpen云端MQTT服务信息
    // 可以登录官网 http://www.geek-open.com 获得
    // 也可以搭建自己的 MQTT 服务生成

    /**
     * GeekOpen MQTT服务器地址,固定参数
     */
    public static final String HOST = "tcp://mqtt.geek-smart.cn";
    /**
     * GeekOpen MQTT服务器端口,固定参数
     */
    public static final String PORT = "1883";
    /**
     * 订阅主题
     * 订阅GeekOpen智能设备的消息,统一格式为  /${appId}/${deviceKey}/${deviceMAC}/subscribe
     * 请更换,登录GeekOpen可查询到设备的订阅主题信息
     */
    public static final String TOPIC = "/lsXGEo/hPHBVjJNAzRH/c82b96746f1a/subscribe";
    /**
     * 用户名
     * 请更换,可登录GeekOpen官网查询
     */
    private static final String USER_NAME = "hkAhCufcFGzs";
    /**
     * 密码
     * 请更换,可登录GeekOpen官网查询
     */
    private static final String PASSWORD = "xNfsGgPQzZvMRjLVnC";


    public MqttService() throws MqttException {
        // MemoryPersistence设置
        client = new MqttClient(HOST+":"+PORT, CLIENT_ID, new MemoryPersistence());
    }

    @PostConstruct
    public void init(){
        connect();
    }

    /**
     * 服务端连接MQTT
     */
    private void connect() {
        log.info("HOST:"+HOST);
        log.info("PORT:"+PORT);
        log.info("TOPIC:"+TOPIC);
        log.info("CLIENT_ID:"+CLIENT_ID);
        log.info("USER_NAME:"+USER_NAME);

        MqttConnectOptions options = new MqttConnectOptions();
        options.setCleanSession(false);
        options.setUserName(USER_NAME);
        options.setPassword(PASSWORD.toCharArray());
        // 设置超时时间
        options.setConnectionTimeout(20);
        // 设置会话心跳时间
        options.setKeepAliveInterval(30);
        // 重连
        options.setAutomaticReconnect(true);
        // 设置是否清除会话
        options.setCleanSession(CLEAN_SESSION);
        try {
            client.setCallback(new MessageCallback());
            client.connect(options);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //订阅消息
        subscribe();
    }

    /**
     * 订阅消息
     */
    public static void subscribe(){
        try{
            // 订阅消息topic
            String[] topic = TOPIC.split(",");
            int[] qos = new int[topic.length];
            // 循环将所有主题的Qos设置为1
            Arrays.fill(qos, 1);
            // subscribe 订阅
            client.subscribe(topic, qos);
            log.info("GeekOpen --> 已添加订阅,topic:" + TOPIC);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 发送消息
     * @param message byte
     * @param topic 主题
     * @param qos  qos
     */
    public static void sendMessage(byte[] message,String topic,Integer qos){
        MqttMessage mess = new MqttMessage();
        mess.setQos(qos);
        mess.setRetained(false);
        mess.setPayload(message);
        try {
            client.publish(topic, mess);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 消息发送
     * @param message 消息体
     * @param topic 主题
     * @param qos  qos
     */
    public static void sendMessage(String message,String topic,Integer qos){
        MqttMessage mess = new MqttMessage();
        mess.setQos(qos);
        mess.setRetained(false);
        mess.setPayload(message.getBytes());
        try {
            log.info("GeekOpen --> 服务端发送文本消息到设备,message:" + message);
            log.info("GeekOpen --> 服务端发送文本消息到设备,topic:" + topic);
            log.info("GeekOpen --> 服务端发送文本消息到设备,qos:" + qos);

            // publish 发布
            client.publish(topic, mess);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }



}

监听智能插座的行为信息,实现自动上报数据

MessageCallback.java
package com.geekopen.iot.demo.service;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * MQTT自定义回调
 */
public class MessageCallback implements MqttCallbackExtended {

    private static final Logger log = LoggerFactory.getLogger(MessageCallback.class);

    /**
     * 服务端连接MQTT成功
     * @param b
     * @param s
     */
    @Override
    public void connectComplete(boolean b, String s) {
        log.info("GeekOpen --> 连接成功:("+b+")"+s);
        //处理自定义业务
        //……
    }

    /**
     * 服务端连接MQTT断开
     * @param throwable
     */
    @Override
    public void connectionLost(Throwable throwable) {
        log.info("GeekOpen --> 连接断开:"+throwable.getMessage());
        //处理自定义业务
        //……
    }

    /**
     * subscribe 接收到设备端消息
     * @param topic
     * @param mqttMessage
     * @throws Exception
     */
    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
        try{
            //消息内容mqttMessage由byte转string
            log.info("GeekOpen --> 服务端收到设备消息,内容:" + new String(mqttMessage.getPayload()));
            log.info("GeekOpen --> 服务端收到设备消息,topic: " + topic);
            //处理自定义业务
            //……
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * publish 发送消息到设备完成
     * @param iMqttDeliveryToken
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        try {
            //消息内容mqttMessage由byte转string
            log.info("GeekOpen --> 服务端发送文本消息到设备完成,消息:" + new String(iMqttDeliveryToken.getMessage().getPayload()));
            //处理自定义业务
            //……
        } catch (MqttException e) {
            throw new RuntimeException(e);
        }
    }
}

开启定时任务,每15秒采集一次用电信息

TimeTask.java
package com.geekopen.iot.demo.service;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

/**
 * 定时任务,查询用电信息
 */
@Configuration
@EnableScheduling
public class TimeTask {

    /**
     * 每15秒采集一次用电信息
     */
    @Scheduled(cron = "0/15 * * * * *")
    private void  statistic()
    {
        String messageId = "timeTask.statistic";
        MqttService.sendMessage("{\"messageId\":\""+ messageId +"\",\"type\":\"statistic\"}","/lsXGEo/hPHBVjJNAzRH/c82b96746f1a/publish",0);
    }


}

创建前端应用 API,各种业务功能实现

MqttController.java

实现restful API,方便前端应用调用,通过发送json指令即可控制插座的通电与断电,更多指令与属性浏览GeekOpen官方文档

package com.geekopen.iot.demo.controller;

import com.geekopen.iot.demo.service.MqttService;
import org.springframework.web.bind.annotation.*;

import java.util.Random;

/**
 * MQTT协议提供API调用
 */
@RestController
@RequestMapping("/api/mqtt")
public class MqttController {

    private String topic = "/lsXGEo/hPHBVjJNAzRH/c82b96746f1a/publish";

    /**
     * 智能插座控制 - 通电
     * @return
     */
    @GetMapping("/open")
    @ResponseBody
    public String open()
    {
        String messageId = "myMessageId"+new Random().nextInt(1,100) ;
        MqttService.sendMessage("{\"messageId\":\""+ messageId +"\",\"type\":\"event\",\"key\":0}",topic,0);
        return messageId;
    }

    /**
     * 智能插座控制 - 断电
     * @return
     */
    @GetMapping("/close")
    @ResponseBody
    public String close()
    {
        String messageId = "myMessageId"+new Random().nextInt(1,100) ;
        MqttService.sendMessage("{\"messageId\":\""+ messageId +"\",\"type\":\"event\",\"key\":1}",topic,0);
        return messageId;
    }

    /**
     * 智能插座用电信息查询 - 电量采集、电压查询、功率监控
     * @return
     */
    @GetMapping("/statistic")
    @ResponseBody
    public String statistic()
    {
        String messageId = "myMessageId"+new Random().nextInt(1,100) ;
        MqttService.sendMessage("{\"messageId\":\""+ messageId +"\",\"type\":\"statistic\"}",topic,0);
        return messageId;
    }

    /**
     * 智能插座软重启
     * @return
     */
    @GetMapping("/restart")
    @ResponseBody
    public String restart()
    {
        String messageId = "myMessageId"+new Random().nextInt(1,100) ;
        MqttService.sendMessage("{\"messageId\":\""+ messageId +"\",\"type\":\"setting\",\"system\":\"restart\"}",topic,0);
        return messageId;
    }

    /**
     * 智能插座 重置/恢复出厂设置
     * @return
     */
    @GetMapping("/reset")
    @ResponseBody
    public String reset()
    {
        String messageId = "myMessageId"+new Random().nextInt(1,100) ;
        MqttService.sendMessage("{\"messageId\":\""+ messageId +"\",\"type\":\"setting\",\"system\":\"reset\"}",topic,0);
        return messageId;
    }


}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值