Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin for Junctek KH140F bluetooth battery monitor #29

Open
chriskomus opened this issue Apr 27, 2023 · 8 comments
Open

Plugin for Junctek KH140F bluetooth battery monitor #29

chriskomus opened this issue Apr 27, 2023 · 8 comments

Comments

@chriskomus
Copy link

chriskomus commented Apr 27, 2023

Hey, first off, thanks for this project!

I'm working on writing a plugin for the Junctek KH140F bluetooth battery shunt and monitor. I've gotten as far as getting characteristic data back, and I can find usable information within the values. However, I have no experience with this, so I'm a bit lost on how to parse the incoming stream of continuous values to get what I'm looking for at the right position.

Below are a bunch of matched values I've found with characteristic data.
Some of them have the byte length in brackets.

As you can see, the data is in there! But the byte length and position of desired information is all over the place. The best option at this point is to pull bytes before the hex values that seem to consistently come afterwards. ie: since C0 comes after volt value, I could get 12.04v from 0XBB1204C00240D883EE ?

volts:

these all seem to start right after the BB, with C0 immediately after the volt value
12.04V - 0XBB1204C00240D883EE (9), 0XBB1204C00481D850EE (9)
12.05V - 0XBB1205C00241D885EE (9),0XBB1205C00241D885EE (9), 0XBB1205C002EE (6)
12.06V - 0XBB1206C020C10241D811EE (11), 0XBB1206C050C10603D801EE (11)
12.07V - 0XBB1207C09163D6022320D746EE (13)
12.32V - 0XBB1232C047EE,0XBB1232C050C10616D864EE
12.30V - 0XBB1230C020C10246D858EE, 0XBB1230C00246D833EE, 0XBB1230C045EE, 0XBB1230C00492D811EE

watts:

position is inconsistent, but D8 always follows the watt value
2.46W - 0XBB1230C020C10246D858EE,0XBB20C10246D800EE, 0XBB20C10246D800EE
1.23W - 0XBB10C10123D848EE
4.92W - 0XBB40C10492D810EE, 0XBB40C16437D6027500D70492D813EE
4.84W - 0XBB1210C00484D865EE, 0XBB1210C00484D865EE, 0XBB1210C00484D865EE
2.41W - 0XBB20C10241D895EE (8), 0XBB1205C00241D885EE (9), 0XBB20C18500D60241D842EE (11)

time remaining (calculated by converting hours to min):

also starts right after BB but D6 follows the time remaining value
63H32M (3812MIN) - 0XBB3812D675EE (6)
70H:48M (4248MIN) - 0XBB4248D6014464D723EE
97H:13M (5833MIN) - 0XBB5833D640EE

amp hours remaining:

value is between D5 and D2
28.325AH - 0XBB243658D5028325D2141314F360EE (15)
28.324AH - 0XBB243667D5028324D2141323F389EE (15)
28.296AH - 0XBB243908D5028296D2141724F315EE (15)
25.819AH - 0XBB265954D5025819D2202450F327EE (15)
25.818AH - 0XBB265963D5025818D2202459F350EE (15)
25.817AH - 0XBB265972D5025817D2202508F384EE (15)

amp (load):

3.5A - BB0350C14487D882EE (9), BB0350C14490D891EE (9)
couldnt find many results, can be calculated from watts / volts, so its not crucial.

SoC:

couldn't find any results, but this can be calculated by amp hours remaining / the total battery aHs (not sure if that value is obtainable via BT or will have to be set in config).

.

If anyone can help, it would be greatly appreciated! The battery monitor is great so far and about 1/3 of the price of other BT enabled shunts, so I'm really hoping to get something working.

@Olen
Copy link
Owner

Olen commented Apr 27, 2023

Hi, and thanks for the effort.
I think you might be on to something, and maybe it makes more sense if you reverse the bytestream to get the parameters, and then reverse the bytes in the values again

That seems to give you the following:

EE - Start of Stream
C0 - Voltage
C1 - Amp
D2 - Amp hours remaining
D5 - ?
D6 - Time remaining
D8 - Watts
F3 - ?
BB - End of Stream

Some of your examples:

0XBB1204C00240D883EE
EE - SoS
83 - ?? (checksum?)
D8 - 0240 Watts
C0 - 1204 Volts
BB - EoS

0XBB1204C00481D850EE
EE - SoS
50 - ?? (checksum?)
D8 - 0481 Watts
C0 - 1204 Volts
BB - EoS

0XBB1230C020C10246D858EE
EE - SoS
58 - ?? (checksum?)
D8 - 0246 Watts
C1 - 20 Amps
C0 - 1230 Volts
BB - EoS

0XBB243658D5028325D2141314F360EE
EE - SoS
60 - ?? (checksum?)
F3 - 141314 Unknown
D2 - 028325 Amp hours remaining
D5 - 243658 Unknown
BB - EoS

In some of the strings, C1 is just one byte and in others it is two:

