baumi's blog

baumi's personal blog … Linux, OS X, Windows, Random things, …

KOSTAL PIKO 12-20 + KSEM G2 modbus API access + WebSocket access etc.

KOSTAL KSEM G2 (modbus TCP) grid power total:
1) In device configuration, enable ModBus TCP slave
2) Install mbpoll
3) Reading smart meter using command line:

mbpoll -0 -t 3:int -r 0,2 -c 2 192.168.1.12 -1 -B -q

Simple BASH parsing example:

mbpoll -0 -t 3:int -r 0,2 -c 2 192.168.1.12 -1 -B -q > /tmp/mbpoll.txt
consumption=$(grep "\[0\].*" -m 1 /tmp/mbpoll.txt | cut -d ':' -f 2 | tr -d '\t ' | cut -d '(' -f 1 )
feedback=$(grep "\[2\].*" -m 1 /tmp/mbpoll.txt | cut -d ':' -f 2 | tr -d '\t ' | cut -d '(' -f 1 )
grid=$(( (consumption - feedback)/10 ))
echo "$grid W"

Alternative:

grid=$(mbpoll -0 -r 40087 192.168.1.12 -1 -B -q -t 3:int16 | grep "40087" | tr -d '\t ' | cut -d ':' -f 2)
grid=$((grid*10))
echo "$grid W"

Register 40087 is signed int in 10 Watt steps, e.g.
-10 = -100 Watt feedback to grid,
+32 = 320 Watt consumption from grid,
thus we need to multiply by 10 before showing the result.

ModBus registers documentation:
https://www.kostal-solar-electric.com/en-gb/products/accessories/smart-energy-meter/-/media/document-library-folder—kse/2020/12/15/14/22/ba_kostal_interface_ksem_de.pdf

KOSTAL PIKO solar output (bash/wget):
1) Using bash you can easily read the current SOLAR output in WATT:

#!/bin/bash
pvwatt=$(wget -qO - "http://192.168.1.11/api/dxs.json?dxsEntries=67109120" | cut -d ','
-f 2 | cut -d ':' -f 2 | cut -d '}' -f 1 | cut -d '.' -f 1)
echo "$pvwatt W"

Reference for “dxsEntries” values:
https://www.msxfaq.de/sonst/iot/kostal15.htm

Problem: while KSEM G2 works reliable, KOSTAL PIKO inverters webserver keep crashing every couple of weeks/days. The inverter keeps communicating with KSEM G2 and transmits its data.

Solution 1: Reading inverter data via ModBus, however:
mbpoll -0 -t 3:int -r 0,2 -c 2 192.168.1.11 -1 -B -q

would always return:

mbpoll: Connection failed: Operation now in progress.

At least, for me, tested when KOSTAL inverter webserver was stuck. Also tested while rebooting KSEM G2 (which is required so PARAKO Software can connect), same result.

Solution 2: KSEM G2 doesn’t expose/mirror the inverter data via ModBus registers, however we can access them using websockets to connect to KSEM G2. The websockets are usually used by KSEM G2 web interface to display both smart meter data but also inverter data such as “pvPowerTotal” as well as “housePowerTotal” which might be handy.

KSEM G2 Websocket access:
wscat -c ws://192.168.1.12/api/data-transfer/ws/protobuf/gdr/local/values/kostal-energyflow/sumvalues -x 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhZG1pbiIsImV4cCI6MTY3MjgyMzA1OCwiaXNzIjoiVFFTIiwibm9uYyI6MTI5ODQ5ODA4MSwicm9sZSI6ImFkbWluLHVzZXIiLCJzdWIiOiJFTU9TIn0.m97uLGsNTAZ4Otw9p63Xehm2CmWhrCHNAMf2FT9GrnXaYZ3Ua3HKVY5yDonrRp31ZGlaJt16YBWk2Mc42oDJ5DaeourSclnRIAAYnOp1m9l853Fm3_b6C1EUjPLJGVx9zqfbTBDcFXLwDJvrFiJzxVBRadbwI9SPfWfQIU7bQT8YpK8uFBGdRF1jcTjTLWKWG_7ISZXg-6spoRhRp2yq1oE1_6tE7Y8E1Qxcvhp03ZFlWTfGnzLy4Ny344H4aUkmCwhb1fw3C3n0ZCcKxKlbVdT2O7pqyfT439D3Fd5k7BOC-bw7GE3s0_9lDtgmOeqr5J17RHkN-iZhhmB8yW31Rg' -w 0 | xxd -p -r | protoc --decode_raw

Attention: /usr/bin/wscat needs to be patched in order to properly work with binary data. Add this function in before the class:

function buf2hex(buffer) { // buffer is an ArrayBuffer
return [...new Uint8Array(buffer)]
.map(x => x.toString(16).padStart(2, '0'))
.join('');
}

and before every “ws.send(programOptions.execute);” add this:

ws.binaryType = "arraybuffer";

and patch the “wsConsole.print” to output the hex encoded binary response:

wsConsole.print(Console.Types.Incoming, buf2hex(data), Console.Colors.Blue);

You can paste/decode the hex response here:
https://protobuf-decoder.netlify.app/

Preview:
1 {
1: "energyflow-totals"
2 {
1: "energyflow-totals"
2: 1
3 {
1: 1672579250
2: 916908563
}
5 {
1: "gridPowerTotal"
2 {
1: 18446744073709503616
}
}
5 {
1: "pvPowerTotal"
2 {
1: 18446744073706446856
}
}
5 {
1: "auxillaryPowerTotal"
2: ""
}
5 {
1: "housePowerTotal"
2 {
1: 3056760
}
}
}
}
2: "\340F\245=8.h\362H\t\010\2423\224\2156"

For uint/int conversion, see: https://blog.b-nm.at/2023/01/01/bash-cast-unsinged-int-into-signed-integer/

Comments are currently closed.