数据单元标识定义
信息点 DA 由信息点元 DA1 和信息点组 DA2 两个字节构成。DA2 采用二进 制编码方式表示信息点组,DA1 对位表示某一信息点组的 1~8 个信息点,以此 共同构成信息点标识 Pn(256*8: n=1~2040)
信息点
当 DA1 和 DA2 全为“0”时,表示终端信息点,用 P0 表示;信息点标识 Pn 对应于不同信息类标识 Fn 可以是测点号、灯号、组号等
信息类
信息类 DT 由信息类元 DT1 和信息类组 DT2 两个字节构成。DT2 采用二进 制编码方式表示信息类组,DT1 对位表示某一信息类组的 1~8 种信息类型,以 此共同构成信息类标识 Fn
Java工具类
package com.utils;/*** 信息点组 DA2 | 信息点元 DA1* DA2从1开始 | D7 D6 D5 D4 D3 D2 D1 D0* -------------|-----------------------------------------* 1 | P8 P7 P6 P5 P4 P3 P2 P1* 2 | P16 P15 P14 P13 P12 P11 P10 P9* 3 | P24 P23 P22 P21 P20 P19 P18 P17* ... | ... ... ... ... ... ... ... ...* 255 |P2040 P2039 P2038 P2037 P2036 P2035 P2034 P2033** Fn的两个字节组成* 信息类组 DT2 | 信息类元 DT1* DT2从0开始 | D7 D6 D5 D4 D3 D2 D1 D0* -------------|-----------------------------------------------------* 0 | F8 F7 F6 F5 F4 F3 F2 F1* 1 | F16 F15 F14 F13 F12 F11 F10 F9* 2 | F24 F23 F22 F21 F20 F19 F18 F17* ... | ... ... ... ... ... ... ... ...* 30 |F248 F247 F246 F245 F244 F243 F242 F241* -------------|-----------------------------------------------------* 255 | 未定义*/
public class GBPnFnUtil {public static void main(String[] args) {// 计算并返回 PnFn 的值String pnValue = getPnFn("00008003");System.out.println("PnFn value: " + pnValue);// PnFn P0F3String pnfn = "P0F32";// 计算并返回的十六进制值String hex = getHexFromPnFn(pnfn);System.out.println("Hex value: " + hex);}/*** 根据DA2 DA1 DT2 DT1十六进制获取数据* @param da1da2dt1dt2hex* @return*/public static String getPnFn(String da1da2dt1dt2hex){short[] pnfnByte = HexUtil.hexStrToByteArray(da1da2dt1dt2hex);//设备传送过来的数据顺序DA1 DA2 DT1 DT2int da1 = pnfnByte[0];int da2 = pnfnByte[1];int dt1 = pnfnByte[2];int dt2 = pnfnByte[3];//获取PNFN使用数据时DA2 DA1 DT2 DT1String pnValue = getPnValue(da2, da1);String fnValue = getFnValue(dt2, dt1);return pnValue+fnValue;}private static String getPnValue(int da2, int da1) {// 特殊情况处理:当 DA1 和 DA2 全为“0”时,返回 P0if (da2 == 0 && da1 == 0) {return "P0";}// 每组包含 8 个 P 值int groupSize = 8;// 计算 Pn 的基索引int baseIndex = (da2-1) * groupSize;if (baseIndex<0) baseIndex = 0;// DA1 的每个位对应一个 P 值int bitIndex = Integer.numberOfTrailingZeros(da1);// 最终的 Pn 索引int pnIndex = baseIndex + bitIndex + 1;// 返回 Pn 值return "P" + pnIndex;}/*** Fn的两个字节组成* 信息类组 DT2 | 信息类元 DT1* | D7 D6 D5 D4 D3 D2 D1 D0* -------------|-----------------------------------------------------* 0 | F8 F7 F6 F5 F4 F3 F2 F1* 1 | F16 F15 F14 F13 F12 F11 F10 F9* 2 | F24 F23 F22 F21 F20 F19 F18 F17* ... | ... ... ... ... ... ... ... ...* 30 |F248 F247 F246 F245 F244 F243 F242 F241* -------------|-----------------------------------------------------* 255 | 未定义* @param dt2* @param dt1* @return*/private static String getFnValue(int dt2, int dt1) {// 特殊情况处理:当 DA1 和 DA2 全为“0”时,返回 P0if (dt2 == 0 && dt1 == 0) {return "F0";}// 每组包含 8 个 P 值int groupSize = 8;// 计算 Pn 的基索引int baseIndex = dt2 * groupSize;if (baseIndex<0) baseIndex = 0;// DA1 的每个位对应一个 P 值int bitIndex = Integer.numberOfTrailingZeros(dt1);// 最终的 Fn 索引int fnIndex = baseIndex + bitIndex + 1;// 返回 Fn 值return "F" + fnIndex;}/*** 根据PnFn字符串获取对应的十六进制数据* @param pnfnstr* @return*/public static String getHexFromPnFn(String pnfnstr){// 提取 Pn 和 FnString pn = pnfnstr.substring(0, pnfnstr.indexOf('F'));String fn = pnfnstr.substring(pnfnstr.indexOf('F'));// 获取 DA1 DA2int[] da1da2 = getHexFromPn(pn);int da1 = da1da2[0];int da2 = da1da2[1];// 获取 DT1 DT2int[] dt1dt2 = getHexFromFn(fn);int dt1 = dt1dt2[0];int dt2 = dt1dt2[1];// 组合为十六进制字符串return String.format("%02X%02X%02X%02X", da1, da2, dt1, dt2);}private static int[] getHexFromPn(String pn) {int pnIndex = Integer.parseInt(pn.substring(1));// 特殊情况处理:当 Pn 为 P0 时,返回 DA1 = 0, DA2 = 0if (pnIndex == 0) {return new int[]{0, 0};}int groupSize = 8;int da2 = (pnIndex - 1) / groupSize + 1;int bitIndex = (pnIndex - 1) % groupSize;int da1 = 1 << bitIndex;return new int[]{da1, da2};}private static int[] getHexFromFn(String fn) {int fnIndex = Integer.parseInt(fn.substring(1));// 特殊情况处理:当 Fn 为 F0 时,返回 DT1 = 0, DT2 = 0if (fnIndex == 0) {return new int[]{0, 0};}int groupSize = 8;int dt2 = (fnIndex - 1) / groupSize;int bitIndex = (fnIndex - 1) % groupSize;int dt1 = 1 << bitIndex;return new int[]{dt1, dt2};}
}