找回密码
 立即注册
搜索
查看: 19926|回复: 52

[基础教程] 汉非太阳能(光伏)控制器接入ha小白级教程

  [复制链接]

9

主题

127

回帖

916

积分

高级会员

积分
916
金钱
780
HASS币
0
发表于 2021-12-20 20:15:14 | 显示全部楼层 |阅读模式
本帖最后由 zjhcr 于 2021-12-25 13:49 编辑

先上成果图
haa.png

IMG_2718.JPG

前言本人从入门ha到现在也有一段时间了,从什么都不懂的小白慢慢到开始对ha稍有眉目,回顾这段时间走过来的路,曲折又受益良多。在这里非常感谢论坛里的一众大神们,是他们努力的启蒙才有今天我们从容面对各种问题的动力。
楼主玩ha能源板块有一段时间了,最开始使用PZEM-004T模块接入ha测量家庭电量消耗,到后来突发奇想到,把自家的太阳能控制器也给接入ha,方便统一察看和记录。经过多次努力,终于成功把太阳能控制器接入了ha。
本着人人为我、我为人人、饮水思源的心态,特意抽空写了这一篇文分享给各位,希望对新手也能有所启示和帮助(虽然我自己也是一个新手,很多东西不懂的还是得去问去了解,哈哈)。

首先上场的是今天的主角,来自武汉汉非科技出品的MPPT太阳能控制器,某宝上比较常见的一款控制器,光和硅能也有代理它的产品,特点是MPPT效率高,自损耗小,性价比也不错,楼主的这款是120D带WiFi通讯款。110D、130D、140D等不同数值的款仅尺寸和能接受的最大电流(光伏板功率)有所不同,其他功能大同小异
003353awjrdks1l8tnppnt.png
第一章:联网,将控制器自带的通讯从热点模式改为接入WiFi网络
原厂商家提供官方的APP,通过控制器自带的WiFi接入点接入到手机,然后打开app刷新即可看到控制器的数据,我这里仅作截图演示,没有实际连接
微信图片_20211220193650.png
使用APP看数据有诸多不便之处,例如没法显示即时数据,每次都需要手动刷新,然后就是只能在其WiFi范围下使用,远离控制器的范围就无法使用了。
根据自己多年玩数控的经验判断,控制器应该是使用了一颗内置WiFi透传的单片机,将串口数据通过以WiFi网络传输。不哆嗦,立马安排拆解以验明其真实性

拆开控制器,果不其然一颗硕大的ESP-12F芯片通过排线连接在了控制器主板的上方,排线由4根线组成,分别是电源输入的+、-和串口数据的TX和RX。引脚顺序如图示
微信图片_20211220193218.jpg

微信图片_20211220193226.jpg
考虑到通讯版和非通讯版有着几十元的差价,理论上非通讯版可以通过后期加装透传模块或引出TX、RX串口针脚来实现通讯功能,有条件的朋友可以尝试验证一下。需要注意的是,+、-的供电电压是直连电池端的电压,譬如24v的电池组,这两引脚测量出就是24v左右的电压,自带的通讯模块板子上具有3.3v稳压芯片,非通讯版自行加装透传模块的切勿直接接入ESP芯片,否则会立即烧毁。
txrx.png

印证了WiFi透传模块是ESP-12F核心之后,开始琢磨连接网络。控制器自带的WiFi是AP模式,根据连上它的热点之后获取的网关是11.11.11.254,顺藤摸瓜,浏览器打开这个地址,发现ESP-12F所使用的是esp-link这一固件
esp-link.png
点击左边的WiFi Station栏,可以切换无线网络模式,先点一下下方的Switch to,切换成STA模式,也就是从原来的AP模式改成STA终端模式接入到我们家里的WiFi网络去,然后右边就会有自动扫描出附近的WiFi,找到自己家的那个,点击,并在最下方输入密码,然后点击Connect连接
esp-link2.png

