fix(scale): 修复 RS485 多联秤地址 ≥ 10 时清零命令发送到错误设备的问题

- 新增 FixedSensorScale 继承 SensorScale,通过反射重写 zeroTwo/tareTwo
- 修复根因:SDK 将 int 地址直接拼接为十进制字符串再按十六进制解析,
  导致地址 10 发送字节 0x10(=16号秤)而非 0x0A(=10号秤)
- 修复方式:String.format("%02X", address) 确保正确的十六进制编码
- Weigher2 替换 mSensorScale 字段类型为 FixedSensorScale
- WeightUtil.tareTwo 移除 isTaring 防重复逻辑,简化为直接调用 zeroTwo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 14:58:27 +08:00
co-authored by Claude Sonnet 4.6
parent 99d670390a
commit 72ecc8fcd6
3 changed files with 110 additions and 15 deletions
@@ -0,0 +1,91 @@
package com.shuwei.dish.match.utils;
import android.util.Log;
import com.wabon.wbintelligenthardwaresdk.api.SensorScale;
import java.lang.reflect.Method;
/**
* 修复 SensorScale 地址编码 bug 的子类。
*
* 问题根因:SensorScale.zeroTwo / tareTwo 内部使用
* String command = address + "630603";
* 将 int 地址直接拼接为十进制字符串,再整体按十六进制解析成字节。
* 对于地址 1-9,十进制 == 十六进制,偶然正确;
* 对于地址 10+,十进制 "10" 被解析为 0x10=16),命中错误的物理秤。
*
* 修复方式:重写这两个方法,将地址先格式化为两位十六进制字符串(如 10 → "0A"),
* 再拼接命令码,通过反射调用父类私有方法 suspendSendThread 和 sumHex 发送。
*/
public class FixedSensorScale extends SensorScale {
private static final String TAG = "FixedSensorScale";
public FixedSensorScale(OnScaleResult result) {
super(result);
}
/**
* 重写清零命令,修复地址编码:十进制地址 → 两位十六进制字符串。
* 例:address=10 → "0A630603",发送字节 0x0A(正确),而非原来的 0x10(错误)。
*
* @param listener 操作成功回调
* @param address 秤地址(来自 onGetWeight 回调的十进制值)
*/
@Override
public void zeroTwo(OperateSuccessListener listener, int address) {
sendFixedCommand(listener, address, "630603", "zeroTwo");
}
/**
* 重写去皮命令,修复地址编码,逻辑同 zeroTwo。
*
* @param listener 操作成功回调
* @param address 秤地址
*/
@Override
public void tareTwo(OperateSuccessListener listener, int address) {
sendFixedCommand(listener, address, "630601", "tareTwo");
}
/**
* 通用发送逻辑:将地址格式化为两位十六进制后拼接命令码,
* 通过反射调用父类私有方法 sumHex 计算校验和,再调用 suspendSendThread 发送。
*
* @param listener 操作成功回调
* @param address 秤地址(十进制)
* @param commandCode 命令码(十六进制字符串,如 "630603"
* @param methodName 调用方名称,仅用于日志
*/
private void sendFixedCommand(OperateSuccessListener listener, int address,
String commandCode, String methodName) {
try {
// 将十进制地址转为两位十六进制字符串:10 → "0A"1 → "01"
String hexAddress = String.format("%02X", address);
String command = hexAddress + commandCode;
Log.d(TAG, methodName + ", address=" + address
+ ", hexAddress=" + hexAddress + ", command=" + command);
// 反射调用 sumHex(String) 计算校验和
Method sumHexMethod = SensorScale.class.getDeclaredMethod("sumHex", String.class);
sumHexMethod.setAccessible(true);
String checksum = (String) sumHexMethod.invoke(this, command);
// 反射调用 suspendSendThread(String) 发送完整命令帧
Method suspendMethod = SensorScale.class.getDeclaredMethod(
"suspendSendThread", String.class);
suspendMethod.setAccessible(true);
suspendMethod.invoke(this, command + checksum);
// 保存回调(通过反射写入父类私有字段 mOperateSuccessListener
java.lang.reflect.Field listenerField = SensorScale.class
.getDeclaredField("mOperateSuccessListener");
listenerField.setAccessible(true);
listenerField.set(this, listener);
} catch (Exception e) {
Log.e(TAG, methodName + " 反射调用失败: address=" + address, e);
}
}
}
@@ -23,7 +23,7 @@ public class Weigher2 {
public static final int ERR_003 = 1003; public static final int ERR_003 = 1003;
public static final int ERR_004 = 1004; public static final int ERR_004 = 1004;
public static final int ERR_PCB_NOT_SUPPORT = 2000; public static final int ERR_PCB_NOT_SUPPORT = 2000;
private static SensorScale mSensorScale; private static FixedSensorScale mSensorScale;
// private static String mDevicePort = "/dev/ttyS4"; // private static String mDevicePort = "/dev/ttyS4";
private static String mDevicePort = "/dev/ttyS7"; private static String mDevicePort = "/dev/ttyS7";
private static boolean mConnect = false; private static boolean mConnect = false;
@@ -402,7 +402,8 @@ public class Weigher2 {
} }
}; };
//.<init>(); //.<init>();
mSensorScale = new SensorScale(var0); // 使用修复版子类,解决地址 ≥ 10 时 zeroTwo/tareTwo 编码错误的问题
mSensorScale = new FixedSensorScale(var0);
} }
public static void setNoPull485Pin(boolean noPull) { public static void setNoPull485Pin(boolean noPull) {
@@ -1,8 +1,6 @@
package com.shuwei.dish.match.utils package com.shuwei.dish.match.utils
import android.os.Build import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log import android.util.Log
import com.shuwei.dish.match.utils.ext.roundedOneDecimalPlace import com.shuwei.dish.match.utils.ext.roundedOneDecimalPlace
//import com.aithings.Weigher //import com.aithings.Weigher
@@ -21,6 +19,7 @@ object WeightUtil {
val weightFuncMap: ConcurrentHashMap<String, WeightCallback?> = ConcurrentHashMap() val weightFuncMap: ConcurrentHashMap<String, WeightCallback?> = ConcurrentHashMap()
fun init() { fun init() {
SensorScale.isLog = true
Weigher2.init() Weigher2.init()
Weigher2.setListener(object : WeightListenerImpl() { Weigher2.setListener(object : WeightListenerImpl() {
override fun onInit(connect: Boolean) { override fun onInit(connect: Boolean) {
@@ -28,6 +27,16 @@ object WeightUtil {
isConnected = connect isConnected = connect
} }
override fun onTare() {
super.onTare()
Log.d(TAG, "tareTwo,onTare 回调触发")
}
override fun onZero() {
super.onZero()
Log.d(TAG, "tareTwo,onZero 回调触发")
}
override fun onGetWeight(address: Int, state: Int, weight: Double) { override fun onGetWeight(address: Int, state: Int, weight: Double) {
super.onGetWeight(address, state, weight) super.onGetWeight(address, state, weight)
val stateStr = when (state) { val stateStr = when (state) {
@@ -69,18 +78,12 @@ object WeightUtil {
fun tareTwo(address: Int) { fun tareTwo(address: Int) {
try { try {
Log.d(TAG, "执行清零操作: address=$address") Log.d(TAG, "tareTwo,执行清零操作: address=$address")
Weigher2.tareTwo(address) // SDK 内部自动管理总线,直接发送清零命令
// Weigher2.zeroTwo(address) Weigher2.zeroTwo(address)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
Log.e(TAG, "执行清零异常: address=$address, error=${e.message}", ) Log.e(TAG, "tareTwo,执行清零异常: address=$address, error=${e.message}")
}
}
private fun runOnUiThread(action: () -> Unit) {
Handler(Looper.getMainLooper()).post {
action()
} }
} }
@@ -102,7 +105,7 @@ open class WeightListenerImpl : Weigher2.Listener {
} }
override fun onZero() { override fun onZero() {
Log.d("WeightUtil", "zero ok") Log.d("WeightUtil", "tareTwo,zero ok")
} }
override fun onTare() { override fun onTare() {