KHF-Net

Battery Monitor Device Connectivity and Remote Configuration Tool.

Views1
PublishedJan 14, 2026

Loading actions...

5 minBeginnerpromptSingle file

Skill content

Main instructions and any bundled files for this skill.

markdown

KHF-Net

Battery Monitor Device Connectivity and Remote Configuration Tool.

Description

KHF-Net is a program designed to connect Junctek's KH-F series battery monitor devices to an MQTT broker using an RS485 bus interface. Its primary function is to facilitate seamless communication to these devices. KHF-Net is specifically designed to operate on the Linux platform. I might be portable to other operating systems by introducing additional work.

In addition to connecting devices, KHF-Net includes a telnet access feature to offer remote configuration capabilities for KH-F series devices. This functionality allows users to adjust settings remotely for convenient management. Furthermore this telnet interface serves for debugging purposes.

The program serves as a utility to bridge communication between the battery monitor devices and an MQTT broker while providing remote configuration and debugging functionalities.

It also supports networked serial ports, enabling remote connection to KH-F series battery monitor devices over a network. This feature expands connectivity options beyond physical serial ports.

License

This project is licensed under the European Union Public License 1.2 (EUPL-1.2). For the full license text see the LICENSE file.

Table of Contents

  1. Description
  2. License
  3. Installation
  4. usage
  5. MQTT topics

Installation

Prerequisites

  • Git
  • CMake (version X.X or higher)
  • gcc (version y.y or higher, needs C++20)

Clone the repository

git clone <repository_url>

Build scripts

To build the project:

./build.sh

To clean the build artefacts in the build dir:

./clean.sh

To clean the build directory pristine:

./distclean.sh

Manual build steps

If you prefer to do the build steps manually, here it is (out-of-source build):

mkdir -p build && cd build
cmake -G "Unix Makefiles" ..
make
make install

Optional: Clean build artifacts (if needed):

make clean

Usage

A lot of aspects of the MQTT connection are configurable. See the command help output for details.

The serial port connection is also configurable. The most important option is the --tty-path, which configures the path to the serial port device, where the RS485 bus is connected. The baud rate setting is just for testing purposes, the KH-F series has no configurable baud rate, so go with the default value of 115200.

The program does no special RS485 handling on the serial port hardware. It is assumed, that all the bus direction handling is done in hardware or in the device driver. If some special settings are on the wish list, it should be easy to implement them.

The program is successfully tested with some FTDI-232 based RS485-to- USB adapters and with some CH340C RS485-to-USB adapters sold by Reichelt Eletronik

If someone has a serial port server, which is capable of raw 8-bit-mode (no telnet mode and no RFC-2217 mode), then the hostname and the TCP port number can be given, to access this serial port server.

Examples for using a serial port server might be the famous ser2net in simple raw port mode, setting the baud rate and port control options locally.

An other example is using socat as a port server, i.e.:

socat /dev/ttyS1,b115200,raw,echo=0 tcp-listen:2020,reuseaddr

The khf-net program provides a detailed help message when the --help command-line switch is used. To access the help output, run the following command:

$ ./build/bin/khf-net --help
KH-F series battery monitor network connector
Valid options are:

RS485 bus configuration:
-d, --tty-path=PATH        PATH to serial port device for RS485 bus (default: /dev/ttyUSB0)
   --baudrate=BAUD        baudrate for the serial port, i.e. 115200 (default: 115200)
   --tty-net-host=HOSTNAME   network HOSTNAME or IP, which provides serial port device, enables networked serial port mode
   --tty-net-port=PORT    use TCP port number PORT for TTY access (raw mode only) (default: 2020)
-i, --batt-poll-interval=ms   battery poll interval (default: 1000)
-t, --batt-comm-timeout=ms   battery request timeout (default: 100)