connect.png

点完connect之后,esp-link的页面就会失联,不用担心,这是因为WiFi接入点丢失和控制器ip地址变化了,所以会提示丢失连接。这时候只需要到路由器查看esp-link连上WiFi后的内网DHCP获取的新地址,重新浏览器输入就可以继续操作了,就像局域网内的机器那样了。如果担心DHCP获取的地址经常变化,可以再到WiFi Station页面上最下方给esp-link设置固定IP。需要注意的是,如果使用11.11.11.254以外的IP地址,手机APP客户端将无法再连接控制器,因为APP只认11.11.11.254这个地址进行通讯,无法修改。如果需要同时使用手机app和联网功能的话,那么最好想办法继续使用11.11.11.254作为地址又确保内网能访问到(举个解决办法:二级路由或者网关地址拓展)
staticip.png

以下为调试部分,如果确信接入网络的操作没有问题,可以略过这部分内容:
连接上本地网络之后,可以先用官方的PC上位机软件(附件有提供)来测试是否正常连通
上位机1.png

点击左上角设置,通信模式选以太网,IP地址输esp-link获取到的内网IP,端口8088,通过与厂家确认,我这款控制器使用的是比较常见的Modbus协议,因此通讯协议选择TCP_Modbus,控制器类型MPPT
上位机2.png

设置好后返回主界面点击连接,主界面的右侧开始跑码,而主界面的所有数据都能更新显示出来,上位机成功获取控制器数据,至此网络接入调试完成。
上位机3.png

Tips:另外也可以用ModScan32这个软件来对Modbus设备进行测试,对于其他一些不是汉非的但支持Modbus标准的控制器也可以用ModScan32来连接测试获取数据。Modbus是标准工业协议,HA也能直接支持对Modbus协议的读取和写入,这是它巨大的优势所在 ModScan32.zip (2.15 MB, 下载次数: 65)
modscan1.png

modscan2.png


                               
登录/注册后可看大图

MODBUS Point Type选择03:Holding Register
可以看到ModScan32连接成功后,下方数表就会有变化的数值出现了,对照厂家提供的协议就能知道是什么的数值(下一章讲到协议)

第二章:协议
所谓协议,用我不专业但通俗的解读就是能和设备进行握手通讯,读懂通讯内容的“字典”。通信双方必须共同遵从的一组约定。如怎么样建立连接、怎么样互相识别等。只有遵守这个约定,设备之间才能相互通信交流。通过查阅官方说明和厂商的文档,得知我的这个控制器使用的是一种工业上比较常见的Modbus标准协议,这是一个大框架协议,我把它称作大协议。Modbus协议的原理我们不需要懂,只需要知道这个协议规定了很多寄存地址,而寄存地址下的数值有对应的数据或者功能代码,通过对地址的数值进行读取或者写入,能达到我们对设备进行读数或者控制的目的。而厂家在开发时会有对设备数据相对应是哪个地址的数据说明书,我称它作小协议,只有拿到了小协议,我们才清楚通过Modbus读取的数据哪个对应的是设备哪个数值或者功能,大协议是我们能够建立通讯的前提,小协议是我们能解读数据内容的关键。因此拿到小协议是咱们下一步对接入HA的关键所在,一般厂家都能够提供他们的协议,咨询售后即可。汉非的太阳能控制器协议楼主附件提供上,供大家学习使用 控制器通信协议(ModBus版)公开文件V1.0.0_CN.pdf (327.16 KB, 下载次数: 55)
协议1.png

协议2.png
翻到下面,寄存器地址与名称,这才是我们需要的精华内容,每个地址分别对应了不同的数据和功能,譬如0x0001对应的是“太阳能电池板电压”数值
协议3.png