0XBB1232C050C10616D864EE
EE - SoS
64 - ?? (checksum?)
D8 - 0616 Watt
C1 - 50 (one byte) Amp?
C0 - 1232 Volt
BB - EoS

BB0350C14487D882EE
EE - SoS
82 - ?? (checksum?)
D8 - 4487 Watt
C1 - 0350 (two bytes) Amp?
BB - EoS

Not sure how to interpret those, or how to split the strings if the field has a variable length.
Since it seems like the parameter "names" are hex while all the values are decimal, you could just read the string byte by byte in reverse order and each time you find one of the known parameter identifiers, you read up to the next known identifier. Then you need to choose whether you believe the value is sane or not. E.g is a one byte Amp a sane value, or should you throw those values away until you understand them?
0.5 Amp do make sense in the real world, but do you ever see a C1 with 0000 (or 0050), or is it always just one byte if it is < 100?

@chriskomus
Copy link
Author

Awesome, that helps a lot! I'm going to take a look and see what I can come up. Reversing the order and reading values between parameter identifiers seems like the best option given that values have variable lengths.

You're right in that amps are always one byte if under < 100. I don't see C1 with something like 0050 at all for example. Same goes for all other values.

I looked at all other possible params and couln't find much, so I suspect SoC isn't being transmitted and is instead being calculated.

D3 unknown:
increments sporadically (a few per test):
BB243955D56975D311EE
BB243962D5028290D26976D3141818F322EE
BB267205D5010126D3204541F317EE
BB267213D5010127D3204549F340EE

D5 and F3 unknown:
they increment continally with many per test, often one after the other:
at idle:
BB265894D5202350F364EE
BB265895D5202351F366EE
BB265896D5202352F368EE
BB265897D5202353F370EE

when charging includes D2 (ah remaining) and D4 (unknown) also incremements:
BB275488D5025681D20258D4230344F337EE
BB275489D5025682D20259D4230345F341EE
BB275490D5025683D20261D4230346F358EE
BB275491D5025684D20262D4230347F362EE

The device records date/time, so maybe one of those is a timestamp?

D7:
always 3 bytes, can't figure out what its for
BB0331D6012000D701EE
BB012285D770EE
BB0340C1012058D74362D864EE

BB4498D6026964D743EE
BB3748D6029464D793EE
BB1207C09163D6022320D746EE

I need to test using heavier loads instead of this old test battery with <1 amp loads to see how larger values (for amps and watts) are transmitted.

@chriskomus
Copy link
Author

Got it working! Will do some more testing and make a PR when it's ready.

I added a MonitoringDevice class, which inhereits from BatteryDevice, because I wanted to add minutes remaining, and also when drawing power it displays a negative value (ie: -50watts) to differentiate when supplying power.

image

@sm-green
Copy link

sm-green commented Apr 2, 2024

@chriskomus Have you gotten this to the point of creating a PR? I'm interested in this plugin as well. Thanks!

@Olen
Copy link
Owner

Olen commented Apr 2, 2024

I added a MonitoringDevice class, which inhereits from BatteryDevice, because I wanted to add minutes remaining, and also when drawing power it displays a negative value (ie: -50watts) to differentiate when supplying power.

Isn't power just a function of voltage * current, so a negative current equals a negative power?

And I wonder how mins_remaining is calculated. After monitoring my batteries for a few years, I am still loking for the perfect formula to calculate that based on the soc, capacity and current. Both when charging and when using the batteries, the current fluctuates so much that trying to calculate remaining charge time or usage time gets really hard.
Atm. I use the average of the last 10 current-measurements and use that as a basis, and it gives me numbers that are at least somewhat useful under load.

@chriskomus
Copy link
Author

@sm-green it's been awhile since I've looked at this project but I will be revisiting the plugin soon when I get my camper trailer out of storage. I ended up mostly finishing the plugin, but then ended up using a different solution with grafana/prometheus last summer. I would like to finish this up and create a PR though, as there is quite a bit of development that I've done since last year.

@Olen , for minutes remaining I just used the value that the Junctek device returns. It's really inaccurate though, and fluctuates wildly based on load. Your solution of using the last 10 current-measurements sounds way better! I'll take a look. I will also add a number of new fields/values that have been discovered from the bytestream and make a PR soon when its ready.

@Olen
Copy link
Owner

Olen commented Apr 5, 2024

Yeah. The "Minutes remaining" I have made is made in Home Assistant, not in this code, though.

I think a better approach would be to use for instance the average of the last 10 minutes, not the last 10 datapoints, because sometines I get 10 datapoints in 10 seconds, and sometimes it only report once every 15 minute when I force the data-refresh, so when the sun disappears, or if load is suddenly stopped because the power is turned off it can take hours before the average of 10 measurements reach 0.

@sclawer
Copy link

sclawer commented Jun 3, 2024

I am also interested in the plugin for Junktek..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants