Homeassistant通过MQTT连接ESP32读取正泰计量表DDSU666

一、 通过Docker搭建MQTT服务器(emqx)

emqx安装指南

  1. 获取 Docker 镜像
docker pull emqx/emqx:5.4.1
  1. 启动 Docker 容器
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.4.1
  1. 通过浏览器访问 http://localhost:18083/(localhost 可替换为您的实际 IP 地址)以访问 EMQX Dashboard 管理控制台,进行设备连接与相关指标监控管理。
  2. ​ 默认用户名及密码:
    账户:admin 密码:​ public

至此,MQTT服务器便搭建完毕。如果想添加用户、密码就在系统里添加,然并卵,没屌用。
MQTT服务器

二、 Homeassistant设置

Homeassistant设置比较简单,直接添加MQTT集成即可,地址就填刚才搭建的MQTT服务器地址。当然,你也可以跳过搭建MQTT服务器,直接使用公用MQTT服务器也可。
在这里插入图片描述
点击下一步
在这里插入图片描述
完成后。。。。

连接MQTT

三、通过MQTTX客户端添加实体

通过MQTTX客户端连接MQTT服务器
可以参考官网MQTT介绍
我的设置如下:
TOPIC:xuhome/EP/ddsu666-power/config
格式:discovery prefix(前缀)+模块ID(随意起)+实体ID(随意起)+config
弄完可以参考下面的 这个是功率:

{
    "unique_id": "ddsu666-power",
    "name": "power",
    "icon": "mdi:thermometer",
    "state_topic": "ddsu666/power/state",
    "json_attributes_topic": "ddsu666/power/attributes",
    "unit_of_measurement": "Kw",
    "device": {
        "identifiers": "ddsu666",
        "manufacturer": "制造商",
        "model": "EP",
        "name": "ddsu666",
        "sw_version": "1.0"
    }
}

在这里插入图片描述
后面就添加电压、电流、功率。记得 TOPIC的实体ID必须更换。

**添加电量,**这个与前面的不同,因为要添加到“能源”里面,由特定的要求。但是“device”里面不用变,只添加一些东西。
topic:xuhome/sensor/EP/ddsu666-electricity/config
(注意xuhome是我的前缀,更改成你的)

{
    "unique_id": "ddsu666",
    "name": "electricity",
    "icon": "mdi:gauge",
    "state_topic": "ddsu666/electricity/state",
    "json_attributes_topic": "ddsu666/electricity/attributes",
    "unit_of_measurement": "kWh",
    "last_reset_value_template": "{{ value_json['electricity'].TotalStartTime }}",
    "device_class":"energy",
    "state_class":"total_increasing",
    "device": {
        "identifiers": "ddsu666",
        "manufacturer": "XuHome",
        "model": "EP",
        "name": "ddsu666",
        "sw_version": "1.0"
    }
}

完成后你会发现hass的MQTT里面多了一个设备 n个实体
在这里插入图片描述
点击设备 会弹出你添加的东西,当然 你不会由数据 因为你还差一步。
在这里插入图片描述
(1)"device_class"对应的设备类型如下:


