Hi, sorry i cant answer your question… Really need the SOC myself too, as thats the main reason i want to try this…
But, do you have the display plugged in, or use a TTL<->RS485 converter? How have you set it up? Are you using a d1 mini?
The display arrived today, will have a go at it tomorrow…
I am using an ESP32s and I connect TX, RX, and GND direct to KG140F. The display is plugged in and “on”.
I have SCO working, at least matches what they have on the app. SOC = Ah remaining / Battery capacity (Amp) * 100
Anyone can help in reducing the frequency of the serial log from 10s to 30s or 60s? This may be one of the reasons HA is freezing for some people.
Hi, i have gotten a d1 mini reading the data from the shunt, but when i add the lines:
mqtt:
- name: D1_mini_1
topic: tele/D1_mini_1/RESULT
To my config yaml file, i get this error when checking the config yaml file before i boot: (the topic name in my tasmota config is D1_mini_1). Do i need a ‘full topic’?
Invalid config for [mqtt]: expected dictionary for dictionary value @ data[‘mqtt’]. Got [OrderedDict([(‘name’, ‘D1_mini_1’), (‘topic’, ‘tele/D1_mini_1/RESULT’)])]. (See /config/configuration.yaml, line 198).
Any ideas? (sorry, im new to HA etc)
Hi, i have gotten a d1 mini reading the data from the shunt, but when i add the lines:
mqtt:
- name: D1_mini_1
topic: tele/D1_mini_1/RESULT
To my config yaml file, i get this error when checking the config yaml file before i boot: (the topic name in my tasmota config is D1_mini_1). Do i need a ‘full topic’?
Invalid config for [mqtt]: expected dictionary for dictionary value @ data[‘mqtt’]. Got [OrderedDict([(‘name’, ‘D1_mini_1’), (‘topic’, ‘tele/D1_mini_1/RESULT’)])]. (See /config/configuration.yaml, line 198).
Any ideas?
For example, i have the lines in tasmota console:
18:10:31.823 MQT: tele/D1_mini_1/RESULT = {“SerialReceived”:":R50=1,\n:r50=1,87,2669,200,268391,98603,387360,0,129,0,99,0,8420,1000,\r\n:R51=1,\n:r51=1,143,0,0,0,0,0,100,0,0,2800,100,100,100,0,1,1,\r\n"}
Mine is done differently. Try this.
template:
- trigger:
- platform: mqtt
topic: tele/D1_mini_1/RESULT
sensor:
- name: Freezer Battery Temperature
unit_of_measurement: "°C"
state: "{{ (trigger.payload.split(',')[9] | float-100) }}"
Thanks, trying how you say, unfortunately nothing shows up, and i now get this in the logs:
Logger: homeassistant.config
Source: config.py:982
First occurred: 8:21:48 PM (3 occurrences)
Last logged: 8:23:50 PM
Invalid config for [template]: [trigger] is an invalid option for [template]. Check: template->sensor->3->trigger. (See /config/configuration.yaml, line 183).
Invalid config for [template]: [trigger] is an invalid option for [template]. Check: template->sensor->3->trigger. (See /config/configuration.yaml, line 180).
Any ideas whay? Thanks again
Post your yaml config. I am not an expert but let me see if I can help
Hi, thanks for offering your time (scroll to the bottom, the rest of the yaml it for my inverter, that all works fine…)
default_config:
# Load frontend themes from the themes folder
frontend:
themes: !include_dir_merge_named themes
# Text to speech
tts:
- platform: google_translate
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
http:
use_x_forwarded_for: true
trusted_proxies:
- 172.30.33.0/24
modbus:
- name: epever
type: rtuovertcp
host: 192.168.0.188
port: 8088
delay: 5
timeout: 10
close_comm_on_error: false
retry_on_empty: true
retries: 20
sensors:
# Utility
- name: "Grid Voltage"
unit_of_measurement: V
slave: 10
address: 0x3500
input_type: input
scale: 0.01
precision: 2
- name: "Grid Current"
unit_of_measurement: A
slave: 10
address: 0x3501
input_type: input
scale: 0.01
precision: 2
- name: "Grid State"
# 0:Normal, 1:Low input; 2:High input, 3: No connected
slave: 10
address: 0x3511
input_type: input
- name: "Grid Total"
unit_of_measurement: kWh
slave: 10
address: 0x350F
input_type: input
scale: 0.01
precision: 2
data_type: int32
swap: word
count: 2
# PV Array
- name: "PV Voltage"
unit_of_measurement: V
slave: 10
address: 0x3549
input_type: input
scale: 0.01
precision: 2
- name: "PV Current"
unit_of_measurement: A
slave: 10
address: 0x354A
input_type: input
scale: 0.01
precision: 2
- name: "PV Power"
unit_of_measurement: W
slave: 10
address: 0x354B
input_type: input
scale: 0.01
precision: 2
data_type: int32
swap: word
count: 2
- name: "PV Total"
unit_of_measurement: kWh
slave: 10
address: 0x3557
input_type: input
scale: 0.01
precision: 2
data_type: int32
swap: word
count: 2
# Load
- name: "Load Voltage"
unit_of_measurement: V
slave: 10
address: 0x3521
input_type: input
scale: 0.01
precision: 2
- name: "Load Current"
unit_of_measurement: A
slave: 10
address: 0x3522
input_type: input
scale: 0.01
precision: 2
- name: "Load Total"
unit_of_measurement: kWh
slave: 10
address: 0x3530
input_type: input
scale: 0.01
precision: 2
data_type: int32
swap: word
count: 2
# Battery
- name: "Battery Voltage"
unit_of_measurement: V
slave: 10
address: 0x3580
input_type: input
scale: 0.01
precision: 2
- name: "Battery Current"
unit_of_measurement: A
slave: 10
address: 0x3581
input_type: input
scale: 0.01
precision: 2
- name: "Battery Capacity"
unit_of_measurement: "%"
slave: 10
address: 0x3586
input_type: input
scale: 1
- name: "Battery Temp"
#ElectricChrgBatteryTemp
unit_of_measurement: "°C"
slave: 10
address: 0x3512
input_type: input
scale: 0.01
- name: "Battery State"
# 0:Normal, 1:Overvoltage, 2:Undervoltage, 3:Undervoltage Disconnect, 4:Fault
slave: 10
address: 0x3589
input_type: input
- name: "Charging Mode"
# 1:Solar Priority, 2:Utility & Solar, 3:Solar
slave: 10
address: 0x9607
input_type: holding
- name: "Inverter Mode"
# 0:Inverter priority, 1:Utility Priority
slave: 10
address: 0x9608
input_type: holding
- name: "Inverter Temp"
#LoadHeatSink2Temp
unit_of_measurement: "°C"
slave: 10
address: 0x3533
input_type: input
scale: 0.01
template:
sensor:
- name: "Grid Power"
unit_of_measurement: W
device_class: power
state: "{{((states('sensor.grid_current')| float(0) * states('sensor.grid_voltage')| float(0))) | round(2) }}"
- name: "Power into batt"
state: "{{ states('sensor.grid_power') | float + states('sensor.pv_power') | float }}"
unit_of_measurement: W
device_class: power
- name: "House Load"
unit_of_measurement: W
device_class: power
state: "{{((states('sensor.load_current')| float(0) * states('sensor.load_voltage')| float(0))) | round(2) }}"
- trigger:
- platform: mqtt
topic: tele/D1_mini_1/RESULT
sensor:
- platform: integration
source: sensor.house_load
name: energy_used
unit_prefix: k
round: 2
Also, when adding - trigger: - platform: mqtt topic: tele/D1_mini_1/RESULT
then sensors grid_power and house_load stop working also… Causing some kind of problem with the template i think?
see if this works. I put trigger before the sensor.
template:
- trigger:
- platform: mqtt
topic: tele/D1_mini_1/RESULT
sensor:
- name: "Grid Power"
unit_of_measurement: W
device_class: power
state: "{{((states('sensor.grid_current')| float(0) * states('sensor.grid_voltage')| float(0))) | round(2) }}"
- name: "Power into batt"
state: "{{ states('sensor.grid_power') | float + states('sensor.pv_power') | float }}"
unit_of_measurement: W
device_class: power
- name: "House Load"
unit_of_measurement: W
device_class: power
state: "{{((states('sensor.load_current')| float(0) * states('sensor.load_voltage')| float(0))) | round(2) }}"
Thanks very much, if also been having a bit of help on another thread i made, and is working now
Pasted some more lines from giro above to test, but needs some editing as wrong values for current and capacity
# Loads default set of integrations. Do not remove.
default_config:
# Load frontend themes from the themes folder
frontend:
themes: !include_dir_merge_named themes
# Text to speech
tts:
- platform: google_translate
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
http:
use_x_forwarded_for: true
trusted_proxies:
- 172.30.33.0/24
modbus:
- name: epever
type: rtuovertcp
host: 192.168.0.188
port: 8088
delay: 5
timeout: 10
close_comm_on_error: false
retry_on_empty: true
retries: 20
sensors:
# Utility
- name: "Grid Voltage"
unit_of_measurement: V
slave: 10
address: 0x3500
input_type: input
scale: 0.01
precision: 2
- name: "Grid Current"
unit_of_measurement: A
slave: 10
address: 0x3501
input_type: input
scale: 0.01
precision: 2
- name: "Grid State"
# 0:Normal, 1:Low input; 2:High input, 3: No connected
slave: 10
address: 0x3511
input_type: input
- name: "Grid Total"
unit_of_measurement: kWh
slave: 10
address: 0x350F
input_type: input
scale: 0.01
precision: 2
data_type: int32
swap: word
count: 2
# PV Array
- name: "PV Voltage"
unit_of_measurement: V
slave: 10
address: 0x3549
input_type: input
scale: 0.01
precision: 2
- name: "PV Current"
unit_of_measurement: A
slave: 10
address: 0x354A
input_type: input
scale: 0.01
precision: 2
- name: "PV Power"
unit_of_measurement: W
slave: 10
address: 0x354B
input_type: input
scale: 0.01
precision: 2
data_type: int32
swap: word
count: 2
- name: "PV Total"
unit_of_measurement: kWh
slave: 10
address: 0x3557
input_type: input
scale: 0.01
precision: 2
data_type: int32
swap: word
count: 2
# Load
- name: "Load Voltage"
unit_of_measurement: V
slave: 10
address: 0x3521
input_type: input
scale: 0.01
precision: 2
- name: "Load Current"
unit_of_measurement: A
slave: 10
address: 0x3522
input_type: input
scale: 0.01
precision: 2
- name: "Load Total"
unit_of_measurement: kWh
slave: 10
address: 0x3530
input_type: input
scale: 0.01
precision: 2
data_type: int32
swap: word
count: 2
# Battery
- name: "Battery Voltage"
unit_of_measurement: V
slave: 10
address: 0x3580
input_type: input
scale: 0.01
precision: 2
- name: "Battery Current"
unit_of_measurement: A
slave: 10
address: 0x3581
input_type: input
scale: 0.01
precision: 2
- name: "Battery Capacity"
unit_of_measurement: "%"
slave: 10
address: 0x3586
input_type: input
scale: 1
- name: "Battery Temp"
#ElectricChrgBatteryTemp
unit_of_measurement: "°C"
slave: 10
address: 0x3512
input_type: input
scale: 0.01
- name: "Battery State"
# 0:Normal, 1:Overvoltage, 2:Undervoltage, 3:Undervoltage Disconnect, 4:Fault
slave: 10
address: 0x3589
input_type: input
- name: "Charging Mode"
# 1:Solar Priority, 2:Utility & Solar, 3:Solar
slave: 10
address: 0x9607
input_type: holding
- name: "Inverter Mode"
# 0:Inverter priority, 1:Utility Priority
slave: 10
address: 0x9608
input_type: holding
- name: "Inverter Temp"
#LoadHeatSink2Temp
unit_of_measurement: "°C"
slave: 10
address: 0x3533
input_type: input
scale: 0.01
template:
- sensor:
- name: "Grid Power"
unit_of_measurement: W
device_class: power
state: "{{((states('sensor.grid_current')| float(0) * states('sensor.grid_voltage')| float(0))) | round(2) }}"
- name: "Power into batt"
state: "{{ states('sensor.grid_power') | float + states('sensor.pv_power') | float }}"
unit_of_measurement: W
device_class: power
- name: "House Load"
unit_of_measurement: W
device_class: power
state: "{{((states('sensor.load_current')| float(0) * states('sensor.load_voltage')| float(0))) | round(2) }}"
- trigger:
- platform: mqtt
topic: tele/D1_mini_1/RESULT
sensor:
- name: Temperatura
unit_of_measurement: "°C"
state: "{{ (trigger.payload.split(',')[9] | float-100) }}"
- name: Tensione
unit_of_measurement: "V"
state: "{{ (trigger.payload.split(',')[3] | float/100) }}"
- name: Corrent
unit_of_measurement: "A"
state: "{{ (trigger.payload.split(',')[4] | float/100) }}"
- name: Potenza
unit_of_measurement: "W"
state: "{{ (trigger.payload.split(',')[6] | float/100) }}"
- name: Capacità
unit_of_measurement: "%"
state: "{{ (trigger.payload.split(',')[5] | float/11000*100) }}"
- name: Consumato
unit_of_measurement: "kWh"
state: "{{ (trigger.payload.split(',')[6] | float/10000) }}"
sensor:
- platform: integration
source: sensor.house_load
name: energy_used
unit_prefix: k
round: 2
```
I used the info provided by OP and this thread to link my Juntek 100A shunt to Home assistant.
I appreciate this, it feels good to have this info visible without having to reach for my phone or walk to the display.
I was able to link the state of charge and I’ll paste my code in case others can use it.
My code has all the sections of r50 because I wanted to monitor the values to see the info it carried
This code goes in the configuration.yaml (putting this down as it stumped me when I found the thread as a newb)
One thing I’m stumped on as this is my first HA project, is the value for the AMPS being used is sent as a positive number even when the amps are being drawn.
I found the value that corresponds to the negative and positive switch.
It’s down the string at section [12], it returns a 0 if the amps are negative and it returns a 1 if the amps are positive.
Can anyone suggest a code that will watch the section at [12] and if it is 1 do nothing but if it is 0 it would take the value and subtract the value x 2.
var pos/neg
var amps
if [12] = 1
do nothing
if [12] = 0
pos/neg = amps - (amps + amps)
or a conversion trick to reverse polarity of an sensor value.
I’m new to HA code
template:
- trigger:
- platform: mqtt
topic: tele/D1_mini_1/RESULT
sensor:
- name: SOCX
unit_of_measurement: "%"
state: "{{ (trigger.payload.split(',')[2] | float/11000*100) }}"
- name: Voltage
unit_of_measurement: "V"
state: "{{ (trigger.payload.split(',')[3] | float/100) }}"
- name: Current
unit_of_measurement: "A"
state: "{{ (trigger.payload.split(',')[4] | float/100) }}"
- name: Amp Hours Remaining
unit_of_measurement: "AH"
state: "{{ (trigger.payload.split(',')[5] | float/1000) }}"
- name: Battery Remaining
unique_id: 0000420000-1
unit_of_measurement: "%"
state: "{{ (trigger.payload.split(',')[5] | float/10/400) }}"
- name: Total Power Used
unit_of_measurement: "AH"
state: "{{ (trigger.payload.split(',')[6] | float/1000) }}"
- name: Elec. Consumption
unit_of_measurement: "kW-h"
state: "{{ (trigger.payload.split(',')[7] | float/100000) }}"
- name: Total kW-h
unit_of_measurement: "kW-h"
state: "{{ (trigger.payload.split(',')[8] | float/10000) }}"
- name: Temperature
unit_of_measurement: "°C"
state: "{{ (trigger.payload.split(',')[9] | float-100) }}"
- name: VoltageXX
unit_of_measurement: "V"
state: "{{ (trigger.payload.split(',')[10] | float/100) }}"
- name: CurrentXX
unit_of_measurement: "A"
state: "{{ (trigger.payload.split(',')[11] | float/100) }}"
- name: pos/neg
state: "{{ (trigger.payload.split(',')[12]) }}"
- name: Battery Life AH
unit_of_measurement: "AH"
state: "{{ (trigger.payload.split(',')[13] | float/10) }}"
- name: Internal Resistance
unit_of_measurement: "m-Ohm"
state: "{{ (trigger.payload.split(',')[14] | float/100) }}"
Hi, my Tasmota consolle doesn’t show 11:27:23.727 MQT: tele/BatteryMonitor/RESULT = same as others. Did I miss something?
Hope you did not miss this
Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog SerialSend :R50=1,2,1,; RuleTimer1 10 endon
Rule1 1
Check also the connection between KG140F and your Wemos mini (or whatever you use)
Hi Giro,
can you please suggest a RS485 converter? Or send some detail (chip name and input and ouput connection) and a picture of your?
I buyed a rs485 to TTL but it doesn’t seem to be correct for this job.
Thank you very much.
Lucio
Hi,
I’m a noob in home assistant but i want to contribute with this community.
After reading the documentation about the KG140F DC 0-120V 100A and compare it with the information of this thread I got the following information:
The communication channel give me the following:
My shunt has this values:
r50=2,215,2056,200,5408,4592,9437,14353,134,0,0,0,162,30682
Explanation:
position Description
1 2 represents the communication address;
2 215 represents the checksum;
3 2056 represents the voltage of 20.56V;
4 200 represents current 2.00A;
5 5408 represents the remaining battery capacity is 5.408Ah;
6 4593 means the cumulative capacity is 4.593Ah;
7 9437 represents the watt-hour is 0.09437kw.h;
8 14353 represents the running time of 14353s;
9 134 represents the ambient temperature is 34℃;
10 0 means the function is pending;
11 0 means the output status is ON; (0-ON, 1-OVP, 2-OCP, 3-LVP, 4-NCP, 5-OPP, 6-OTP, 255-OFF)
12 0 represents the direction of current, and the current is forward current; (0-forward, 1-reverse)
13 162 means battery life is 162 minutes;
14 30682 represents the internal resistance of the battery is 306.82mΩ.
Decoding:
HA position split
Address(1,2,3,4,5,6,....) 1
Checksum:153, 2
Voltage(V)(2056->20.56) 3
CurrentAmpere(A)(200->2.0) 4
RemainingAh(Ah)(5408->5.408) 5
ElapsedAH(Ah) 6
AccumulatedChargingCapacity(Kwh) 7
RunningTimeSeconds, 8
Temperature(ºC)(134->34ºc->134-100) 9
pending 10
OutputStatus(alarms) 11
CurrentDirection(0/1) 12
BatteryLifeMinutes 13
ohm(30682->306.82->30682/100) 14
After struggling my head with the sensors, templates and so on, i finished with the following package(yaml file): pck_enrgyconsum_battery_control.yaml
input_number:
number_ampere_preset:
name: Number-Ampere-preset
icon: mdi:battery-high
min: 0
max: 360
initial: 127.5
step: 0.1
mode: box
unit_of_measurement: Ah
template:
- trigger:
- platform: mqtt
topic: tele/tasmota_03-ESP32-Shunt-PowerBank/RESULT
sensor:
- name: KG140F-01-Address
# unit_of_measurement: ""
state: "{{ (trigger.payload.split(',')[1] | float) }}"
- name: KG140F-01-Checksum
# unit_of_measurement: "V"
state: "{{ (trigger.payload.split(',')[2] | float) }}"
- name: KG140F-01-Voltage
unit_of_measurement: "V"
state: "{{ (trigger.payload.split(',')[3] | float/100) }}"
- name: KG140F-01-CurrentAmpere
unit_of_measurement: "Ah"
state: "{{ (trigger.payload.split(',')[4] | float/100) }}"
- name: KG140F-01-RemainingAh
unit_of_measurement: "Ah"
state: "{{ (trigger.payload.split(',')[5] | float/1000) }}"
- name: KG140F-01-ElapsedAH
unit_of_measurement: "Ah"
state: "{{ (trigger.payload.split(',')[6] | float/1000) }}"
- name: KG140F-01-AccumChrgCapacity
unit_of_measurement: "Kwh"
state: "{{ (trigger.payload.split(',')[7] | float/100000) }}"
- name: KG140F-01-RunningTimeSeconds
unit_of_measurement: "s"
state: "{{ (trigger.payload.split(',')[8] | float) }}"
- name: KG140F-01-RunningTimeHours
unit_of_measurement: "h"
state: "{{ (trigger.payload.split(',')[8] | float/60/60) }}"
- name: KG140F-01-Temperature
unit_of_measurement: "ºC"
state: "{{ (trigger.payload.split(',')[9] | float-100) }}"
- name: KG140F-01-Pending
# unit_of_measurement: ""
state: "{{ (trigger.payload.split(',')[10] | float) }}"
- name: KG140F-01-OutputStatus
# unit_of_measurement: ""
state: "{{ (trigger.payload.split(',')[11] | float) }}"
- name: KG140F-01-CurrentDirection
# unit_of_measurement: ""
state: "{{ (trigger.payload.split(',')[12] | float) }}"
- name: KG140F-01-BatteryLifeMinutes
unit_of_measurement: "min"
state: "{{ (trigger.payload.split(',')[13] | float) }}"
- name: KG140F-01-BatteryLifeHours
unit_of_measurement: "h"
state: "{{ (trigger.payload.split(',')[13] | float/60) }}"
- name: KG140F-01-Ohm
unit_of_measurement: "mΩ"
state: "{{ (trigger.payload.split(',')[14] | float/100) }}"
sensor:
# Calculate current power
- platform: template
sensors:
kg140f_01_currentpower:
value_template: >
{% set t = states('sensor.kg140f_01_currentdirection') | float(0) %}
{% if t == 0 %}
{{ '%0.1f' | format ( -1 |float *
(
states('sensor.kg140f_01_voltage') | float *
states('sensor.kg140f_01_currentampere') | float
)
)
}}
{% elif t == 1 %}
{{ '%0.1f' | format
(
states('sensor.kg140f_01_voltage') | float *
states('sensor.kg140f_01_currentampere') | float
)
}}
{% else %}
{{ '%0.1f' | format
(
states('sensor.kg140f_01_voltage') | float *
states('sensor.kg140f_01_currentampere') | float
)
}}
{% endif %}
unit_of_measurement: 'W'
friendly_name: KG140F-01 Current Power
kg140f_01_ampereconsumption:
value_template: >
{% set t = states('sensor.kg140f_01_currentdirection') | float(0) %}
{% if t == 0 %}
{{ '%0.1f' | format ( -1 |float * states('sensor.kg140f_01_currentampere') | float ) }}
{% elif t == 1 %}
{{states('sensor.kg140f_01_currentampere')|float }}
{% else %}
{{states('sensor.kg140f_01_currentampere')|float }}
{% endif %}
unit_of_measurement: 'Ah'
friendly_name: KG140F-01 Ampere Consumption
kg140f_01_battery_level:
value_template: >
{{ '%0.1f' | format
(
(states('sensor.kg140f_01_remainingah') | float * 100 ) /
states('input_number.number_ampere_preset') | float
)
}}
unit_of_measurement: '%'
friendly_name: KG140F-01 Battery Level
The only thing that is not working for me, is the tasmota rule, despite whatever i put in the rule, the transmission to the HA is every second… I bought some D1 mini, just for check if the problem is the ESP32 or not.
Rule1 on System#Boot do RuleTimer1 10 endon on Rules#Timer=1 do backlog SerialSend :R50=1,2,1,; RuleTimer1 10 endon
Rule1 1
So the dashboard is:
When the shunt detect the negative current:
When the shunt detect the positive current(charging):
Thanks a lot to all of you for your knowledge
Luis.
Thank you all for this. Seems perfect for RV use also!
Has anyone figured out how to filter only the “:R50=1,2,1” message?