spb012ble (Voltcraft SEM6000 SE) remote control and documentation https://6xq.net/spb012ble
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Lars bfc43a391c 1 month ago
2 months ago
2 months ago
1 month ago
2 months ago
2 months ago
1 month ago
2 months ago

# spb012ble

The spb012ble, better known as Voltcraft SEM6000 SE, is a “smart meter” plug with the following features:

• Remote control via Bluetooth and Android/iOS app
• Energy measurement with hourly (24), daily (30), monthly (12) statistics plus current power, voltage, current and frequency.
• Scheduler with 12 slots
• Timer
• Random mode (anti-burglar)

It looks very similar to the revogi Smart Meter Plug EU and may be a rebranded version.

This repository contains documentation on the hardware and firmware, as well as software to control the “smart meter”.

## Software

To install the software, clone this repository:

git clone https://codeberg.org/ldb/spb012ble.git
virtualenv -p python3 sandbox
source sandbox/bin/activate
pip install .

Controlling the device works like this:

spb012ble-monitor connect:A3:00:00:00:08:16 auth:0000 sync \
switch:on led:on measure

## Hardware

The device is marked as model no. SEM 6000 40th, but sold as Voltcraft SEM6000 SE. On the bottom in the hole for the type E plug a screw can be removed. This allows removing the cover of the female socket on the opposite side.

This reveals a transparent plastic ring, which is slightly glued. It can be removed with a guitar pick or thin plastic piece.

On the bottom of the device there are a few capacitors and resistors, as well as four RGB-LED’s for the light ring.

The top half only carries a crystal osciallator.

The microcontroller PCB (green), which is connected to a flexible PCB (black), connects to the left side of the main PCB (white). The microcontroller board is marked with BK3432 V001. The flexible PCB has the marking SPB012-BLE V0.05 RW, 2021.08.31

The Bluetooth chip is marked as Beken BK3432 EU024JFE, an ARM968E microcontroller with built-in Bluetooth 4.2 or 5.01 transceiver. The antenna is to the left.

The remaining housing seems to be glued together, which prevents further non-destructive analysis. There must be a mechanical relais hidden in the plug, responsible for the noticeable click when turning it on or off. Also, according to the magazine c’t, it uses a RN8209D chip for measurements.

## Firmware

The meter’s firmware is updateable through the smartphone app. It is fetched via the URL https://upgrade.revogi.com/?SN=<sn>, where sn is a hex-encoded string that can be read from the GATT endpoint 0000fff1-​0000-​1000-​8000-​00805f9b34fb and contains an identifier, as well as software and hardware revision. For hardware revision 3 devices are currently shipped with firmware version v1.16. That version is not available for download, but v1.17 is part of the Android app as bk3432_​ble_​app_​app22.bin. v1.18 is available on the update servers, but currently not advertised for updates yet.

typedef struct {
uint32_t crc32;
uint16_t version;
uint16_t length; /* Image length in 4 byte blocks */
uint32_t uid;
uint8_t  unknown1, unknown2;
uint16_t unknown3;
} imageHeader_t;

It looks like it is mapped at address 0x0001b020. Most of the code is run in ARM Thumb mode.

A high-level datasheet for the BK3432 as well as a (semi-public) SDK are floating around the internet. According to that SDK the firmware runs the proprietary RivieraWaves Bluetooth real-time operating system (RTOS). Certain parts of this OS are not upgradeable over-the-air (OTA), including the kernel and the Bluetooth stack itself. Thus the OTA image above only contains the application-specific code of the spb012ble.

The RN8209D is connected to the microcontroller through the UART2 interface at 9600baud while UART1 at 115200baud seems to be used for debugging messages. Every 500ms the firmware polls the following registers in order:

1. PowerPA (Active Power A). The average power over some unknown period of time. It is updated every 290ms. Negative values are simply inverted. If the measured value changes by less than 51mW the old value is used. A value less than 500mW is turned into zero.
2. URms (Voltage RMS).
3. IARms (Current A RMS). Similarly to the power measurements, changes less than 20mA will result in the old value being used. A value less than 20mA is reported as zero.
4. UFreq (Voltage Frequency). Updated only every 640ms.

Power, voltage and current can be calibrated via the command 240 while the UFreq register value is scaled interally by the constant 0x6d3d3, as described by the RN8209D datasheet on page 25.

\begin{aligned} \begin{aligned} P &= \left \lfloor \frac{\textrm{PowerPA} \cdot P_{calib}}{1000} \right \rfloor \\ U &= \left \lfloor \frac{\textrm{URms}}{U_{calib}} \right \rfloor \\ I &= \left \lfloor \frac{\textrm{IARms} \cdot I_{calib}}{1000} \right \rfloor \\ f &= \left \lfloor \frac{\left \lfloor \frac{3579545}{8} \right \rfloor}{\textrm{UFreq}} \right \rfloor \end{aligned} \end{aligned}

### Bugs

Accumulation accuracy

The current power readout is accumulated every five seconds, which is rather slow for quickly-changing loads like PC power supplies. This value is truncated to 1W resolution for hourly energy statistics without proper rounding and propagated from there to daily and monthly statistics.

/* Runs every five seconds */
powerSum += power;
if (minute == 59 && second == 55) {
energy += powerSum / (SECONDS_PER_HOUR / FIVE_SECONDS) / 1000;
update_energy_history_24h();
powerSum = 0;

This can result in significant under-reporting of energy use for devices with low power draw of a few watts.

Input checks

Inputs checks in the firmware are basically nonexistent. For instance the Android app allows setting power limits from 1000W to 4000W, while the firmware happily accepts any value from 0W to 65535W.

globalPowerLimit = (packet[4] << 8) | packet[5];
flash_settings();

The same applies to the device name, which overwrites arbitrary memory if too long:

memset(globalDeviceNameA, 20);
memcpy(globalDeviceNameA, &packet[4], packet[1]-3);
memset(globalDeviceNameB, 20);
memcpy(globalDeviceNameB, &packet[4], packet[1]-3);
globalDeviceNameBLen = 20;
flash_settings();
Scheduler rules soft-brick

Under unknown circumstances the firmware crashes when adding or removing scheduler rules. The device will enter a soft-bricked state and not advertise any GATT services via BLE, making it impossible to control it remotely. Power-cycling only temporarily fixes the issue. Thus a full device reset is required to restore normal operation.

Authentication

The client unlocks the meter using a four-digit PIN code. If that client – for whatever reason – disconnects the meter will advertise itself again over BLE and any other client can access the device without providing the PIN code, since it is already unlocked.

Brute-forcing four digits takes about 30 minutes worst-case at a measured average rate of 5.7tries per second.

But even worse: The PIN can be reset to the default without prior authentication due to how commands are dispatched:

bool checksum_correct = verify_checksum(packet);
if (checksum_correct == false) {
return 0;
}
uint8_t action = packet[2];
if (action == 23) {
handle_authentication(&packet[4]);
} else if (action == 240) {
handle_calibration(&packet[4]);
} else if (action == 48) {
handle_set_mac(&packet[4]);
}
if (is_authenticated != true) {
return 0;
}
if (action == 12) {
Switch behavior

The physical switch on the top of the device is not debounced properly through hard- or software. Pressing it often results in the device switching off and on again or vice versa.

Default device name

While purely cosmetic, the default device name is “Volcraft”, lacking a t.

1. Datasheet and website disagree.