None: 通用传感器。这是默认值,不需要设置。
apparent_power: 视在功率,单位为VA。
aqi: 空气质量指数,无单位。
atmospheric_pressure: 大气压力,单位为cbar、bar、hPa、mmHg、inHg、kPa、mbar、Pa或psi。
battery: 剩余电池百分比,单位为%。
carbon_dioxide: 二氧化碳浓度,单位为ppm。
carbon_monoxide: 一氧化碳浓度,单位为ppm。
current: 电流,单位为A、mA。
data_rate: 数据传输速率,单位为bit/s、kbit/s、Mbit/s、Gbit/s、B/s、kB/s、MB/s、GB/s、KiB/s、MiB/s或GiB/s。
data_size: 数据大小,单位为bit、kbit、Mbit、Gbit、B、kB、MB、GB、TB、PB、EB、ZB、YB、KiB、MiB、GiB、TiB、PiB、EiB、ZiB或YiB。
date: 日期字符串(ISO 8601)。
distance: 距离,单位为km、m、cm、mm、mi、yd或in。
duration: 持续时间,单位为d、h、min或s。
energy: 能量,单位为Wh、kWh、MWh、MJ或GJ。
energy_storage: 储存能量,单位为Wh、kWh、MWh、MJ或GJ。
enum: 具有有限状态集合(非数值型)。
frequency: 频率,单位为Hz、kHz、MHz或GHz。
gas: 气体体积,单位为m³、ft³或CCF。
humidity: 空气湿度百分比,单位为%。
illuminance: 当前光照强度,单位为lx。
irradiance: 辐照度,单位为W/m²或BTU/(h⋅ft²)。
moisture: 物质中水分的百分比,单位为%。
monetary: 货币价值(ISO 4217)。
nitrogen_dioxide: 二氧化氮浓度,单位为µg/m³。
nitrogen_monoxide: 一氧化氮浓度,单位为µg/m³。
nitrous_oxide: 一氧化二氮浓度,单位为µg/m³。
ozone: 臭氧浓度,单位为µg/m³。
ph: 水溶液的酸碱度(pH)值。
pm1: 小于1微米的颗粒物浓度,单位为µg/m³。
pm25: 小于2.5微米的颗粒物浓度,单位为µg/m³。
pm10: 小于10微米的颗粒物浓度,单位为µg/m³。
power_factor: 功率因数,无单位或%。
power: 功率,单位为W或kW。
precipitation: 累积降水量,单位为cm、in或mm。
precipitation_intensity: 降水强度,单位为in/d、in/h、mm/d或mm/h。
pressure: 压力,单位为Pa、kPa、hPa、bar、cbar、mbar、mmHg、inHg或psi。
reactive_power: 无功功率,单位为var。
signal_strength: 信号强度,单位为dB或dBm。
sound_pressure: 声压级,单位为dB或dBA。
speed: 速度,单位为ft/s、in/d、in/h、km/h、kn、m/s、mph或mm/d。
sulphur_dioxide: 二氧化硫浓度,单位为µg/m³。
temperature: 温度,单位为°C、°F或K。
timestamp: 日期时间对象或时间戳字符串(ISO 8601)。
volatile_organic_compounds: 挥发性有机化合物浓度,单位为µg/m³。
volatile_organic_compounds_parts: 挥发性有机化合物的比例,单位为ppm或ppb。
voltage: 电压,单位为V、mV。
volume: 体积,单位为L、mL、gal、fl. oz.、m³、ft³或CCF。
volume_storage: 储存体积,单位为L、mL、gal、fl. oz.、m³、ft³或CCF。
water: 水消耗量,单位为L、gal、m³、ft³或CCF。
weight: 质量,单位为kg、g、mg、µg、oz、lb或st。
wind_speed: 风速,单位为ft/s、km/h、kn、m/s或mph。

(2)"state_class"对应的设置:
1. 传感器的值永远不会重置,例如,终生总能耗或生产:state_class,未设置为或设置为total、last_reset、None
2. 传感器的值可能会重置为 0,其值只能增加:state class 。示例:与计费周期一致的能源消耗,例如每月,每次断开连接时,电表都会重置为 0 则,total_increasing
3. 传感器的值可以重置为 0,其值可以增加和减少: 状态类 ,当值重置时更新。例如:与计费周期一致的净能耗,例如每月。totallast_reset
4. 传感器的状态会随着每次状态更新而重置,例如,传感器每分钟更新一次过去一分钟的能耗:状态类,每次状态更改都会更新。totallast_reset

四、完成数据发布

先做个实验:用MQTTX客户端连接MQTT服务器,发布一条数据

topic: ddsu666/voltage/state (这个可以看上一节添加实体的topic)

"state_topic": "ddsu666/power/state",

内容就直接填个数据:33
在这里插入图片描述
发布完看看HASS里面的MQTT数据是否变了。

五、ESP32发布数据

后面的就更简单了。。搭建电路就不说了,我用的Arduino。用的是PubSubClient库。

程序参考库的例子。
说一下读正泰的电量表吧。

//电能表 SUDD6666
float   U,  //电压8192
        I,  //电流8194
        P,  //瞬时功率8196
        Q,  //瞬时无功功率8198
        S,  //瞬时视在功率8200
        PF, //功率因数8202
        Fr, //电网频率8204
        EP; //总功率16384

这个是电量表的modbus地址,ESP32添加ModbusRTU库。

//两个uint16t 转化位Float
float intof(uint16_t a,uint16_t b){
    bigSwit.u[0]=b;
    bigSwit.u[1]=a;
    return bigSwit.f;
}

// 任务:RTU
void Task_RTU( void *pvParameters ){

    Serial2.begin(9600,SERIAL_8N2,34,32);    //定义串口通讯,波特率 校验方式
    mb.begin(&Serial2);
    mb.master();
    vTaskDelay(1000);
    for(;;){
        vTaskDelay(10);
        if (!mb.slave()) {                // 检查是否没有正在进行的事务
            mb.readHreg(1,8192,res,14,cb);  // 从Modbus服务器发送读取Hreg
            while(mb.slave()) {             // 检查交易是否处于活动状态
                mb.task();
                vTaskDelay(10);
            }
            U=intof(res[0],res[1]);
            I=intof(res[2],res[3]);
            P=intof(res[4],res[5]);
            Q=intof(res[6],res[7]);
            S=intof(res[8],res[9]);
            PF=intof(res[10],res[11]);
            Fr=intof(res[12],res[13]);
        }
        if (!mb.slave()) {
            mb.readHreg(1,16384,res1,2,cb);
            while(mb.slave()) {
            mb.task();
            vTaskDelay(10);
            }
            EP=intof(res1[0],res1[1]);
        }

    }
}

发布MQTT就更简单了,也用不到订阅。建个定时器。

void time02(){
    digitalWrite(LED,!digitalRead(LED));
    if (mqtt_client.connect("ddsu666")){   //为什么要加这个,因为每次都需要连接一下,不然值不变。。。不知道啥原因。
	    mqtt_client.publish("ddsu666/voltage/state",String(U).c_str());
	    vTaskDelay(100);
	    mqtt_client.publish("ddsu666/current/state",String(I).c_str());
	    vTaskDelay(100);
	    mqtt_client.publish("ddsu666/power/state",String(P).c_str());
	    vTaskDelay(100);
	    mqtt_client.publish("ddsu666/electricity/state",String(EP).c_str());
	    vTaskDelay(100);}
    }

setup()函数里添加

    mqtt_client.setServer(mqtt_broker, mqtt_port);
    mqtt_client.setCallback(mqttCallback);
    connectToMQTTBroker();

connectToMQTTBroker()函数内容是:

void connectToMQTTBroker() {
    while (!mqtt_client.connected()) {

        Serial.printf("Connecting to MQTT Broker as %s.....\n", client_id.c_str());
        if (mqtt_client.connect("ddsu666", mqtt_username, mqtt_password)) {
            Serial.println("Connected to MQTT broker");
            mqtt_client.subscribe("ddsu666/electricity/state");
            // Publish message upon successful connection
          //  mqtt_client.publish("ddsu666/electricity/state", "98.65");
        } else {
            Serial.print("Failed to connect to MQTT broker, rc=");
            Serial.print(mqtt_client.state());
            Serial.println(" try again in 1 seconds");
            delay(1000);
        }
    }
}

其实connectToMQTTBroker()可以简化mqtt_client.connect(“ddsu666”)。

至此 就ok了 剩下的继续探索吧,少年!

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值