| | |
| | | return (byte) (sum & 0xFF); |
| | | } |
| | | |
| | | |
| | | public static byte[] getRequestParam(int feCount, byte[] address, byte control, byte[] data) throws IOException { |
| | | |
| | | ///FEFEFE 68 999999999999 68 01 02 65 F3C1 16 |
| | |
| | | return hexResult; |
| | | |
| | | } |
| | | private static String addByte(String value, byte add) { |
| | | byte b = (byte) Integer.parseInt(value, 16); |
| | | int result = (b & 0xFF) + (add & 0xFF); |
| | | // 确保结果在0-255范围内(处理负数) |
| | | if (result < 0) { |
| | | result += 256; |
| | | } |
| | | String hexResult = String.format("%02X", result & 0xFF); |
| | | return hexResult; |
| | | |
| | | } |
| | | |
| | | |
| | | private static String[] parseSub33Reverse(String msg, int n) { |
| | |
| | | map.put("total", total); |
| | | } |
| | | |
| | | /** |
| | | * 电表跳闸、合闸 |
| | | * @param ip |
| | | * @param port |
| | | * @param addressBuf |
| | | * @param type (0跳闸 1合闸) |
| | | * @param date 有效截止时间 |
| | | * @throws IOException |
| | | */ |
| | | private static boolean electricityControl(String ip, int port, byte[] addressBuf,int type, String date) { |
| | | /** |
| | | * N1为控制命令类型,N1=1AH代表跳闸4D,N1=1BH代表合闸4F允许N2保留 |
| | | * 权限密码操作代码:PAP2P1P0C3C2C1C0(02/223203/111111H) |
| | | * 4F |
| | | * TCP/IP直接合闸指令[2026年03月09日 10:57:39] |
| | | * Tx ->FEFEFEFE68615121010000681C1035366555776655444F33568843433659E016 |
| | | * TCP/IP直接合闸指令[2026年03月09日 10:57:40] |
| | | * Rx <-FEFEFEFE68615121010000689C004016 |
| | | * 直接合闸执行成功! 9C |
| | | */ |
| | | try { |
| | | byte control = 0x1C; |
| | | byte n1 = 0x4D; |
| | | if(type==1){ |
| | | n1 = 0x4F; |
| | | } |
| | | // byte[] data0 = {0x02, 0x03, 0x32, 0x22,0x44,0x33,0x22,0x11}; |
| | | byte[] data = {0x35, 0x36, 0x65, 0x55,0x77,0x66,0x55,0x44,n1,0x33,0,0,0,0,0,0}; |
| | | byte[] data2 = getDateBytes(date); |
| | | for (int i = 0; i < data2.length; i++) { |
| | | data[10+i]=data2[i]; |
| | | } |
| | | byte[] bufReq = getRequestParam(4, addressBuf, control, data); |
| | | String reqt = bytesToHex(bufReq); |
| | | System.out.println(reqt); |
| | | byte[] respBuf = readDeviceData(ip, port, bufReq); |
| | | String resp = bytesToHex(respBuf); |
| | | System.out.println(resp); |
| | | //FEFEFEFE68379707010000689C004216 |
| | | String msg = resp.substring(24, 26); |
| | | return msg.equals("9C"); |
| | | }catch (Exception e){ |
| | | |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | private static byte[] getDateBytes(String dateStr) { |
| | | // String dateStr = new SimpleDateFormat("yyyyMMddHHmmss").format(date); |
| | | dateStr = dateStr.substring(2); |
| | | // 1. 验证输入 |
| | | if (dateStr == null || dateStr.length() != 12) { |
| | | throw new IllegalArgumentException("时间必须是12位十进制数"); |
| | | } |
| | | if (!dateStr.matches("\\d{12}")) { |
| | | throw new IllegalArgumentException("时间必须全部是数字"); |
| | | } |
| | | // 2. 准备结果数组(6字节) |
| | | byte[] result = new byte[6]; |
| | | // 3. 从右向左每2位一组处理(小端序) |
| | | byte add = 0x33; |
| | | for (int i = 0; i < 6; i++) { |
| | | // 计算在字符串中的位置(从右向左) |
| | | int strIndex = 10 - (i * 2); // 因为要取两位,所以是10,8,6,4,2,0 |
| | | String twoDigits = dateStr.substring(strIndex, strIndex + 2); |
| | | // 将两位十进制数转换为BCD字节 |
| | | // 例如:"25" -> 0x25 |
| | | int t = Integer.parseInt(twoDigits, 16); |
| | | int t1 = ( t& 0xFF) + (add & 0xFF); |
| | | System.out.println(t1+":"); |
| | | result[i] =(byte) t1 ; |
| | | } |
| | | // 注意:上面的循环顺序已经是小端序,result[0]存的是最低两位 |
| | | return result; |
| | | } |
| | | |
| | | |
| | | private static void electricityStatus(String ip, int port, byte[] addressBuf, Map<String, Object> map) throws IOException { |
| | | byte control = 0x11; |
| | | byte[] data = {0x36, 0x38, 0x33, 0x37}; |
| | |
| | | String ts = hexToBinary1(nArr); |
| | | String time = "20"+ts.substring(0,6)+ts.substring(8); |
| | | Date date = getDateByStr(time); |
| | | System.out.println( formatData(date)); |
| | | // String resp = "FEFEFEFE 68 615121010000 68 91 06 36383337 3333 7916"; |
| | | map.put("currentTime", formatData(date)); |
| | | map.put("time", date); |
| | | // map.put("currentTime", formatData(date)); |
| | | } |
| | | public static Date getDateByStr(String date) { |
| | | TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai"); |
| | |
| | | return null; |
| | | } |
| | | |
| | | public static Map<String, Object> electricity(String ip, int port, String address) throws IOException { |
| | | public static Map<String, Object> electricityData(String ip, int port, String address) throws IOException { |
| | | Map<String, Object> r = new HashMap<>(); |
| | | byte[] addressBuf = convertToBCDAddress(address); |
| | | electricityTotal(ip, port, addressBuf, r); |
| | |
| | | electricityTime(ip, port, addressBuf, r); |
| | | return r; |
| | | } |
| | | |
| | | public static boolean electricityAct(String ip, int port, String address,int type,String dateStr) { |
| | | Map<String, Object> r = new HashMap<>(); |
| | | byte[] addressBuf = convertToBCDAddress(address); |
| | | return electricityControl(ip,port,addressBuf,type,dateStr); |
| | | } |
| | | private static String hexToBinary(String hex) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (char c : hex.toCharArray()) { |
| | |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | |
| | | private static String addHex(String hex1, String hex2) { |
| | | int num1 = Integer.parseInt(hex1.replace("0x", ""), 16); |
| | |
| | | public static void main(String[] args) throws IOException { |
| | | // testWater(); |
| | | // electricityTest(); |
| | | water("192.168.1.78",1030,"000152462599"); |
| | | Map<String, Object> map = electricity("192.168.1.78", 1030, "000001215161"); |
| | | System.out.println(JSONObject.toJSONString(map)); |
| | | // water("192.168.1.78",1030,"000152462599"); |
| | | // Map<String, Object> map = electricityData("192.168.1.78", 1030, "000001215161"); |
| | | // System.out.println(JSONObject.toJSONString(map)); |
| | | electricityAct("192.168.1.78", 1030, "000001215161",0,"20260309162655"); |
| | | // FEFEFE6899254652010068810 843C3333433333333 E9 16 |
| | | // FEFEFE6899254652010068810 84 3C3333433333333E916 |
| | | |