通过对比ModScan32调试软件读取的数列表可以见到40002(实际ModScan32里40001应该是代表地址起始0,而40002对应的是1也就是0x0001,ModScan32上显示的是10进制地址而协议书上的是16进制地址有所不同,但只要能找对顺序下来就很好对应解读,Modbus的最大优势就是顺序地址)这个地址的数值1261,刚好就是我控制器显示的太阳能电池板电压的数值(实际是12.61,小数点不对,没关系,后面可以在HA里取模调整)

协议4.png

如此按地址顺序对照,我们发现地址的顺序和数值与协议书上的描述都一一对应上了,接下来可以为接入HA做准备了。

第三章:接入Home Assistant终于来到了重头戏,把控制器对接入HA。前面铺垫那么多,最终目的不都是为了接入我们的HA嘛。
通过查阅HA的官方文档,发现HA是能够直接支持Modbus协议的
具体可以参照官方文档
https://www.home-assistant.io/integrations/modbus/
2.png

利用ha目录下新建packages文件夹,把原本要修改configuration.yaml的内容都新建成yaml文件往packages文件夹里放,方便增减配置文件和排错,这个新手都应该学会的技能了吧
新手必备技能 【package】【检测配置】https://bbs.hassbian.com/thread-1114-1-1.html
packages目录下新建一个名为mppt.yaml的文件,用NotePad++打开编辑
把以下代码复制粘贴进去

(论坛字数限制,接第16楼继续,附件链接在16楼)顺便在1楼向各位路过的大佬咨询,如何解决模板sensor无法增加state_class: total_increasing 参数,致使发电量数据暂时还没有办法接入HA的能源板块的问题















评分

参与人数 2金钱 +7 收起 理由
froyo + 2 论坛有你更精彩!
zero_33 + 5 墙都不扶,就服楼主!

查看全部评分

回复

使用道具 举报

9

主题

127

回帖

916

积分

高级会员

积分
916
金钱
780
HASS币
0
 楼主| 发表于 2021-12-20 21:12:23 来自手机 | 显示全部楼层
yylwhy 发表于 2021-12-20 21:10
在海鲜市场看到了块2*1 450W的 太阳能板

我的板子都是捡的二手,隔壁城市的玩家升级下来的,150元2块380瓦便宜捡,自己开车拉回来
回复

使用道具 举报

9

主题

127

回帖

916

积分

高级会员

积分
916
金钱
780
HASS币
0
 楼主| 发表于 2021-12-21 09:22:08 来自手机 | 显示全部楼层
nuaawmy 发表于 2021-12-21 06:49
一直没搞懂能源板块怎么调出来的,家里电表介接入了HA,能看功率 电压 电流,配置文件里要输啥命令吗 ...

什么样的电表?只有功率电压电流没有用电量计量吗。能源板块要求有用电量的实体并且具备一些特定属性
回复

使用道具 举报

9

主题

127

回帖

916

积分

高级会员

积分
916
金钱
780
HASS币
0
 楼主| 发表于 2021-12-21 10:41:34 | 显示全部楼层
marinefei 发表于 2021-12-21 09:59
太阳能板??是不是太阳能热水器的板子也能利用起来了?

不一样的东西,咱们说的太阳能板是指光伏板
回复

使用道具 举报

9

主题

127

回帖

916

积分

高级会员

积分
916
金钱
780
HASS币
0
 楼主| 发表于 2021-12-21 10:57:59 | 显示全部楼层
zkxa 发表于 2021-12-21 10:41
啥时候更新呢。

今晚。白天上班哈哈哈
回复

使用道具 举报

9

主题

127

回帖

916

积分

高级会员

积分
916
金钱
780
HASS币
0
 楼主| 发表于 2021-12-21 11:43:21 | 显示全部楼层
ztrx 发表于 2021-12-21 11:15
用锂电池?感觉怕怕的

目前我还是在用淘汰下来修复的铅酸电瓶
但还是建议一步到位上锂电,锂电不会像铅酸吃得多放得少。
三元锂危险点,用磷酸铁锂还是挺安全的呀
回复