MQTT configuration:
-h, --mqtt-broker=HOSTNAME   HOSTNAME or IP of MQTT broker (default: localhost)
-p, --mqtt-port=PORT       PORT number at MQTT broker (default: 1883)
   --mqtt-client-id=CLIENT-ID   CLIENT-ID at MQTT broker
   --mqtt-user=USER-NAME   USER-NAME at MQTT broker
   --mqtt-pass=PASSWORD   PASSWORD at MQTT broker
   --mqtt-clean-session   open a clean session at the broker (default)
   --mqtt-continue-session   continue a session at the broker (opposite of clean session)
   --device-topic=TOPIC   MQTT device topic (default: khf-net)
   --cmd-prefix=PREFIX    MQTT topic PREFIX for command subscriptions (default: cmd)
   --log-prefix=PREFIX    MQTT topic PREFIX for log messages (default: log)
   --feedback-prefix=PREFIX   MQTT topic PREFIX for command feedback messages and settings publication (default: feedback)
   --actuator-prefix=PREFIX   MQTT topic PREFIX for actuator command subscriptions (default: actuator)
   --sensor-prefix=PREFIX   MQTT topic PREFIX for sensor value publication (default: sensor)
   --online-prefix=PREFIX   MQTT topic PREFIX for online message (default: connected)
   --online-suffix=SUFFIX   MQTT topic SUFFIX for online message (default: LWT)
   --online-msg=MESSAGE   MQTT online MESSAGE to publish on broker connection (default: online)
   --online-retain        retain MQTT online message
   --lwt-prefix=PREFIX    MQTT topic PREFIX for LWT message (default: connected)
   --lwt-suffix=SUFFIX    MQTT topic SUFFIX for LWT message (default: LWT)
   --lwt-msg=MESSAGE      MQTT offline MESSAGE to set as LWT message (default: offline)
   --lwt-retain           retain MQTT offline message
   --sensor-refresh=min   interval time in minutes for full sensor value array publication (0 = off) (default: 60)
   --disable-khf-devinfo-log   disable KHF device information logging to MQTT
   --disable-khf-misc-log   disable KHF miscelleneous logging to MQTT
   --disable-khf-settings-feedback   disable KHF settings feedback to MQTT
   --disable-khf-configuration   disable all KHF configuration commands from MQTT
   --disable-khf-relay-control   disable KHF relays as actuators from MQTT

Set MQTT online or offline suffix to empty string (''), to disable the message.

Network shell configuration:
   --tap-net-port[=PORT]   enable telnet TAP service (test access port) on PORT (default: 4223)

Other configuration:
   --debug[=INT]          enable debug output (default: 0)
-h, --help                 display this help list and exit
-V, --version              print program version and exit

debug flags:
 0x00001 MQTT message log
 0x00002 tty ctrl log
 0x00004 KHF bus debug
 0x00008 UART data

.
.
.

(The output was shortened; the program also tells all the MQTT topics, it publishes and subscribes, which would be lengthy here. See section MQTT topics for more details on that.)

MQTT topics

Please refer to the device manual, what all the detailed MQTT topics might be on, a lot of them is self-explanatory. So this is a list of the published and subscribed topics:

MQTT topic structure with default prefixes and device topic from command line configuration
(@@ is placeholder for the device bus address without leading zero, i.e. '2' or '33'):
    connected/khf-net/LWT                                        publishing the online state and LWT of khf-net
    actuator/khf-net/@@/relay                                    subscription for relay control
    cmd/khf-net/poll_interval_ms                                 subscription for poll_interval_ms command
    cmd/khf-net/comm_timeout_ms                                  subscription for comm_timeout_ms command
    cmd/khf-net/scan_bus                                         subscription for scan_bus command (no payload)
    cmd/khf-net/populate_address                                 subscription for populate_address command
    cmd/khf-net/@@/reload_device_info                            subscription, command reloads device information
    cmd/khf-net/@@/refresh_all_measurements                      subscription, command sends all measurements (no payload)
    cmd/khf-net/@@/refresh_all_misc                              subscription, command sends all misc values (no payload)
    cmd/khf-net/@@/reload_settings                               subscription, command reloads all settings
    cmd/khf-net/@@/bus_address                                   subscription for device control
    cmd/khf-net/@@/over_voltage_protection_mV                    subscription for device control
    cmd/khf-net/@@/under_voltage_protection_mV                   subscription for device control
    cmd/khf-net/@@/discharge_over_current_protection_mA          subscription for device control
    cmd/khf-net/@@/charge_over_current_protection_mA             subscription for device control
    cmd/khf-net/@@/over_power_protection_mW                      subscription for device control
    cmd/khf-net/@@/high_temperature_protection_degC              subscription for device control
    cmd/khf-net/@@/low_temperature_protection_degC               subscription for device control
    cmd/khf-net/@@/protection_delay_time_s                       subscription for device control
    cmd/khf-net/@@/protection_recovery_time_s                    subscription for device control
    cmd/khf-net/@@/battery_total_capacity_mAh                    subscription for device control
    cmd/khf-net/@@/voltage_calibration_factor_percent            subscription for device control
    cmd/khf-net/@@/current_calibration_factor_percent            subscription for device control
    cmd/khf-net/@@/temperature_calibration_offset_K              subscription for device control
    cmd/khf-net/@@/clock_speed_calibration_factor_percent        subscription for device control
    cmd/khf-net/@@/relay_normally_closed_mode                    subscription for device control
    cmd/khf-net/@@/empty_detection_voltage_mV                    subscription for device control
    cmd/khf-net/@@/full_charge_detection_voltage_mV              subscription for device control
    cmd/khf-net/@@/full_charge_tail_current_percent_C            subscription for device control
    cmd/khf-net/@@/full_charge_detection_time_s                  subscription for device control
    cmd/khf-net/@@/temperature_unit_is_farenheit                 subscription for device control
    cmd/khf-net/@@/ble_password                                  subscription for device control
    cmd/khf-net/@@/data_logging_interval_s                       subscription for device control
    cmd/khf-net/@@/low_capacity_alarm_percent                    subscription for device control
    cmd/khf-net/@@/data_logging_enabled                          subscription for device control
    cmd/khf-net/@@/set_device_time                               subscription for device control
    cmd/khf-net/@@/manual_relay_setting                          subscription for device control
    cmd/khf-net/@@/trigger_current_zero_calibration              subscription for device control
    cmd/khf-net/@@/trigger_factory_reset                         subscription for device control
    cmd/khf-net/@@/set_remaining_capacity_percent                subscription for device control
    feedback/khf-net/poll_interval_ms                            publishing command feedback
    feedback/khf-net/comm_timeout_ms                             publishing command feedback
    feedback/khf-net/@@/relay                                    publishing relay control feedback
    feedback/khf-net/@@/bus_address                              publishing device command feedback
    feedback/khf-net/@@/over_voltage_protection_mV               publishing device command feedback
    feedback/khf-net/@@/under_voltage_protection_mV              publishing device command feedback
    feedback/khf-net/@@/discharge_over_current_protection_mA     publishing device command feedback
    feedback/khf-net/@@/charge_over_current_protection_mA        publishing device command feedback
    feedback/khf-net/@@/over_power_protection_mW                 publishing device command feedback
    feedback/khf-net/@@/high_temperature_protection_degC         publishing device command feedback
    feedback/khf-net/@@/low_temperature_protection_degC          publishing device command feedback
    feedback/khf-net/@@/protection_delay_time_s                  publishing device command feedback
    feedback/khf-net/@@/protection_recovery_time_s               publishing device command feedback
    feedback/khf-net/@@/battery_total_capacity_mAh               publishing device command feedback
    feedback/khf-net/@@/voltage_calibration_factor_percent       publishing device command feedback
    feedback/khf-net/@@/current_calibration_factor_percent       publishing device command feedback
    feedback/khf-net/@@/temperature_calibration_offset_K         publishing device command feedback
    feedback/khf-net/@@/clock_speed_calibration_factor_percent   publishing device command feedback
    feedback/khf-net/@@/relay_normally_closed_mode               publishing device command feedback
    feedback/khf-net/@@/empty_detection_voltage_mV               publishing device command feedback
    feedback/khf-net/@@/full_charge_detection_voltage_mV         publishing device command feedback
    feedback/khf-net/@@/full_charge_tail_current_percent_C       publishing device command feedback
    feedback/khf-net/@@/full_charge_detection_time_s             publishing device command feedback
    feedback/khf-net/@@/temperature_unit_is_farenheit            publishing device command feedback
    feedback/khf-net/@@/ble_password                             publishing device command feedback
    feedback/khf-net/@@/data_logging_interval_s                  publishing device command feedback
    feedback/khf-net/@@/low_capacity_alarm_percent               publishing device command feedback
    feedback/khf-net/@@/data_logging_enabled                     publishing device command feedback
    log/khf-net/@@/error                                         publishing device errors
    log/khf-net/@@/device_found                                  publishing device related log output
    log/khf-net/@@/device_type                                   publishing device related log output
    log/khf-net/@@/fw_version                                    publishing device related log output
    log/khf-net/@@/serial_number                                 publishing device related log output
    log/khf-net/@@/log_entries_count                             publishing device related log output
    log/khf-net/@@/protection_relay_state                        publishing device related log output
    log/khf-net/@@/remaining_charge_discharge_time_min           publishing device related log output
    log/khf-net/@@/clock_speed_adjustment_percent                publishing device related log output
    log/khf-net/@@/device_time                                   publishing device related log output
    sensor/khf-net/@@/battery_voltage_mV                         publishing measurement value
    sensor/khf-net/@@/battery_current_mA                         publishing measurement value
    sensor/khf-net/@@/battery_power_mW                           publishing measurement value
    sensor/khf-net/@@/battery_capacity_mAh                       publishing measurement value
    sensor/khf-net/@@/battery_capacity_mWh                       publishing measurement value
    sensor/khf-net/@@/battery_capacity_percent                   publishing measurement value
    sensor/khf-net/@@/discharged_energy_mWh                      publishing measurement value
    sensor/khf-net/@@/charged_energy_mWh                         publishing measurement value
    sensor/khf-net/@@/sensor_temperature_degC                    publishing measurement value

