Suntech Protocol - Module Battery Information.

Turbovix a year ago

Hello everyone, does anyone know if the Suntech protocol decoder can decode the module battery value? Below is what the module reports to the platform.

ST300STT;999999999;145;403;20250116;07:37:38;1b7326;-20.336503;-040.285532;000.000;058.41;11;1;71408838;12.68;000010;1;2397;105537;4.1;1

The module battery value is 4.1, that is, the penultimate value.

When trying to retrieve the value of the "battery" attribute using computed attributes, I receive the following error:

org.traccar.handler.ComputedAttributesHandler.computeAttribute:137@1:1 variable 'battery' is undefined - Variable (ComputedAttributesHandler:138 < AttributeResource:63 < ... < OverrideFilter:49 < ...)

However, using "power" I receive the vehicle's battery value correctly.

Turbovix a year ago

Looking at the protocol code, shouldn't the battery value be interpreted directly in the "case "STT" on line 406, instead of in the " if (getHbm(deviceSession.getDeviceId()) == 1)" ?

Turbovix a year ago

I made the following change and now the module battery value is displayed.

switch (type) {
    case "STT" -> {
        position.set(Position.KEY_STATUS, Integer.parseInt(values[index++]));
        
        position.set(Position.KEY_INDEX, Integer.parseInt(values[index++]));

        // Skip the next intermediate value        
        index++; 

        // KEY_BATTERY
        if (index < values.length) {
            position.set(Position.KEY_BATTERY, Double.parseDouble(values[index++]));
        }    
    }
    case "EMG" -> position.addAlarm(decodeEmergency(Integer.parseInt(values[index++])));
    case "EVT" -> position.set(Position.KEY_EVENT, Integer.parseInt(values[index++]));
    case "ALT" -> position.addAlarm(decodeAlert(Integer.parseInt(values[index++])));
    case "UEX" -> index = decodeSerialData(position, values, index);
}
Anton Tananaev a year ago

I believe other types also support it and it should be only included with HBM = 1, so the original code looks correct and what you have is incorrect. But maybe you have some other protocol documentation that you didn't share.

Turbovix a year ago

Anton, there are 7 decoding methods in SuntechProtocolDecoder.java, which determines that the information received from a specific module is decoded by method A or B...? In my case, I have modules ST340, ST340UR, ST340RB, ST310UC2.

Antonio Junior a year ago

Based on the documentation and table provided by suntech, I implemented it like this, the internal battery they call batteryBackup.

if (protocol.startsWith("ST3") || protocol.equals("ST500") || protocol.equals("ST600")) {
            index += 1; // model
            // implementado por Junior Melo 11/06/2024
            String batteryBackup; // battery internal in volt


            if (type.equals("ALT") || type.equals("EMG") && values.length == 20) {


                batteryBackup = values[18];

                double voltage = Double.parseDouble(batteryBackup);

                double batteryPercentage = 0;

                if (voltage >= 4.06) {
                    batteryPercentage = 100;
                } else if (voltage >= 3.97) {
                    batteryPercentage = 90;
                } else if (voltage >= 3.89) {
                    batteryPercentage = 80;
                } else if (voltage >= 3.83) {
                    batteryPercentage = 70;
                } else if (voltage >= 3.77) {
                    batteryPercentage = 60;
                } else if (voltage >= 3.75) {
                    batteryPercentage = 50;
                } else if (voltage >= 3.73) {
                    batteryPercentage = 40;
                } else if (voltage >= 3.66) {
                    batteryPercentage = 30;
                } else if (voltage >= 3.53) {
                    batteryPercentage = 20;
                } else if (voltage >= 3.49) {
                    batteryPercentage = 10;
                } else {
                    batteryPercentage = 0;
                }

                position.set(Position.KEY_BATTERY_LEVEL, batteryPercentage);
            }

            if (type.equals("STT") && values.length == 21) {
                batteryBackup = values[19];

                double voltage = Double.parseDouble(batteryBackup);

                double batteryPercentage = 0;

                if (voltage >= 4.06) {
                    batteryPercentage = 100;
                } else if (voltage >= 3.97) {
                    batteryPercentage = 90;
                } else if (voltage >= 3.89) {
                    batteryPercentage = 80;
                } else if (voltage >= 3.83) {
                    batteryPercentage = 70;
                } else if (voltage >= 3.77) {
                    batteryPercentage = 60;
                } else if (voltage >= 3.75) {
                    batteryPercentage = 50;
                } else if (voltage >= 3.73) {
                    batteryPercentage = 40;
                } else if (voltage >= 3.66) {
                    batteryPercentage = 30;
                } else if (voltage >= 3.53) {
                    batteryPercentage = 20;
                } else if (voltage >= 3.49) {
                    batteryPercentage = 10;
                } else {
                    batteryPercentage = 0;
                }

                position.set(Position.KEY_BATTERY_LEVEL, batteryPercentage);
            }


        }

Image Icon BatteryLevel

Turbovix a year ago

@AntonioJunior, I think this approach is perfect. I will try it. Thanks for sharing.

Antonio Junior a year ago

@Turbovix, and a pleasure to help!