/**
* Copyright (c) 2010-2016 by the respective copyright holders.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.openhab.binding.swegonventilation.protocol;
import java.util.HashMap;
import org.openhab.binding.swegonventilation.internal.SwegonVentilationCommandType;
import org.openhab.binding.swegonventilation.internal.SwegonVentilationException;
/**
* Class for parse data packets from Swegon ventilation system.
*
* @author Pauli Anttila
* @since 1.4.0
*/
public class SwegonVentilationDataParser {
public static HashMap<SwegonVentilationCommandType, Integer> parseData(byte[] data)
throws SwegonVentilationException {
if (data[0] == (byte) 0x64) {
@SuppressWarnings("unused")
byte unknownByte = data[1];
@SuppressWarnings("unused")
byte destinationAddress = data[2];
@SuppressWarnings("unused")
byte sourceAddress = data[3];
byte dataLen = data[4];
byte msgType = data[5];
byte[] d = new byte[dataLen - 3];
for (int i = 8; i < (data.length - 3); i++) {
d[i - 8] = data[i];
}
switch (msgType) {
case (byte) 0x21:
return parseMessage21(d);
case (byte) 0x71:
return parseMessage71(d);
case (byte) 0x73:
return parseMessage73(d);
}
} else {
throw new SwegonVentilationException("Illegal data received, first byte mismatch!");
}
return null;
}
private static HashMap<SwegonVentilationCommandType, Integer> parseMessage21(byte[] data) {
HashMap<SwegonVentilationCommandType, Integer> map = new HashMap<SwegonVentilationCommandType, Integer>();
int operatingMode = data[0];
int unitState = data[1];
int fanSpeed = data[3] & 0x0F;
map.put(SwegonVentilationCommandType.OPERATING_MODE, operatingMode);
map.put(SwegonVentilationCommandType.UNIT_STATE, unitState);
map.put(SwegonVentilationCommandType.FAN_SPEED, fanSpeed);
return map;
}
private static HashMap<SwegonVentilationCommandType, Integer> parseMessage71(byte[] data) {
HashMap<SwegonVentilationCommandType, Integer> map = new HashMap<SwegonVentilationCommandType, Integer>();
int outdoorTemp = data[0];
int supplyTemp = data[1];
int extractTemp = data[2];
int supplyTempHeated = data[3];
int t5 = data[4];
int t6 = data[5];
int t7 = data[6];
int exhaustTemp = data[7];
int co2 = data[8];
int rh = data[9];
int supplyFanSpeed = (data[10] & 0xFF) * 10;
int extractFanSpeed = (data[11] & 0xFF) * 10;
int efficiency = data[12];
map.put(SwegonVentilationCommandType.T1, outdoorTemp);
map.put(SwegonVentilationCommandType.OUTDOOR_TEMP, outdoorTemp);
map.put(SwegonVentilationCommandType.T2, supplyTemp);
map.put(SwegonVentilationCommandType.SUPPLY_TEMP, supplyTemp);
map.put(SwegonVentilationCommandType.T3, extractTemp);
map.put(SwegonVentilationCommandType.EXTRACT_TEMP, extractTemp);
map.put(SwegonVentilationCommandType.T4, supplyTempHeated);
map.put(SwegonVentilationCommandType.SUPPLY_TEMP_HEATED, supplyTempHeated);
map.put(SwegonVentilationCommandType.T8, exhaustTemp);
map.put(SwegonVentilationCommandType.EXHAUST_TEMP, exhaustTemp);
map.put(SwegonVentilationCommandType.T5, t5);
map.put(SwegonVentilationCommandType.T6, t6);
map.put(SwegonVentilationCommandType.T7, t7);
map.put(SwegonVentilationCommandType.CO2, co2);
map.put(SwegonVentilationCommandType.HUMIDITY, rh);
map.put(SwegonVentilationCommandType.SUPPLY_AIR_FAN_SPEED, supplyFanSpeed);
map.put(SwegonVentilationCommandType.EXTRACT_AIR_FAN_SPEED, extractFanSpeed);
map.put(SwegonVentilationCommandType.EFFICIENCY, efficiency);
// Calculate supply efficiency
int calcEfficiency = (int) (((double) supplyTemp - (double) outdoorTemp)
/ ((double) extractTemp - (double) outdoorTemp) * 100);
map.put(SwegonVentilationCommandType.EFFICIENCY_SUPPLY, calcEfficiency);
// Calculate extract efficiency
calcEfficiency = (int) (((double) extractTemp - (double) exhaustTemp)
/ ((double) extractTemp - (double) outdoorTemp) * 100);
map.put(SwegonVentilationCommandType.EFFICIENCY_EXTRACT, calcEfficiency);
return map;
}
private static HashMap<SwegonVentilationCommandType, Integer> parseMessage73(byte[] data) {
HashMap<SwegonVentilationCommandType, Integer> map = new HashMap<SwegonVentilationCommandType, Integer>();
map.put(SwegonVentilationCommandType.HEATING_STATE, (data[0] & 0x01) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.COOLING_STATE, (data[0] & 0x02) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.BYBASS_STATE, (data[0] & 0x04) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.FREEZE_PROTECTION_STATE, (data[0] & 0x08) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.PREHEAT_STATE, (data[0] & 0x10) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.PREHEATING_STATE, (data[0] & 0x10) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.CHILLING_STATE, (data[0] & 0x20) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.PREHEATER_OVERHEAT_STATE, (data[0] & 0x40) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.REHEAT_STATE, (data[0] & 0x80) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.REHEATING_STATE, (data[0] & 0x80) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.FIREPLACE_FUNCTION_STATE, (data[1] & 0x01) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.UNDERPRESSURE_COMPENSATION_STATE, (data[1] & 0x02) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.EXTERNAL_BOOST_STATE, (data[1] & 0x04) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.HUMIDITY_BOOST_STATE, (data[1] & 0x08) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.CO2_BOOST_STATE, (data[1] & 0x10) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.DEFROSTING_STATE, (data[1] & 0x20) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.DEFROST_STARTER_MODE, (data[1] & 0x40));
map.put(SwegonVentilationCommandType.TF_STOP_STATE, (data[1] & 0x80) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.EXTERNAL_BOOST_FUNCTION_STATE, (data[3] & 0x04) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.EXTERNAL_FIREPLACE_FUNCTION_STATE, (data[3] & 0x08) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.FILTER_GUARD_STATUS, (data[3] & 0x10) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.IR_FREEZE_PROTECTION_STATUS, (data[3] & 0x20) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.EMERGENCY_STOP_STATE, (data[3] & 0x80) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.REHEATING_FREEZING_ALARM, (data[7] & 0x01) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.REHEATING_OVERHEAT_ALARM, (data[7] & 0x02) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.IR_SENSOR_FAILURE, (data[7] & 0x04) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.SUPPLY_FAN_FAILURE, (data[7] & 0x08) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.EXTRACT_FAN_FAILURE, (data[7] & 0x10) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.TEMPERATURE_DEVIATION_FAILURE, (data[7] & 0x20) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.EFFICINECY_ALARM, (data[8] & 0x01) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.FILTER_GUARD_ALARM, (data[8] & 0x02) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.SERVICE_REMINDER, (data[8] & 0x04) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.TEMPERATURE_FAILURE, (data[8] & 0x08) > 0 ? 1 : 0);
map.put(SwegonVentilationCommandType.AFTERHEATING_SETPOINT_SUPPLY_AIR_REGULATED, (int) data[10]);
map.put(SwegonVentilationCommandType.AFTERHEATING_SETPOINT_ROOM_REGULATED, (int) data[11]);
map.put(SwegonVentilationCommandType.SUPPLY_FAN_VIRTUAL_SPEED, (int) data[12]);
map.put(SwegonVentilationCommandType.EXTRACT_FAN_VIRTUAL_SPEED, (int) data[13]);
map.put(SwegonVentilationCommandType.UNIT_STATUS, (int) data[14]);
return map;
}
}