scan_bus command

Sending this topic (no payload necessary, it is ignored anyway), the khf-net program deletes the internal device data base and scans the bus again for all devices, that might answer. All found devices are populated and subsequently polled.

populate_address command

Sending this topic with a valid bus address as payload in ASCII text, i.e. 1 or 42, populates this device address in the device database of the program and polls the device for its presence and values. Thus the populated device might get marked unavailable (i.e. timeout), if it does not respond timely.

Examples

tbd.

Troubleshooting

Bus contention

If you use your KH-F device together with the original display module, then there might be problems arising from two hosts acessing the module bus. The khf-net program tries to synch up with the other polling host (i.e. the display module), but this is not easy and to some degree error prone.

One solution to this bus contention problem is, to disable the display host mode in the display settings, then khf-net is the only polling host. The display still sniffes the bus and displays the sniffed data, but some settings do not work from the display module any more.

One other possible solution could be, to implement a pure sniffing mode in khf-net, but currently this is not available yet.

Accidental relay toggle from the display

The OK button on the display is for toggeling the relay state on a short press. This is available, when the display is lit, else not.

If someone hits the OK button accidentally, while the display is lit, the relay toggles and could, i.e. trigger a overcurrent cutoff.

This can be avoided, to my own experiments, when the display host mode is disabled. In this configuration state, the OK button seems not any more doing this function.

KH-F firmware problems

current calibration error

Some KH-F device firmware versions do not respect the current calibration factor, namely the KH-F firmware version 132. This issue is solved in the firmware version 137.

eternal capacity error

The combination of KH-F firmware version 134 and Android Bluetooth-App V1.4.1 destroys the remaining capacity value, when the Bluetooth connection is established.

This is no fault of the khf-net program but of the firmware. Go back to firmware version 132 or forward to firmware version 137.

Contributing

Contributions are welcome, submit issues or do pull-requests. My time is very limited, I'll try my best to catch up with your contributions.

Acknowledgments

The project uses the MQTT-C library as an external dependency and all the MQTT lifting is done using this library.

Thanks to the authors of this library, making MQTT access this easy.

Contact

Ask on the project hosting site for support in the issues section.

Share: