package art.servers.asfserver.protocols.dgt;
|
|
import art.library.model.devices.DeviceStatus;
|
import art.library.model.devices.vms.asf.Asf;
|
import art.library.model.devices.vms.asf.AsfStatus;
|
import art.library.model.devices.vms.asf.information.AsfInformationConfigurationAddressState;
|
import art.library.model.devices.vms.general.VmsGeneral;
|
import art.library.model.devices.vms.general.VmsGeneralStatus;
|
import art.library.utils.common.ArrayUtils;
|
import art.library.utils.common.NumberUtils;
|
import art.servers.Shared;
|
import art.servers.asfserver.types.VmsGraphic;
|
import java.awt.Color;
|
|
public class AsfDgtProtocolAnalyser
|
{
|
|
public AsfDgtProtocolAnalyser()
|
{
|
}
|
|
public static void analyseResponseReset(int[] information) throws Exception
|
{
|
checkAck(information);
|
}
|
|
public static void analyseResponseTimeout(int[] information) throws Exception
|
{
|
checkAck(information);
|
}
|
|
public static void analyseResponseMPP(Asf deviceclone, int[] information) throws Exception
|
{
|
checkAck(information);
|
}
|
|
public static void analyseResponseMEP(Asf deviceclone, int[] information) throws Exception
|
{
|
int state = information[0];
|
|
switch (state)
|
{
|
|
case AsfDgtConstants.ASF_OFF:
|
deviceclone.getDeviceStatus().state = AsfStatus.STATE_OFF;
|
break;
|
|
case AsfDgtConstants.ASF_FIX:
|
analyseFixState(deviceclone, information, 1);
|
break;
|
default:
|
throw new Exception("Invalid operation");
|
}
|
}
|
|
public static void analyseResponseEyA(Asf deviceclone, int[] information) throws Exception
|
{
|
int status = information[0];
|
int brightness = information[1];
|
int technology = information[2];
|
int activeAlarms1 = information[3];
|
int activeAlarms2 = information[4];
|
int activeAlarms3 = information[5];
|
int activeAlarms4 = information[6];
|
|
if (brightness >= 0x30)
|
{
|
brightness = brightness - 0x30;
|
}
|
deviceclone.getDeviceStatus().brightnessLevel = AsfDgtProtocolConstructor.getBrightnessClientLevel(brightness, 100, deviceclone.getDeviceInformation().maximumBrightnessLevel);
|
|
if ((status & 0x01) != 0)
|
{
|
// AN
|
deviceclone.setAlarm("alarm_offline", false);
|
deviceclone.setAlarm("alarm_abnormal_state", false);
|
}
|
|
if ((status & 0x02) != 0)
|
{
|
// NC
|
deviceclone.setAlarm("alarm_offline", true);
|
deviceclone.setAlarm("alarm_abnormal_state", false);
|
}
|
|
if ((status & 0x04) != 0)
|
{
|
// EA
|
deviceclone.setAlarm("alarm_offline", false);
|
deviceclone.setAlarm("alarm_abnormal_state", true);
|
}
|
|
deviceclone.setAlarm("alarm_open_door", ((activeAlarms1 & 0x01) != 0));
|
deviceclone.setAlarm("alarm_configuration", ((activeAlarms1 & 0x02) != 0));
|
deviceclone.setAlarm("alarm_terminal", ((activeAlarms1 & 0x04) != 0));
|
deviceclone.setAlarm("alarm_ventilation_on", ((activeAlarms1 & 0x08) != 0));
|
deviceclone.setAlarm("alarm_ventilation_failure", ((activeAlarms1 & 0x10) != 0));
|
deviceclone.setAlarm("alarm_hardware_error", ((activeAlarms1 & 0x20) != 0));
|
deviceclone.setAlarm("alarm_temperature_high", ((activeAlarms1 & 0x80) != 0));
|
|
deviceclone.setAlarm("alarm_temperature_exceeded", ((activeAlarms2 & 0x01) != 0));
|
deviceclone.setAlarm("alarm_mains_voltage_error", ((activeAlarms2 & 0x02) != 0));
|
deviceclone.setAlarm("alarm_batteries_degraded", ((activeAlarms2 & 0x04) != 0));
|
deviceclone.setAlarm("alarm_power_stopped", ((activeAlarms2 & 0x08) != 0));
|
deviceclone.setAlarm("alarm_batteries_low", ((activeAlarms2 & 0x10) != 0));
|
deviceclone.setAlarm("alarm_batteries_disconnected", ((activeAlarms2 & 0x20) != 0));
|
deviceclone.setAlarm("alarm_heating_on", ((activeAlarms2 & 0x40) != 0));
|
deviceclone.setAlarm("alarm_batteries_not_totally_charged", ((activeAlarms2 & 0x80) != 0));
|
|
deviceclone.setAlarm("alarm_red_power_failure", ((activeAlarms3 & 0x01) != 0));
|
deviceclone.setAlarm("alarm_green_power_failure", ((activeAlarms3 & 0x02) != 0));
|
deviceclone.setAlarm("alarm_blue_power_failure", ((activeAlarms3 & 0x04) != 0));
|
deviceclone.setAlarm("alarm_yellow_power_failure", ((activeAlarms3 & 0x08) != 0));
|
deviceclone.setAlarm("alarm_white_power_failure", ((activeAlarms3 & 0x10) != 0));
|
deviceclone.setAlarm("alarm_led_failure", ((activeAlarms3 & 0x20) != 0));
|
|
deviceclone.setAlarm("alarm_power_failure", ((activeAlarms4 & 0x01) != 0));
|
deviceclone.setAlarm("alarm_photocell_failure", ((activeAlarms4 & 0x08) != 0));
|
deviceclone.setAlarm("alarm_power_contactor_failure", ((activeAlarms4 & 0x10) != 0));
|
deviceclone.setAlarm("alarm_start_delay_condensation", ((activeAlarms4 & 0x20) != 0));
|
deviceclone.setAlarm("alarm_humidity_sensor_failure", ((activeAlarms4 & 0x40) != 0));
|
}
|
|
public static void analyseResponseEP(Asf deviceclone, int[] information) throws Exception
|
{
|
int state = information[0];
|
|
if (state == AsfDgtConstants.ASF_OFF)
|
{
|
deviceclone.getDeviceStatus().state = AsfStatus.STATE_OFF;
|
return;
|
}
|
|
switch (state)
|
{
|
case AsfDgtConstants.ASF_FIX:
|
analyseFixState(deviceclone, information, 1);
|
break;
|
case AsfDgtConstants.ASF_ALTERNANT:
|
case AsfDgtConstants.ASF_SEQUENCE:
|
throw new Exception("Operation not supported");
|
default:
|
throw new Exception("Invalid operation");
|
}
|
}
|
|
public static void analyseResponsePP(Asf deviceclone, int[] information) throws Exception
|
{
|
int numberParameters = information[0];
|
int pointer = 1;
|
for (int i = 0; i < numberParameters; i++)
|
{
|
int parameterType = information[pointer++];
|
switch (parameterType)
|
{
|
case AsfDgtConstants.ASF_BRIGHTNESS_PARAMETER:
|
{
|
int brightnessMode = information[pointer++];
|
if (brightnessMode == 'A')
|
{
|
deviceclone.getDeviceStatus().brightnessMode = VmsGeneralStatus.BRIGHTNESS_MODE_AUTO;
|
} else
|
{
|
deviceclone.getDeviceStatus().brightnessMode = VmsGeneralStatus.BRIGHTNESS_MODE_MANUAL;
|
}
|
}
|
break;
|
|
case AsfDgtConstants.ASF_ALTERNANCE_TIME_PARAMETER:
|
{
|
int alternatingTime = information[pointer++];
|
}
|
break;
|
|
case AsfDgtConstants.ASF_BLINK_TIMES_PARAMETER:
|
{
|
deviceclone.getDeviceStatus().blinkOn = (float) ((float) information[pointer++] / 10f);
|
deviceclone.getDeviceStatus().blinkOff = (float) ((float) information[pointer++] / 10f);
|
}
|
break;
|
}
|
}
|
}
|
|
public static void getPixelsGraphic(VmsGeneral deviceclone, VmsGraphic graphic)
|
{
|
try
|
{
|
int pointer = 0;
|
int height = graphic.graphicContent[pointer++];
|
int width = graphic.graphicContent[pointer++];
|
|
if ((height == 0) && (width == 0))
|
{
|
// Not exist the graphic in Vms memory
|
// Return byte[0] and generate a black image
|
return;
|
}
|
|
if ((height == 78) && (width == 32))
|
{
|
height = 32;
|
}
|
|
int initialRow = graphic.graphicContent[pointer++];
|
int initialColumn = graphic.graphicContent[pointer++];
|
int colorAreas = graphic.graphicContent[pointer++];
|
int groupRows = height / 8;
|
boolean[] green = new boolean[height * width];
|
boolean[] red = new boolean[height * width];
|
boolean[] blue = new boolean[height * width];
|
|
for (int i = 0; i < height * width; i++)
|
{
|
green[i] = false;
|
red[i] = false;
|
blue[i] = false;
|
}
|
|
int pos = pointer;
|
int maxPosPixel = 0;
|
|
if (colorAreas > 0)
|
{
|
// GREEN
|
|
for (int i = 0; i < groupRows; i++)
|
{
|
for (int j = 0; j < width; j++)
|
{
|
byte byteCol = (byte) graphic.graphicContent[i * (width) + j + pos];
|
for (int k = 7; k >= 0; k--)
|
{
|
int bit = k;
|
|
int mask = (int) (java.lang.Math.pow(2.0, (double) bit));
|
|
int posPixel = (i * (8 * width)) + ((7 - k) * (width)) + j;
|
|
if (posPixel > maxPosPixel)
|
{
|
maxPosPixel = posPixel;
|
}
|
int value = byteCol & mask;
|
if (value != 0)
|
{
|
green[posPixel] = true;
|
}
|
}
|
}
|
}
|
|
pos = pos + (groupRows * width);
|
}
|
|
if (colorAreas > 1)
|
{
|
// RED
|
|
for (int i = 0; i < groupRows; i++)
|
{
|
for (int j = 0; j < width; j++)
|
{
|
byte byteCol = (byte) graphic.graphicContent[i * (width) + j + pos];
|
|
for (int k = 7; k >= 0; k--)
|
{
|
int bit = k;
|
|
int mask = (int) (java.lang.Math.pow(2.0, (double) bit));
|
|
int posPixel = (i * (8 * width)) + ((7 - k) * (width)) + j;
|
|
if (posPixel > maxPosPixel)
|
{
|
maxPosPixel = posPixel;
|
}
|
int value = byteCol & mask;
|
if (value != 0)
|
{
|
red[posPixel] = true;
|
}
|
}
|
}
|
}
|
|
pos = pos + (groupRows * width);
|
}
|
|
if (colorAreas > 2)
|
{
|
// BLUE
|
|
for (int i = 0; i < groupRows; i++)
|
{
|
for (int j = 0; j < width; j++)
|
{
|
byte byteCol = (byte) graphic.graphicContent[i * (width) + j + pos];
|
|
for (int k = 7; k >= 0; k--)
|
{
|
int bit = k;
|
|
int mask = (int) (java.lang.Math.pow(2.0, (double) bit));
|
|
int posPixel = (i * (8 * width)) + ((7 - k) * (width)) + j;
|
|
if (posPixel > maxPosPixel)
|
{
|
maxPosPixel = posPixel;
|
}
|
int value = byteCol & mask;
|
if (value != 0)
|
{
|
blue[posPixel] = true;
|
}
|
}
|
}
|
}
|
|
pos = pos + (groupRows * width);
|
}
|
|
graphic.pixels = new int[height * width];
|
for (int i = 0; i < height * width; i++)
|
{
|
if (colorAreas >= 3)
|
{
|
graphic.pixels[i] = getPixelColor(green[i], red[i], blue[i]);
|
} else
|
{
|
graphic.pixels[i] = getPixelColor(green[i], red[i]);
|
}
|
}
|
|
} catch (Exception e)
|
{
|
|
}
|
}
|
|
private static void checkAck(int[] information) throws Exception
|
{
|
if (ArrayUtils.isNullOrEmpty(information) || information[0] != AsfDgtConstants.ASF_ACK)
|
{
|
throw new Exception("No ack received");
|
}
|
}
|
|
private static void analyseFixState(Asf deviceclone, int[] information, int index) throws Exception
|
{
|
NumberUtils.AsciiToInt(information[index++]); //Topology
|
int numberOfSubpanels = NumberUtils.AsciiToInt(information[index++]);
|
int memory = -1;
|
boolean blinking = false;
|
|
for (int i = 0; i < numberOfSubpanels; i++)
|
{
|
int subpanel = NumberUtils.AsciiToInt(information[index++]);
|
|
if (subpanel == 1)
|
{
|
int contentType = NumberUtils.AsciiToInt(information[index++]);
|
if (contentType == 1)
|
{
|
// Graphic memory content
|
memory = information[index++];
|
//Blinking
|
blinking = (information[index++] == (int) 'S');
|
} else
|
{
|
throw new Exception("Not valid content");
|
}
|
} else
|
{
|
throw new Exception("Not valid content");
|
}
|
}
|
|
AsfStatus asfStatus = deviceclone.getDeviceStatus();
|
|
AsfInformationConfigurationAddressState addressState = deviceclone.getDeviceInformation().configuration.getByAddressBlinking(memory, blinking);
|
if (addressState == null || addressState.state < 0)
|
{
|
throw new Exception("Invalid address state");
|
}
|
|
asfStatus.state = addressState.state;
|
}
|
|
private static int getPixelColor(boolean green, boolean red, boolean blue)
|
{
|
try
|
{
|
if ((green == true) && (red == true) && (blue == true))
|
{
|
return (Color.WHITE.getRGB());
|
}
|
if ((green == true) && (red == true) && (blue == false))
|
{
|
return (Color.YELLOW.getRGB());
|
}
|
if ((green == false) && (red == true) && (blue == false))
|
{
|
return (Color.RED.getRGB());
|
}
|
if ((green == true) && (red == false) && (blue == false))
|
{
|
return (Color.GREEN.getRGB());
|
}
|
if ((green == false) && (red == false) && (blue == true))
|
{
|
return (Color.BLUE.getRGB());
|
}
|
if ((green == false) && (red == true) && (blue == true))
|
{
|
return (Color.MAGENTA.getRGB());
|
}
|
if ((green == true) && (red == false) && (blue == true))
|
{
|
return (Color.CYAN.getRGB());
|
}
|
} catch (Exception e)
|
{
|
}
|
|
return (Color.BLACK.getRGB());
|
}
|
|
private static int getPixelColor(boolean green, boolean red)
|
{
|
try
|
{
|
if ((green == true) && (red == true))
|
{
|
return (Color.YELLOW.getRGB());
|
}
|
if ((green == false) && (red == true))
|
{
|
return (Color.RED.getRGB());
|
}
|
if ((green == true) && (red == false))
|
{
|
return (Color.GREEN.getRGB());
|
}
|
} catch (Exception e)
|
{
|
}
|
|
return (Color.BLACK.getRGB());
|
}
|
|
}
|