使用道具 举报

9

主题

127

回帖

916

积分

高级会员

积分
916
金钱
780
HASS币
0
 楼主| 发表于 2021-12-21 16:40:34 来自手机 | 显示全部楼层
telanx 发表于 2021-12-21 16:35
我擦,这个市政让随便接吗?得放楼顶上吧?要不光照只有挺短时间的吧?然后拉根线下来接入电表?那还得弄两 ...

你说的那是并网,离网是不接入市电,不需要任何批准手续的,有地方放光伏板就行。是的,楼顶光照最好,没有遮挡最合适
回复

使用道具 举报

9

主题

127

回帖

916

积分

高级会员

积分
916
金钱
780
HASS币
0
 楼主| 发表于 2021-12-21 21:01:45 | 显示全部楼层
本帖最后由 zjhcr 于 2021-12-21 21:52 编辑

接1楼继续

modbus:
  - type: tcp
    close_comm_on_error: false
#host、port改成你控制器的IP和端口
    host: 192.168.1.86
    port: 8088
    name: hub1
    sensors:
      - name: PV_Voltage
        slave: 1
        address: 1
        input_type: holding
        unit_of_measurement: V
        scale: 0.01
        precision: 2
        device_class: voltage
        scan_interval: 5
      - name: PV_Current
        slave: 1
        address: 2
        input_type: holding
        unit_of_measurement: A
        scale: 0.01
        precision: 2
        device_class: current
        scan_interval: 5
      - name: PV_Power
        slave: 1
        address: 3
        unit_of_measurement: W
        device_class: power
        input_type: holding
        scan_interval: 5
      - name: PV_State
        slave: 1
        address: 4
        input_type: holding
        scan_interval: 5
      - name: Battery_Voltage
        slave: 1
        address: 5
        unit_of_measurement: V
        scale: 0.01
        precision: 2
        device_class: battery
        input_type: holding
        scan_interval: 5
      - name: Battery_Temperature
        slave: 1
        address: 6
        unit_of_measurement: °C
        device_class: temperature
        input_type: holding
        scan_interval: 5
      - name: Charge_Current
        slave: 1
        address: 7
        unit_of_measurement: A
        scale: 0.01
        precision: 2
        device_class: current
        input_type: holding
        scan_interval: 5
      - name: Discharge_Current
        slave: 1
        address: 8
        unit_of_measurement: A
        scale: 0.01
        precision: 2
        device_class: current
        input_type: holding
        scan_interval: 5
      - name: Battery_Level
        slave: 1
        address: 10
        unit_of_measurement: "%"
        device_class: battery
        input_type: holding
        scan_interval: 5
      - name: Charge_State
        slave: 1
        address: 11
        input_type: holding
        scan_interval: 5
      - name: Controller_Temperature
        slave: 1
        address: 12
        unit_of_measurement: °C
        device_class: temperature
        input_type: holding
        scan_interval: 5
      - name: Controller_TotalEnergy
        slave: 1
        address: 16
        unit_of_measurement: kAh
        device_class: energy
        input_type: holding
        scan_interval: 5
      - name: Controller_TotalUsed
        slave: 1
        address: 20
        unit_of_measurement: Ah
        device_class: energy
        input_type: holding
        scan_interval: 5

sensor:
  - platform: template
    sensors:
      pv_state_change:
        friendly_name: '光伏板状态'
        value_template: >
          {% if is_state('sensor.pv_state', '0') %}
            低电压未发电
          {% elif is_state('sensor.pv_state', '1') %} 
            发电中
          {% elif is_state('sensor.pv_state', '2') %} 
            过压保护
          {% elif is_state('sensor.pv_state', '3') %} 
            光伏板未接入
          {% endif %}
      pv_voltage_change:
        unit_of_measurement: V
        device_class: voltage
        friendly_name: '光伏板电压'
        value_template: >
          {% set state = states('sensor.pv_voltage') %}{{ (state) }}
      pv_current_change:
        unit_of_measurement: A
        device_class: current
        friendly_name: '光伏板电流'
        value_template: >
          {% set state = states('sensor.pv_current') %}{{ (state) }}
      pv_power_change:
        unit_of_measurement: W
        device_class: power
        friendly_name: '光伏功率'
        value_template: >
          {% set state = states('sensor.pv_power_change2') %}{{ (state) }}
      battery_voltage_change:
        unit_of_measurement: V
        device_class: voltage
        friendly_name: '蓄电池电压'
        value_template: >
          {% set state = states('sensor.battery_voltage') %}{{ (state) }}
      discharge_current_change:
        unit_of_measurement: A
        device_class: current
        friendly_name: '放电电流'
        value_template: >
          {% set state = states('sensor.discharge_current') %}{{ (state) }}
      discharge_power_change:
        unit_of_measurement: W
        device_class: power
        friendly_name: '放电功率'
        value_template: >
          {% set state = states('sensor.discharge_power_change2') %}{{ (state) }}
      controller_temperature_change:
        unit_of_measurement: °C
        device_class: temperature
        friendly_name: '控制器温度'
        value_template: >
          {% set state = states('sensor.controller_temperature') %}{{ (state) }}
      battery_temperature_change:
        unit_of_measurement: °C
        device_class: temperature
        friendly_name: '蓄电池温度'
        value_template: >
          {% set state = states('sensor.battery_temperature') %}{{ (state) }}
      battery_level_change:
        unit_of_measurement: "%"
        device_class: temperature
        friendly_name: '蓄电池电量'
        value_template: >
          {% set state = states('sensor.battery_level') %}{{ (state) }}
      charge_state_change:
        friendly_name: '充电模式'
        value_template: >
          {% if is_state('sensor.pv_state', '0') %}
            停充
          {% elif is_state('sensor.pv_state', '1') %} 
            强充
          {% elif is_state('sensor.pv_state', '2') %} 
            MPPT
          {% elif is_state('sensor.pv_state', '3') %} 
            浮充
          {% elif is_state('sensor.pv_state', '4') %} 
            提升
          {% elif is_state('sensor.pv_state', '5') %} 
            均衡
          {% elif is_state('sensor.pv_state', '6') %} 
            恒流
          {% elif is_state('sensor.pv_state', '7') %} 
            恒压
          {% endif %}
      controller_totalenergy_change:
        unit_of_measurement: kWh
        device_class: energy
        friendly_name: '总发电量'
        value_template: >
          {% set state = states('sensor.controller_totalenergy') %}{{ (state | float * 0.12 ) | round(2)}}
      controller_totalused_change:
        unit_of_measurement: kWh
        device_class: energy
        friendly_name: '总用电量'
        value_template: >
          {% set state = states('sensor.controller_totalused') %}{{ (state | float * 0.012 ) | round(2)}}

template:
  - sensor:
      - name: "PV Power Change2"
        unit_of_measurement: W
        state: "{{ (states('sensor.battery_voltage')|float * states('sensor.pv_current')|float ) | round(2) }}"
        device_class: power
      - name: "Discharge Power Change2"
        unit_of_measurement: W
        state: "{{ (states('sensor.battery_voltage')|float * states('sensor.Discharge_Current')|float ) | round(2) }}"
        device_class: power


如果只想白嫖代码的话,到这里直接复制粘贴就已经基本完成了,如果想学习代码的内容那么可以接着往下看
首先modbus: 调用HA的Modbus协议支持host: 和 port: 需要改成你自己控制器接入了内网的地址和端口

