数据单元标识定义

PnFn信息点信息类工具类_数据


信息点 DA 由信息点元 DA1 和信息点组 DA2 两个字节构成。DA2 采用二进 制编码方式表示信息点组,DA1 对位表示某一信息点组的 1~8 个信息点,以此 共同构成信息点标识 Pn(256*8: n=1~2040)

信息点

PnFn信息点信息类工具类_十六进制_02


当 DA1 和 DA2 全为“0”时,表示终端信息点,用 P0 表示;信息点标识 Pn 对应于不同信息类标识 Fn 可以是测点号、灯号、组号等

信息类

PnFn信息点信息类工具类_数据_03


信息类 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 P0F3
        String 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 DT2
        int da1 = pnfnByte[0];
        int da2 = pnfnByte[1];
        int dt1 = pnfnByte[2];
        int dt2 = pnfnByte[3];
        //获取PNFN使用数据时DA2 DA1 DT2 DT1
        String pnValue = getPnValue(da2, da1);
        String fnValue = getFnValue(dt2, dt1);
        return pnValue+fnValue;
    }


    private static String getPnValue(int da2, int da1) {
        // 特殊情况处理:当 DA1 和 DA2 全为“0”时,返回 P0
        if (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”时,返回 P0
        if (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 和 Fn
        String pn = pnfnstr.substring(0, pnfnstr.indexOf('F'));
        String fn = pnfnstr.substring(pnfnstr.indexOf('F'));

        // 获取 DA1 DA2
        int[] da1da2 = getHexFromPn(pn);
        int da1 = da1da2[0];
        int da2 = da1da2[1];

        // 获取 DT1 DT2
        int[] 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 = 0
        if (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 = 0
        if (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};
    }
}

如果这篇文章对你有用,可以关注本人微信公众号获取更多ヽ(^ω^)ノ ~

PnFn信息点信息类工具类_数据_04