com.digitaldan.jomnilinkII.MessageFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jomnilink Show documentation
Show all versions of jomnilink Show documentation
jomnilink - A java library for connecting to HAI/Leviton Omni and Lumina home automation controllers
using the HAI OmniLink II protocol.
The newest version!
/**
* Copyright (c) 2009-2021 Dan Cunningham
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package com.digitaldan.jomnilinkII;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.digitaldan.jomnilinkII.MessageTypes.*;
import com.digitaldan.jomnilinkII.MessageTypes.properties.*;
import com.digitaldan.jomnilinkII.MessageTypes.statuses.*;
public class MessageFactory {
public static Message fromBytes(byte[] bytes) throws IOException, OmniUnknownMessageTypeException {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
int start = in.readUnsignedByte();
int length = in.readUnsignedByte();
int type = in.readUnsignedByte();
int len = length - 1;
byte[] data = new byte[len];
in.readFully(data);
bis = new ByteArrayInputStream(data);
in = new DataInputStream(bis);
switch (type) {
case Message.MESG_TYPE_ACK :
return acknowledge();
case Message.MESG_TYPE_NEG_ACK :
return negativeAcknowledge();
case Message.MESG_TYPE_END_OF_DATA :
return endOfData();
case Message.MESG_TYPE_SYS_INFO :
return systemInformation(in);
case Message.MESG_TYPE_SYS_STATUS :
return systemStatus(in, len);
case Message.MESG_TYPE_SYS_TROUBLES :
return systemTroubles(in, len);
case Message.MESG_TYPE_SYS_FEATURES :
return systemFeatures(in, len);
case Message.MESG_TYPE_SYS_FORMATS :
return systemFormats(in, len);
case Message.MESG_TYPE_OBJ_CAPACITY :
return objectTypeCapacities(in, len);
case Message.MESG_TYPE_OBJ_PROP :
return objectProperties(in, len);
case Message.MESG_TYPE_OBJ_STATUS :
return objectStatus(in, len, false);
case Message.MESG_TYPE_EXT_OBJ_STATUS :
return objectStatus(in, len, true);
case Message.MESG_TYPE_AUDIO_SOURCE_STATUS :
return audioSourceStatus(in, len);
case Message.MESG_TYPE_ZONE_READY :
return zoneReadyStatus(in, len);
case Message.MESG_TYPE_OTHER_EVENT_NOTIFY :
return otherEventNotification(in, len);
case Message.MESG_TYPE_EVENT_LOG_DATA :
return eventLogData(in, len);
case Message.MESG_TYPE_NAME_DATA :
return nameData(in, len);
case Message.MESG_TYPE_SEC_CODE_VALID :
return securityCodeValidation(in, len);
default :
throw new OmniUnknownMessageTypeException(type);
}
}
public static byte[] toBytes(Message msg) throws IOException, OmniUnknownMessageTypeException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream os = new DataOutputStream(bos);
os.writeByte(msg.getMessageType());
switch (msg.getMessageType()) {
case Message.MESG_TYPE_REQ_SYS_INFO :
case Message.MESG_TYPE_REQ_SYS_STATUS :
case Message.MESG_TYPE_REQ_SYS_TROUBLES :
case Message.MESG_TYPE_REQ_SYS_FEATURES :
case Message.MESG_TYPE_REQ_SYS_FORMATS :
case Message.MESG_TYPE_CLEAR_NAMES :
case Message.MESG_TYPE_CLEAR_VOICES :
break;
case Message.MESG_TYPE_ENABLE_NOTIFICATIONS : {
os.writeBoolean(((Notifications) msg).isEnabled());
}
break;
case Message.MESG_TYPE_REQ_OBJ_CAPACITY : {
ReqObjectTypeCapacities m = (ReqObjectTypeCapacities) msg;
os.writeByte(m.getObjectType());
}
break;
case Message.MESG_TYPE_REQ_OBJ_PROP : {
ReqObjectProperties m = (ReqObjectProperties) msg;
os.writeByte(m.getObjectType());
os.writeShort(m.getObjectNumber());
os.writeByte(m.getDirection());
os.writeByte(m.getFilter1());
os.writeByte(m.getFilter2());
os.writeByte(m.getFilter3());
}
break;
case Message.MESG_TYPE_REQ_EXT_OBJ_STATUS : {
ReqExtendedObjectStatus m = (ReqExtendedObjectStatus) msg;
os.writeByte(m.getObjectType());
os.writeShort(m.getStartObject());
os.writeShort(m.getEndObject());
}
break;
case Message.MESG_TYPE_REQ_OBJ_STATUS : {
ReqObjectStatus m = (ReqObjectStatus) msg;
os.writeByte(m.getObjectType());
os.writeShort(m.getStartObject());
os.writeShort(m.getEndObject());
}
break;
case Message.MESG_TYPE_REQ_AUDIO_SOURCE_STATUS : {
ReqAudioSourceStatus m = (ReqAudioSourceStatus) msg;
os.writeShort(m.getSource());
os.writeByte(m.getPosition());
}
break;
case Message.MESG_TYPE_REQ_ZONE_READY :
case Message.MESG_TYPE_REQ_CONN_SEC_STATUS :
break;
case Message.MESG_TYPE_COMMAND : {
CommandMessage m = (CommandMessage) msg;
os.writeByte(m.getCommand());
os.writeByte(m.getParameter1());
os.writeShort(m.getParameter2());
}
break;
case Message.MESG_TYPE_READ_EVENT_RECORD : {
ReadEventRecord m = (ReadEventRecord) msg;
os.writeShort(m.getEventNumber());
os.writeByte(m.getDirection());
}
break;
case Message.MESG_TYPE_READ_NAME : {
ReadName m = (ReadName) msg;
os.writeByte(m.getObjectType());
os.writeShort(m.getObjectNumber());
}
break;
case Message.MESG_TYPE_CONN_SEC_COMMAND : {
ConnectedSecurityCommand m = (ConnectedSecurityCommand) msg;
os.writeByte(m.getCommand());
os.writeByte(m.getPartition());
os.writeByte(m.getDigit1());
os.writeByte(m.getDigit2());
os.writeByte(m.getDigit3());
os.writeByte(m.getDigit4());
os.writeByte(m.getDigit5());
os.writeByte(m.getDigit6());
}
break;
case Message.MESG_TYPE_SET_TIME : {
SetTimeCommand m = (SetTimeCommand) msg;
os.writeByte(m.getYear());
os.writeByte(m.getMonth());
os.writeByte(m.getDay());
os.writeByte(m.getDayOfWeek());
os.writeByte(m.getHour());
os.writeByte(m.getMinute());
os.writeBoolean(m.isDaylightSavings());
}
break;
case Message.MESG_TYPE_ACT_KEYPAD_EMERGENCY : {
ActivateKeypadEmergency m = (ActivateKeypadEmergency) msg;
os.writeByte(m.getArea());
os.writeByte(m.getEmergencyType());
}
break;
case Message.MESG_TYPE_REQ_SEC_CODE_VALID : {
ReqSecurityCodeValidation m = (ReqSecurityCodeValidation) msg;
os.writeByte(m.getArea());
os.writeByte(m.getDigit1());
os.writeByte(m.getDigit2());
os.writeByte(m.getDigit3());
os.writeByte(m.getDigit4());
}
break;
case Message.MESG_TYPE_WRITE_NAME : {
WriteName m = (WriteName) msg;
int t = m.getObjectType();
os.writeByte(t);
os.writeShort(m.getObjectNumber());
byte[] d;
if (t == Message.OBJ_TYPE_ZONE || t == Message.OBJ_TYPE_MESG || t == Message.OBJ_TYPE_AUX_SENSOR) {
d = new byte[15];
} else {
d = new byte[12];
}
byte[] s = m.getName().getBytes();
int cnt = s.length;
if (s.length > d.length) {
cnt = d.length;
}
System.arraycopy(s, 0, d, 0, cnt);
os.write(d);
}
break;
default :
throw new OmniUnknownMessageTypeException(msg.getMessageType());
}
byte[] data = bos.toByteArray();
bos.reset();
os.writeByte(Message.MESG_START);
os.writeByte(data.length);
os.write(data);
// calc crc bytes of data, type and length
byte[] crcBytes = new byte[data.length + 1];
System.arraycopy(data, 0, crcBytes, 1, data.length);
crcBytes[0] = (byte) data.length;
int crc = MessageUtils.crc16(crcBytes);
// LSB then MSB
os.writeByte((byte) crc);
os.writeByte((byte) (crc >> 8));
return bos.toByteArray();
}
protected static Acknowledge acknowledge() {
return Acknowledge.getInstance();
}
protected static NegativeAcknowledge negativeAcknowledge() {
return NegativeAcknowledge.getInstance();
}
protected static EndOfData endOfData() {
return EndOfData.getInstance();
}
protected static SystemInformation systemInformation(DataInputStream in) throws IOException {
int model = in.readUnsignedByte();
int major = in.readUnsignedByte();
int minor = in.readUnsignedByte();
int revision = in.readUnsignedByte();
byte[] phoneBytes = new byte[15];
in.readFully(phoneBytes);
String phone = new String(phoneBytes);
return SystemInformation.builder().model(model).major(major).minor(minor).revision(revision).phone(phone)
.build();
}
protected static SystemStatus systemStatus(DataInputStream in, int len) throws IOException {
boolean timeDateValid = in.readBoolean();
int year = in.readUnsignedByte();
int month = in.readUnsignedByte();
int day = in.readUnsignedByte();
int dayOfWeek = in.readUnsignedByte();
int hour = in.readUnsignedByte();
int minute = in.readUnsignedByte();
int second = in.readUnsignedByte();
boolean daylightSavings = in.readBoolean();
int sunriseHour = in.readUnsignedByte();
int sunriseMinute = in.readUnsignedByte();
int sunsetHour = in.readUnsignedByte();
int sunsetMinute = in.readUnsignedByte();
int batteryReading = in.readUnsignedByte();
SystemStatus.SystemStatusBuilder builder = SystemStatus.builder().timeDateValid(timeDateValid).year(year)
.month(month).day(day).dayOfWeek(dayOfWeek).hour(hour).minute(minute).second(second)
.daylightSavings(daylightSavings).sunriseHour(sunriseHour).sunsetMinute(sunsetMinute)
.sunsetHour(sunsetHour).sunsetMinute(sunsetMinute).batteryReading(batteryReading);
for (int i = 16; i < len; i = i + 2) {
builder.alarm(in.readUnsignedByte(), in.readUnsignedByte());
}
return builder.build();
}
protected static SystemTroubles systemTroubles(DataInputStream in, int length) throws IOException {
SystemTroubles.SystemTroublesBuilder builder = SystemTroubles.builder();
for (int i = 0; i < length; i++) {
builder.trouble(in.readUnsignedByte());
}
return builder.build();
}
protected static SystemFeatures systemFeatures(DataInputStream in, int length) throws IOException {
SystemFeatures.SystemFeaturesBuilder builder = SystemFeatures.builder();
for (int i = 0; i < length; i++) {
builder.feature(in.readUnsignedByte());
}
return builder.build();
}
protected static SystemFormats systemFormats(DataInputStream in, int length) throws IOException {
int tempFormat = in.readUnsignedByte();
int timeFormat = in.readUnsignedByte();
int dateFormat = in.readUnsignedByte();
return SystemFormats.builder().tempFormat(tempFormat).timeFormat(timeFormat).dateFormat(dateFormat).build();
}
protected static ObjectTypeCapacities objectTypeCapacities(DataInputStream in, int length) throws IOException {
int objectType = in.readUnsignedByte();
int capacity = in.readUnsignedShort();
return ObjectTypeCapacities.builder().objectType(objectType).capacity(capacity).build();
}
protected static ObjectStatus objectStatus(DataInputStream in, int length, boolean extended) throws IOException {
int statusType = in.readUnsignedByte();
int recordLength = 0;
if (extended) {
recordLength = in.readUnsignedByte();
}
Status[] status;
switch (statusType) {
case Message.OBJ_TYPE_ZONE : {
if (!extended) {
status = new ZoneStatus[(length - 1) / 4];
for (int i = 0; i < status.length; i++) {
status[i] = ZoneStatus.builder().number(in.readUnsignedShort()).status(in.readUnsignedByte())
.loop(in.readUnsignedByte()).build();
}
} else {
status = new ExtendedZoneStatus[(length - 1) / 4];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedZoneStatus.builder().number(in.readUnsignedShort())
.status(in.readUnsignedByte()).loop(in.readUnsignedByte()).build();
}
}
}
break;
case Message.OBJ_TYPE_UNIT : {
if (!extended) {
status = new UnitStatus[(length - 1) / 5];
for (int i = 0; i < status.length; i++) {
status[i] = UnitStatus.builder().number(in.readUnsignedShort()).status(in.readUnsignedByte())
.time(in.readUnsignedShort()).build();
}
} else {
status = new ExtendedUnitStatus[(length - 1) / 5];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedUnitStatus.builder().number(in.readUnsignedShort())
.status(in.readUnsignedByte()).time(in.readUnsignedShort()).build();
}
}
}
break;
case Message.OBJ_TYPE_AREA : {
if (!extended) {
status = new AreaStatus[(length - 1) / 6];
for (int i = 0; i < status.length; i++) {
status[i] = AreaStatus.builder().number(in.readUnsignedShort()).mode(in.readUnsignedByte())
.alarms(in.readUnsignedByte()).entryTimer(in.readUnsignedByte())
.exitTimer(in.readUnsignedByte()).build();
}
} else {
status = new ExtendedAreaStatus[(length - 1) / 6];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedAreaStatus.builder().number(in.readUnsignedShort())
.mode(in.readUnsignedByte()).alarms(in.readUnsignedByte())
.entryTimer(in.readUnsignedByte()).exitTimer(in.readUnsignedByte()).build();
}
}
}
break;
case Message.OBJ_TYPE_THERMO : {
if (!extended) {
status = new ThermostatStatus[(length - 1) / 9];
for (int i = 0; i < status.length; i++) {
status[i] = ThermostatStatus.builder().number(in.readUnsignedShort())
.status(in.readUnsignedByte()).currentTemperature(in.readUnsignedByte())
.heatSetpoint(in.readUnsignedByte()).coolSetpoint(in.readUnsignedByte())
.systemMode(in.readUnsignedByte()).fanMode(in.readUnsignedByte())
.holdStatus(in.readUnsignedByte()).build();
}
} else {
status = new ExtendedThermostatStatus[(length - 1) / 14];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedThermostatStatus.builder().number(in.readUnsignedShort())
.status(in.readUnsignedByte()).currentTemperature(in.readUnsignedByte())
.heatSetpoint(in.readUnsignedByte()).coolSetpoint(in.readUnsignedByte())
.systemMode(in.readUnsignedByte()).fanMode(in.readUnsignedByte())
.holdStatus(in.readUnsignedByte()).currentHumidity(in.readUnsignedByte())
.humidifySetpoint(in.readUnsignedByte()).dehumidifySetpoint(in.readUnsignedByte())
.outdoorTemperature(in.readUnsignedByte()).extendedStatus(in.readUnsignedByte())
.build();
}
}
}
break;
case Message.OBJ_TYPE_MESG : {
if (!extended) {
status = new MessageStatus[(length - 1) / 3];
for (int i = 0; i < status.length; i++) {
status[i] = MessageStatus.builder().number(in.readUnsignedShort()).status(in.readUnsignedByte())
.build();
}
} else {
status = new ExtendedMessageStatus[(length - 1) / 3];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedMessageStatus.builder().number(in.readUnsignedShort())
.status(in.readUnsignedByte()).build();
}
}
}
break;
case Message.OBJ_TYPE_AUX_SENSOR : {
if (!extended) {
status = new AuxSensorStatus[(length - 1) / 6];
for (int i = 0; i < status.length; i++) {
status[i] = AuxSensorStatus.builder().number(in.readUnsignedShort())
.outputStatus(in.readUnsignedByte()).temperature(in.readUnsignedByte())
.heatSetpoint(in.readUnsignedByte()).coolSetpoint(in.readUnsignedByte()).build();
}
} else {
status = new ExtendedAuxSensorStatus[(length - 1) / 6];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedAuxSensorStatus.builder().number(in.readUnsignedShort())
.outputStatus(in.readUnsignedByte()).temperature(in.readUnsignedByte())
.heatSetpoint(in.readUnsignedByte()).coolSetpoint(in.readUnsignedByte()).build();
}
}
}
break;
case Message.OBJ_TYPE_AUDIO_ZONE : {
if (!extended) {
status = new AudioZoneStatus[(length - 1) / 6];
for (int i = 0; i < status.length; i++) {
status[i] = AudioZoneStatus.builder().number(in.readUnsignedShort()).power(in.readBoolean())
.source(in.readUnsignedByte()).volume(in.readUnsignedByte()).mute(in.readBoolean())
.build();
}
} else {
status = new ExtendedAudioZoneStatus[(length - 1) / 6];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedAudioZoneStatus.builder().number(in.readUnsignedShort())
.power(in.readBoolean()).source(in.readUnsignedByte()).volume(in.readUnsignedByte())
.mute(in.readBoolean()).build();
}
}
}
break;
case Message.OBJ_TYPE_EXP : {
if (!extended) {
status = new ExpansionStatus[(length - 1) / 4];
for (int i = 0; i < status.length; i++) {
status[i] = ExpansionStatus.builder().number(in.readUnsignedShort()).status(in.readBoolean())
.battery(in.readUnsignedByte()).build();
}
} else {
status = new ExtendedExpansionStatus[(length - 1) / 4];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedExpansionStatus.builder().number(in.readUnsignedShort())
.status(in.readBoolean()).battery(in.readUnsignedByte()).build();
}
}
}
break;
case Message.OBJ_TYPE_USER_SETTING : {
if (!extended) {
status = new UserSettingStatus[(length - 1) / 5];
for (int i = 0; i < status.length; i++) {
status[i] = UserSettingStatus.builder().number(in.readUnsignedShort())
.settingType(in.readUnsignedByte()).settingValue(in.readUnsignedShort()).build();
}
} else {
status = new ExtendedUserSettingStatus[(length - 1) / 5];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedUserSettingStatus.builder().number(in.readUnsignedShort())
.settingType(in.readUnsignedByte()).settingValue(in.readUnsignedShort()).build();
}
}
}
break;
case Message.OBJ_TYPE_CONTROL_READER : {
if (!extended) {
status = new AccessControlReaderStatus[(length - 1) / 4];
for (int i = 0; i < status.length; i++) {
status[i] = AccessControlReaderStatus.builder().number(in.readUnsignedShort())
.granted(!in.readBoolean()) // 0=granted, 1=denied
.lastUser(in.readUnsignedByte()).build();
}
} else {
status = new ExtendedAccessControlReaderStatus[(length - 1) / 4];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedAccessControlReaderStatus.builder().number(in.readUnsignedShort())
.granted(!in.readBoolean()) // 0=granted, 1=denied
.lastUser(in.readUnsignedByte()).build();
}
}
}
break;
case Message.OBJ_TYPE_CONTROL_LOCK : {
if (!extended) {
status = new AccessControlReaderLockStatus[(length - 1) / 5];
for (int i = 0; i < status.length; i++) {
status[i] = AccessControlReaderLockStatus.builder().number(in.readUnsignedShort())
.locked(!in.readBoolean()) // 0=locked, 1=unlocked
.timer(in.readUnsignedShort()).build();
}
} else {
status = new ExtendedAccessControlReaderLockStatus[(length - 1) / 5];
for (int i = 0; i < status.length; i++) {
status[i] = ExtendedAccessControlReaderLockStatus.builder().number(in.readUnsignedShort())
.locked(!in.readBoolean()) // 0=locked, 1=unlocked
.timer(in.readUnsignedShort()).build();
}
}
}
break;
default :
throw new IOException("Unknown status type " + statusType);
}
if (extended) {
return ExtendedObjectStatus.extendedBuilder().statusType(statusType).recordLength(recordLength)
.statuses(status).build();
} else {
return ObjectStatus.builder().statusType(statusType).statuses(status).build();
}
}
private static String readName(byte[] nameBytes) {
String name = new String(nameBytes);
if (name.indexOf('\0') >= 0) {
name = name.substring(0, name.indexOf('\0'));
}
return name;
}
protected static ObjectProperties objectProperties(DataInputStream in, int length) throws IOException {
int objectType = in.readUnsignedByte();
int number = in.readUnsignedShort();
byte[] nameShort = new byte[12];
byte[] nameLong = new byte[15];
switch (objectType) {
case Message.OBJ_TYPE_ZONE : {
int status = in.readUnsignedByte();
int loop = in.readUnsignedByte();
int type = in.readUnsignedByte();
int area = in.readUnsignedByte();
int options = in.readUnsignedByte();
in.readFully(nameLong);
String name = readName(nameLong);
return ZoneProperties.builder().number(number).status(status).loop(loop).zoneType(type).area(area)
.options(options).name(name).build();
}
case Message.OBJ_TYPE_UNIT : {
int state = in.readUnsignedByte();
int time = in.readUnsignedShort();
int type = in.readUnsignedByte();
in.readFully(nameShort);
String name = readName(nameShort);
return UnitProperties.builder().number(number).state(state).time(time).unitType(type).name(name)
.build();
}
case Message.OBJ_TYPE_BUTTON : {
in.readFully(nameShort);
String name = readName(nameShort);
return ButtonProperties.builder().number(number).name(name).build();
}
case Message.OBJ_TYPE_CODE : {
in.readFully(nameShort);
String name = readName(nameShort);
return CodeProperties.builder().number(number).name(name).build();
}
case Message.OBJ_TYPE_AREA : {
int mode = in.readUnsignedByte();
int alarms = in.readUnsignedByte();
int entryTimer = in.readUnsignedByte();
int exitTimer = in.readUnsignedByte();
boolean enabled = in.readBoolean();
int exitDelay = in.readUnsignedByte();
int entryDelay = in.readUnsignedByte();
in.readFully(nameShort);
String name = readName(nameShort);
return AreaProperties.builder().number(number).mode(mode).alarms(alarms).entryTimer(entryTimer)
.exitTimer(exitTimer).enabled(enabled).exitDelay(exitDelay).entryDelay(entryDelay).name(name)
.build();
}
case Message.OBJ_TYPE_THERMO : {
int status = in.readUnsignedByte();
int temperature = in.readUnsignedByte();
int heatSetpoint = in.readUnsignedByte();
int coolSetpoint = in.readUnsignedByte();
int mode = in.readUnsignedByte();
int fan = in.readUnsignedByte();
int hold = in.readUnsignedByte();
int thermostatType = in.readUnsignedByte();
in.readFully(nameShort);
String name = readName(nameShort);
return ThermostatProperties.builder().number(number).status(status).temperature(temperature)
.heatSetpoint(heatSetpoint).coolSetpoint(coolSetpoint).mode(mode).fan(fan).hold(hold)
.thermostatType(thermostatType).name(name).build();
}
case Message.OBJ_TYPE_MESG : {
in.readFully(nameLong);
String name = readName(nameLong);
return MessageProperties.builder().number(number).name(name).build();
}
case Message.OBJ_TYPE_AUX_SENSOR : {
int status = in.readUnsignedByte();
int current = in.readUnsignedByte();
int lowSetpoint = in.readUnsignedByte();
int highSetpoint = in.readUnsignedByte();
int sensorType = in.readUnsignedByte();
in.readFully(nameLong);
String name = readName(nameLong);
return AuxSensorProperties.builder().number(number).status(status).current(current)
.lowSetpoint(lowSetpoint).highSetpoint(highSetpoint).sensorType(sensorType).name(name).build();
}
case Message.OBJ_TYPE_AUDIO_SOURCE : {
in.readFully(nameShort);
String name = readName(nameShort);
return AudioSourceProperties.builder().number(number).name(name).build();
}
case Message.OBJ_TYPE_CONTROL_READER : {
boolean lockStatus = in.readBoolean();
int unlockTimer = in.readUnsignedShort();
boolean accessDenied = in.readBoolean();
int lastUser = in.readByte();
in.readFully(nameLong);
String name = readName(nameLong);
return AccessControlReaderProperties.builder().number(number).name(name).accessDenied(accessDenied)
.lastUser(lastUser).lockStatus(lockStatus).unlockTimer(unlockTimer).build();
}
case Message.OBJ_TYPE_AUDIO_ZONE : {
boolean on = in.readBoolean();
int source = in.readUnsignedByte();
int volume = in.readUnsignedByte();
boolean mute = in.readBoolean();
in.readFully(nameShort);
String name = readName(nameShort);
return AudioZoneProperties.builder().number(number).on(on).source(source).volume(volume).mute(mute)
.name(name).build();
}
default :
throw new IOException("Unknown property type " + objectType);
}
}
protected static AudioSourceStatus audioSourceStatus(DataInputStream in, int length) throws IOException {
int srcNumber = in.readUnsignedShort();
int seqNumber = in.readUnsignedByte();
int pos = in.readUnsignedByte();
int fieldId = in.readUnsignedByte();
byte[] data = new byte[length - 5];
in.readFully(data);
String sourceData = new String(data);
return AudioSourceStatus.builder().sourceNumber(srcNumber).sequenceNumber(seqNumber).position(pos)
.fieldId(fieldId).sourceData(sourceData).build();
}
protected static ZoneReadyStatus zoneReadyStatus(DataInputStream in, int length) throws IOException {
ZoneReadyStatus.ZoneReadyStatusBuilder builder = ZoneReadyStatus.builder();
for (int i = 0; i < length; i++) {
builder.zone(in.readUnsignedByte());
}
return builder.build();
}
protected static ConnectedSecurityStatus connectedSecurityStatus(DataInputStream in, int length)
throws IOException {
int[] parts = new int[length];
ConnectedSecurityStatus.ConnectedSecurityStatusBuilder builder = ConnectedSecurityStatus.builder();
for (int i = 0; i < length / 2; i++) {
ConnectedSecurityStatus.Partition partition = new ConnectedSecurityStatus.Partition(in.readUnsignedByte(),
in.readUnsignedByte());
builder.partition(partition);
}
return builder.build();
}
protected static OtherEventNotifications otherEventNotification(DataInputStream in, int length) throws IOException {
OtherEventNotifications.OtherEventNotificationsBuilder builder = OtherEventNotifications.builder();
for (int i = 0; i < length / 2; i++) {
builder.notification(in.readUnsignedShort());
}
return builder.build();
}
protected static EventLogData eventLogData(DataInputStream in, int length) throws IOException {
int eventNumber = in.readUnsignedShort();
boolean timeDataValid = in.readBoolean();
int month = in.readUnsignedByte();
int day = in.readUnsignedByte();
int hour = in.readUnsignedByte();
int minute = in.readUnsignedByte();
int eventType = in.readUnsignedByte();
int parameter1 = in.readUnsignedByte();
int parameter2 = in.readUnsignedShort();
return EventLogData.builder().eventNumber(eventNumber).timeDataValid(timeDataValid).month(month).day(day)
.hour(hour).minute(minute).eventType(eventType).parameter1(parameter1).parameter2(parameter2).build();
}
protected static NameData nameData(DataInputStream in, int length) throws IOException {
int objectType = in.readUnsignedByte();
int objectNumber = in.readUnsignedShort();
byte[] data = new byte[length - 3];
in.readFully(data);
String name = new String(data);
return NameData.builder().objectType(objectType).objectNumber(objectNumber).name(name).build();
}
protected static SecurityCodeValidation securityCodeValidation(DataInputStream in, int length) throws IOException {
int code = in.readUnsignedByte();
int level = in.readUnsignedByte();
return SecurityCodeValidation.builder().codeNumber(code).authorityLevel(level).build();
}
}