sensors: 部分就是HA的通过获取到的Modbus数据转换成传感器参数,这里举一个例子:
    sensors:
      - name: PV_Voltage  #在HA里生成的实体名称,这里取PV_Voltage意为光伏板电压
        slave: 1     #从位数,Modbus作用于TCP模式时可不填,我统一填1
        address: 1   #地址,这个就是前面我提到协议里的地址,1代表0x0001,读取地址1的数据
        input_type: holding #输入类型,对应的是ModScan32里的03:Holding Register,一般读数都选择该类型
        unit_of_measurement: V #测量单位,V代表是电压,根据所读的数属于哪种单位来填写,例如电流是A
        scale: 0.01     #通过Modbus读取过来的光伏电压数值是1267,实际是12.67,需用使用该参数转换增加小数点
        precision: 2    #保留小数点后2位精度
        device_class: voltage   #设备种类,这个属于电压,具体有哪些设备种类可参照HA官方文档
        scan_interval: 5    #扫描间隔,就是每隔多久更新一次数据,单位是秒
如此类推把所有对应的地址和协议中的数值都可以读取成为HA里的实体……
由于原厂读取的光伏功率和放电功率都是没有数值(厂家bug?),所以我又建了两个模板sensor用公式自己拿电压和电流乘积得出两个功率的实体,又另外把发电量和用电量原本是Ah安时的单位转换成了kWh千瓦时,但发现模板sensor无法增加state_class: total_increasing 参数,致使发电量数据暂时还没有办法接入HA的能源板块,这个问题有待解决
添加好代码内容后保存mppt.yaml

然后重启HA
可以在实体注册表里看到了很多新生成的实体
ha实体.png

剩下的事情,就是拿这些实体在Lovelace,也就是HA的主界面,新建你喜欢的卡片类型来展示,就可以了。
注意要选取中文名称的那些实体哈哈
ha实体2.png
对了,如果经常出现“实体不可用”的显示,则要考虑是否存在控制器与WiFi连接的信号强度不佳,ESP-12F内置芯片信号没那么强

ModScan32、汉非控制器的协议文件、MPPT.yaml这几样都在附件里了
上位机软件和NotePad++都超过了3M的附件限制,无法发附件里了
最后还请路过的大佬们帮忙解决一下模板sensor无法增加state_class: total_increasing 参数,致使发电量、用电量这两实体的数据暂时还没有办法接入HA的能源板块这个问题,万分感谢~

ModScan32.zip

2.15 MB, 下载次数: 28

控制器通信协议(ModBus版)公开文件V1.0.0_CN.pdf

327.16 KB, 下载次数: 16

mppt.yaml.rar

1.21 KB, 下载次数: 25

回复

使用道具 举报

9

主题

127

回帖

916

积分

高级会员

积分
916
金钱
780
HASS币
0
 楼主| 发表于 2021-12-21 21:54:37 | 显示全部楼层
sss190 发表于 2021-12-21 21:34
楼主你怎么应用的?是接了逆变器还是ups

我玩的光伏功率不大,电池也不大,基本都是直流负载,有摄像头、有路由器有网桥、有工控机,到了夏天光照好的时候,带个逆变器来带带风扇吹吹风,哈哈
回复

使用道具 举报

9

主题

127

回帖

916

积分

高级会员

积分
916
金钱
780
HASS币
0
 楼主| 发表于 2021-12-21 22:01:46 | 显示全部楼层
sss190 发表于 2021-12-21 21:40
如果搞明白了协议,其实可以直接刷esp12f,刷成esphome固件,可以直接接入ha

一开始的思路我也是这么想的,后来发现这个内置的12F原厂esp-link固件剩余空间太小,无法直接通过无线OTA刷入新固件,要拆机飞线刷,比较麻烦,我的设备都已经全部接好电线固定上机柜。其次是这个控制器它用的是Modbus标准协议,后来刚好看到HA能够直接支持Modbus TCP通讯,干脆直接用HA读取Modbus,12F继续用esp-link充当透传,反而还更省事了~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian ( 晋ICP备17001384号-1 )

GMT+8, 2025-7-2 14:28 , Processed in 0.121499 second(s), 10 queries , MemCached On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表