// Path: src/main/java/com/roysolberg/java/hdlserver/hdl/component/HdlComponent.java
// public abstract class HdlComponent implements Serializable{
// 
//     protected int subnet; // 0-254
//     protected int deviceId; // 0-254
//     protected int deviceType; // 0-65535 // TODO: Why do we use both "device" and "component" for the same thing?
//     protected String remark;
// 
//     public HdlComponent(int subnet, int deviceId, int deviceType, String remark) {
//         this.subnet = subnet;
//         this.deviceId = deviceId;
//         this.deviceType = deviceType;
//         this.remark = getCleanRemark(remark);
//     }
// 
//     protected String getCleanRemark(String remark) {
//         if (remark != null) {
//             remark = remark.replaceAll("\u0000", "");
//         }
//         return remark;
//     }
// 
//     public int getSubnet() {
//         return subnet;
//     }
// 
//     public void setSubnet(int subnet) {
//         this.subnet = subnet;
//     }
// 
//     public int getDeviceId() {
//         return deviceId;
//     }
// 
//     public void setDeviceId(int deviceId) {
//         this.deviceId = deviceId;
//     }
// 
//     public int getDeviceType() {
//         return deviceType;
//     }
// 
//     public void setDeviceType(int deviceType) {
//         this.deviceType = deviceType;
//     }
// 
//     public abstract String getDeviceGroup();
// 
//     public String getRemark() {
//         return remark;
//     }
// 
//     public void setDescription(String remark) {
//         this.remark = remark;
//     }
// 
//     public abstract String getDescription();
// 
//     public abstract int getDefaultSortOrder();
// 
//     @Override
//     public String toString() {
//         return "HdlComponent[remark:" + remark + ",description:" + getDescription() + ",type:" + deviceType + ",subnet:" + subnet + ",device:" + deviceId + "]";
//     }
// 
// }


import com.roysolberg.java.hdlserver.hdl.component.HdlComponent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Arrays;
            case 0xE3DA:
                return "Read panel status";
            case 0xE3DB:
                return "Response read panel status";
            case 55808: // 0xDA00
                return "Read system date and time";
            case 55809: // 0xDA01
                return "Response read system date and time";
            case 55876: // 0xDA44
                return "Broadcast system date and time (every minute)";
            case 58341: // 0xE3E5
                return "Broadcast temperature";
            case 61439: // 0xEFFF
                return "Broadcast status of scene";
            case 61494: // 0xF036
                return "Broadcast status of sequence";
            case 0xF037:
                return "Read IP module config";
            case 0xF038:
                return "Response read IP module config";
            default:
                return "Unknown operation";
        }
    }

    public static String getNiceOperationCode(byte[] bytes) {
        int operationCode = (bytes[BYTE_POSITION_OPERATION_CODE_BYTE_2] & 0xFF) | (bytes[BYTE_POSITION_OPERATION_CODE_BYTE_1] & 0xFF) << 8;
        return getNiceOperationCode(operationCode);
    }

// Path: src/main/java/com/roysolberg/java/hdlserver/hdl/component/HdlComponent.java
// public abstract class HdlComponent implements Serializable{
// 
//     protected int subnet; // 0-254
//     protected int deviceId; // 0-254
//     protected int deviceType; // 0-65535 // TODO: Why do we use both "device" and "component" for the same thing?
//     protected String remark;
// 
//     public HdlComponent(int subnet, int deviceId, int deviceType, String remark) {
//         this.subnet = subnet;
//         this.deviceId = deviceId;
//         this.deviceType = deviceType;
//         this.remark = getCleanRemark(remark);
//     }
// 
//     protected String getCleanRemark(String remark) {
//         if (remark != null) {
//             remark = remark.replaceAll("\u0000", "");
//         }
//         return remark;
//     }
// 
//     public int getSubnet() {
//         return subnet;
//     }
// 
//     public void setSubnet(int subnet) {
//         this.subnet = subnet;
//     }
// 
//     public int getDeviceId() {
//         return deviceId;
//     }
// 
//     public void setDeviceId(int deviceId) {
//         this.deviceId = deviceId;
//     }
// 
//     public int getDeviceType() {
//         return deviceType;
//     }
// 
//     public void setDeviceType(int deviceType) {
//         this.deviceType = deviceType;
//     }
// 
//     public abstract String getDeviceGroup();
// 
//     public String getRemark() {
//         return remark;
//     }
// 
//     public void setDescription(String remark) {
//         this.remark = remark;
//     }
// 
//     public abstract String getDescription();
// 
//     public abstract int getDefaultSortOrder();
// 
//     @Override
//     public String toString() {
//         return "HdlComponent[remark:" + remark + ",description:" + getDescription() + ",type:" + deviceType + ",subnet:" + subnet + ",device:" + deviceId + "]";
//     }
// 
// }


// Path: src/main/java/com/roysolberg/java/hdlserver/util/HdlUtil.java
import com.roysolberg.java.hdlserver.hdl.component.HdlComponent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Arrays;

            case 0xE3DA:
                return "Read panel status";
            case 0xE3DB:
                return "Response read panel status";
            case 55808: // 0xDA00
                return "Read system date and time";
            case 55809: // 0xDA01
                return "Response read system date and time";
            case 55876: // 0xDA44
                return "Broadcast system date and time (every minute)";
            case 58341: // 0xE3E5
                return "Broadcast temperature";
            case 61439: // 0xEFFF
                return "Broadcast status of scene";
            case 61494: // 0xF036
                return "Broadcast status of sequence";
            case 0xF037:
                return "Read IP module config";
            case 0xF038:
                return "Response read IP module config";
            default:
                return "Unknown operation";
        }
    }

    public static String getNiceOperationCode(byte[] bytes) {
        int operationCode = (bytes[BYTE_POSITION_OPERATION_CODE_BYTE_2] & 0xFF) | (bytes[BYTE_POSITION_OPERATION_CODE_BYTE_1] & 0xFF) << 8;
        return getNiceOperationCode(operationCode);
    }

    public static String getNicelyDescribedBytes(byte[] bytes, HdlComponent hdlComponent) {