All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bidib.wizard.simulation.OneDMXSimulator Maven / Gradle / Ivy

There is a newer version: 2.0.0-M1
Show newest version
package org.bidib.wizard.simulation;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.bidib.jbidibc.core.BidibLibrary;
import org.bidib.jbidibc.core.BidibPort;
import org.bidib.jbidibc.core.Feature;
import org.bidib.jbidibc.core.LcConfigX;
import org.bidib.jbidibc.core.LcMacro;
import org.bidib.jbidibc.core.enumeration.LcMacroOperationCode;
import org.bidib.jbidibc.core.enumeration.LcMacroState;
import org.bidib.jbidibc.core.enumeration.LcOutputType;
import org.bidib.jbidibc.core.enumeration.LightPortEnum;
import org.bidib.jbidibc.core.exception.ProtocolException;
import org.bidib.jbidibc.core.message.AccessoryGetMessage;
import org.bidib.jbidibc.core.message.AccessoryParaGetMessage;
import org.bidib.jbidibc.core.message.AccessoryParaResponse;
import org.bidib.jbidibc.core.message.AccessoryParaSetMessage;
import org.bidib.jbidibc.core.message.AccessorySetMessage;
import org.bidib.jbidibc.core.message.AccessoryStateResponse;
import org.bidib.jbidibc.core.message.BidibCommand;
import org.bidib.jbidibc.core.message.LcConfigGetMessage;
import org.bidib.jbidibc.core.message.LcConfigResponse;
import org.bidib.jbidibc.core.message.LcConfigSetMessage;
import org.bidib.jbidibc.core.message.LcConfigXGetAllMessage;
import org.bidib.jbidibc.core.message.LcConfigXGetMessage;
import org.bidib.jbidibc.core.message.LcConfigXResponse;
import org.bidib.jbidibc.core.message.LcConfigXSetMessage;
import org.bidib.jbidibc.core.message.LcMacroGetMessage;
import org.bidib.jbidibc.core.message.LcMacroHandleMessage;
import org.bidib.jbidibc.core.message.LcMacroParaGetMessage;
import org.bidib.jbidibc.core.message.LcMacroParaResponse;
import org.bidib.jbidibc.core.message.LcMacroParaSetMessage;
import org.bidib.jbidibc.core.message.LcMacroResponse;
import org.bidib.jbidibc.core.message.LcMacroSetMessage;
import org.bidib.jbidibc.core.message.LcMacroStateResponse;
import org.bidib.jbidibc.core.message.LcNotAvailableResponse;
import org.bidib.jbidibc.core.message.LcOutputMessage;
import org.bidib.jbidibc.core.message.LcOutputQueryMessage;
import org.bidib.jbidibc.core.message.LcStatResponse;
import org.bidib.jbidibc.core.node.MacroFunctionsNode;
import org.bidib.jbidibc.core.port.BytePortConfigValue;
import org.bidib.jbidibc.core.port.Int16PortConfigValue;
import org.bidib.jbidibc.core.port.PortConfigValue;
import org.bidib.jbidibc.core.utils.ByteUtils;
import org.bidib.jbidibc.core.utils.CollectionUtils;
import org.bidib.jbidibc.core.utils.MacroUtils;
import org.bidib.jbidibc.core.utils.MessageUtils;
import org.bidib.jbidibc.simulation.DmxNode;
import org.bidib.jbidibc.simulation.SwitchingFunctionsNode;
import org.bidib.jbidibc.simulation.net.SimulationBidibMessageProcessor;
import org.bidib.jbidibc.simulation.nodes.BacklightPortParamsType;
import org.bidib.jbidibc.simulation.nodes.BacklightPortType;
import org.bidib.jbidibc.simulation.nodes.DefaultNodeSimulator;
import org.bidib.jbidibc.simulation.nodes.DmxChannelParamsType;
import org.bidib.jbidibc.simulation.nodes.DmxChannelsType;
import org.bidib.jbidibc.simulation.nodes.LightPortParamsType;
import org.bidib.jbidibc.simulation.nodes.LightPortType;
import org.bidib.jbidibc.simulation.nodes.PortType;
import org.bidib.wizard.comm.BacklightPortStatus;
import org.bidib.wizard.comm.LightPortStatus;
import org.bidib.wizard.mvc.dmx.model.DmxChannel;
import org.bidib.wizard.mvc.dmx.model.DmxLightPort;
import org.bidib.wizard.mvc.main.model.BacklightPort;
import org.bidib.wizard.mvc.main.model.LightPort;
import org.bidib.wizard.mvc.main.model.Port;
import org.bidib.wizard.simulation.events.BacklightPortStatusEvent;
import org.bidib.wizard.simulation.events.LightPortStatusEvent;
import org.bidib.wizard.simulation.macro.MacroContainer;
import org.bushe.swing.event.EventBus;
import org.bushe.swing.event.annotation.AnnotationProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OneDMXSimulator extends DefaultNodeSimulator
    implements SwitchingFunctionsNode, MacroFunctionsNode, DmxNode {
    private static final Logger LOGGER = LoggerFactory.getLogger(OneDMXSimulator.class);

    private static final String SIMULATION_PANEL_CLASS = "org.bidib.wizard.mvc.simulation.view.panel.OneDMXPanel";

    private final Map lightPorts = new HashMap();

    private final Map backlightPorts = new HashMap();

    private final Map macros = new HashMap();

    private final Map dmxChannels = new HashMap();

    private int lightPortCount;

    private int backlightPortCount;

    public OneDMXSimulator(byte[] nodeAddress, long uniqueId, boolean autoAddFeature,
        SimulationBidibMessageProcessor messageReceiver) {
        super(nodeAddress, uniqueId, autoAddFeature, messageReceiver);
    }

    @Override
    protected void prepareFeatures() {
        LOGGER.info("Prepare the features.");
        super.prepareFeatures();

        features.add(new Feature(BidibLibrary.FEATURE_CTRL_LIGHT_COUNT, lightPortCount));
        features.add(new Feature(BidibLibrary.FEATURE_CTRL_BACKLIGHT_COUNT, backlightPortCount));

        features.add(new Feature(BidibLibrary.FEATURE_CTRL_PORT_QUERY_AVAILABLE, 1));

        features.add(new Feature(BidibLibrary.FEATURE_CTRL_STRETCH_DIMM, 100));

        features.add(new Feature(BidibLibrary.FEATURE_CTRL_MAC_COUNT, 32));
        features.add(new Feature(BidibLibrary.FEATURE_CTRL_MAC_SIZE, 30));
        features.add(new Feature(BidibLibrary.FEATURE_CTRL_MAC_SAVE, 32));
        features.add(new Feature(BidibLibrary.FEATURE_CTRL_MAC_LEVEL, 2));

        features.add(new Feature(BidibLibrary.FEATURE_ACCESSORY_COUNT, 8));
        features.add(new Feature(BidibLibrary.FEATURE_ACCESSORY_SURVEILLED, 0));
        features.add(new Feature(BidibLibrary.FEATURE_ACCESSORY_MACROMAPPED, 2));
    }

    @Override
    protected void prepareCVs() {

        super.prepareCVs();

        // don't restore accessory during startup
        configurationVariables.put(String.valueOf(31), String.valueOf(0));
    }

    @Override
    public String getSimulationPanelClass() {
        return SIMULATION_PANEL_CLASS;
    }

    @Override
    public void start() {
        LOGGER.info("Start the simulator for address: {}", getAddress());

        AnnotationProcessor.process(this);

        // prepare the light ports
        // setupLightPorts();

        // prepare the backlight ports
        // setupBacklightPorts();

        super.start();
    }

    @Override
    public void stop() {
        AnnotationProcessor.unprocess(this);
        super.stop();
    }

    // private void setupLightPorts() {
    // for (int id = 0; id < lightPortCount; id++) {
    // LightPort port = new LightPort();
    //
    // port.setId(id);
    // port.setStatus(id % 3 == 0 ? LightPortStatus.ON : LightPortStatus.OFF);
    //
    // lightPorts.put(id, port);
    // }
    // }

    // private void setupBacklightPorts() {
    // for (int id = 0; id < backlightPortCount; id++) {
    // BacklightPort port = new BacklightPort();
    //
    // port.setId(id);
    // port.setStatus(BacklightPortStatus.START);
    //
    // backlightPorts.put(id, port);
    // }
    // }

    @Override
    protected byte[] prepareResponse(BidibCommand bidibMessage) {

        byte[] response = null;
        switch (ByteUtils.getInt(bidibMessage.getType())) {
            case BidibLibrary.MSG_LC_OUTPUT:
                response = processLcOutputRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_CONFIG_GET:
                response = processLcConfigGetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_CONFIG_SET:
                response = processLcConfigSetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_OUTPUT_QUERY:
                response = processLcOutputQueryRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_CONFIGX_SET:
                response = processLcConfigXSetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_CONFIGX_GET:
                response = processLcConfigXGetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_CONFIGX_GET_ALL:
                processLcConfigXGetAllRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_MACRO_HANDLE:
                response = processLcMacroHandleRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_MACRO_PARA_GET:
                response = processLcMacroParaGetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_MACRO_PARA_SET:
                response = processLcMacroParaSetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_MACRO_GET:
                response = processLcMacroGetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_LC_MACRO_SET:
                response = processLcMacroSetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_ACCESSORY_SET:
                response = processAccessorySetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_ACCESSORY_GET:
                response = processAccessoryGetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_ACCESSORY_PARA_SET:
                response = processAccessoryParaSetRequest(bidibMessage);
                break;
            case BidibLibrary.MSG_ACCESSORY_PARA_GET:
                response = processAccessoryParaGetRequest(bidibMessage);
                break;
            default:
                response = super.prepareResponse(bidibMessage);
                break;
        }
        return response;
    }

    protected byte[] processLcOutputRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the LcOutput request: {}", bidibMessage);
        byte[] response = null;
        try {
            LcOutputMessage lcOutputMessage = (LcOutputMessage) bidibMessage;
            LcOutputType outputType = lcOutputMessage.getOutputType(getPortModel());
            int outputNumber = lcOutputMessage.getOutputNum(getPortModel());
            byte outputStatus = lcOutputMessage.getOutputStatus();

            Port port = null;
            switch (outputType) {
                case LIGHTPORT:
                    DmxLightPort dmxLightPort = lightPorts.get(Integer.valueOf(outputNumber));
                    dmxLightPort.getLightPort().setStatus(LightPortStatus.valueOf(LightPortEnum.valueOf(outputStatus)));
                    port = dmxLightPort.getLightPort();
                    break;
                case BACKLIGHTPORT:
                    BacklightPort backlightPort = backlightPorts.get(Integer.valueOf(outputNumber));
                    backlightPort.setValue(outputStatus, true);
                    port = backlightPort;
                    break;
                default:
                    LOGGER.warn("LcOutput request for unsupported port type detected: {}", outputType);
                    break;
            }

            BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);

            LcStatResponse lcStatResponse =
                new LcStatResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort,
                    lcOutputMessage.getOutputStatus());
            response = lcStatResponse.getContent();

            if (port != null) {
                switch (outputType) {
                    case LIGHTPORT:
                        publishLightPortChange(port);
                        break;
                    case BACKLIGHTPORT:
                        publishBacklightPortChange(port);
                        break;
                    default:
                        break;
                }
            }
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcStat response failed.", ex);
        }
        return response;
    }

    private void publishLightPortChange(Port port) {
        LightPort lightPort = (LightPort) port;
        LightPortStatus status = lightPort.getStatus();

        LOGGER.info("The lightport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
        EventBus.publish(new LightPortStatusEvent(ByteUtils.bytesToHex(nodeAddress), lightPort, status));
    }

    private void publishBacklightPortChange(Port port) {
        BacklightPort backlightPort = (BacklightPort) port;
        BacklightPortStatus status = backlightPort.getStatus();

        LOGGER.info("The backlightport status has changed, notify the listeners, nodeAddress: {}", nodeAddress);
        EventBus.publish(new BacklightPortStatusEvent(ByteUtils.bytesToHex(nodeAddress), backlightPort, status));
    }

    protected byte[] processLcConfigGetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the LcConfigGet request: {}", bidibMessage);
        byte[] response = null;

        try {
            LcConfigGetMessage lcConfigGetMessage = (LcConfigGetMessage) bidibMessage;
            LcOutputType outputType = lcConfigGetMessage.getPortType(getPortModel());
            int outputNumber = lcConfigGetMessage.getPortNumber(getPortModel());

            Port port = null;
            switch (outputType) {
                case LIGHTPORT:
                    port = lightPorts.get(Integer.valueOf(outputNumber));
                    break;
                case BACKLIGHTPORT:
                    port = backlightPorts.get(Integer.valueOf(outputNumber));
                    break;
                default:
                    LOGGER.warn("LcConfigGet request for unsupported port type detected: {}", outputType);
                    break;
            }

            LOGGER.info("Return config of port: {}", port);
            BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);

            LcConfigResponse lcConfigResponse =
                new LcConfigResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort, port.getPortConfig());
            response = lcConfigResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcConfig response failed.", ex);
        }
        return response;
    }

    protected byte[] processLcConfigSetRequest(BidibCommand bidibMessage) {

        LOGGER.info("Process the LcConfigSet request: {}", bidibMessage);
        byte[] response = null;
        try {
            LcConfigSetMessage lcConfigSetMessage = (LcConfigSetMessage) bidibMessage;
            LcOutputType outputType = lcConfigSetMessage.getPortType(getPortModel());
            int outputNumber = lcConfigSetMessage.getPortNumber(getPortModel());

            Port port = null;
            switch (outputType) {
                case LIGHTPORT:
                    DmxLightPort dmxLightPort = lightPorts.get(Integer.valueOf(outputNumber));
                    if (dmxLightPort != null) {
                        dmxLightPort.getLightPort().setPortConfig(lcConfigSetMessage.getPortConfig());
                        port = dmxLightPort;
                    }
                    else {
                        LOGGER.warn("Lightport not available, outputNumber: {}", outputNumber);
                    }
                    break;
                case BACKLIGHTPORT:
                    BacklightPort backlightPort = backlightPorts.get(Integer.valueOf(outputNumber));
                    if (backlightPort != null) {
                        backlightPort.setPortConfig(lcConfigSetMessage.getPortConfig());
                        port = backlightPort;
                    }
                    else {
                        LOGGER.warn("Backlightport not available, outputNumber: {}", outputNumber);
                    }
                    break;
                default:
                    LOGGER.warn("LcConfigSet request for unsupported port type detected: {}", outputType);
                    break;
            }

            BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);

            if (port == null) {
                LOGGER.warn("No port assigned!");
                LcNotAvailableResponse magicResponse =
                    new LcNotAvailableResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort);
                response = magicResponse.getContent();
            }
            else {
                LcConfigResponse magicResponse =
                    new LcConfigResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort, port.getPortConfig());
                response = magicResponse.getContent();
            }
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcConfigResponse response failed.", ex);
        }
        return response;
    }

    protected byte[] processLcConfigXSetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the LcConfigXSet request: {}", bidibMessage);
        byte[] response = null;
        try {
            LcConfigXSetMessage lcConfigXSetMessage = (LcConfigXSetMessage) bidibMessage;
            int outputNumber = lcConfigXSetMessage.getPortNumber(getPortModel());

            LcOutputType outputType = lcConfigXSetMessage.getPortType(getPortModel());

            Port port = null;
            switch (outputType) {
                case LIGHTPORT:
                    DmxLightPort dmxLightPort = lightPorts.get(Integer.valueOf(outputNumber));
                    if (dmxLightPort != null) {

                        dmxLightPort.getLightPort().setPortConfigX(lcConfigXSetMessage.getLcConfigX().getPortConfig());
                        port = dmxLightPort;
                    }
                    else {
                        LOGGER.warn("Lightport not available, outputNumber: {}", outputNumber);
                    }
                    break;
                case BACKLIGHTPORT:
                    BacklightPort backlightPort = backlightPorts.get(Integer.valueOf(outputNumber));
                    if (backlightPort != null) {

                        backlightPort.setPortConfigX(lcConfigXSetMessage.getLcConfigX().getPortConfig());
                        port = backlightPort;
                    }
                    else {
                        LOGGER.warn("Backlightport not available, outputNumber: {}", outputNumber);
                    }
                    break;
                default:
                    LOGGER.warn("LcConfigSet request for unsupported port type detected: {}", outputType);
                    break;
            }

            BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);

            if (port != null) {
                LcConfigX lcConfigX = new LcConfigX(bidibPort, lcConfigXSetMessage.getLcConfigX().getPortConfig());

                LcConfigXResponse lcConfigXResponse =
                    new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(), MessageUtils.getCodedPortConfig(
                        lcConfigX, getPortModel()));
                response = lcConfigXResponse.getContent();
            }
            else {
                LOGGER.warn("No port assigned!");
                LcNotAvailableResponse magicResponse =
                    new LcNotAvailableResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort);
                response = magicResponse.getContent();
            }
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcConfigX response failed.", ex);
        }
        return response;
    }

    protected byte[] processLcConfigXGetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the LcConfigXGet request: {}", bidibMessage);
        byte[] response = null;

        try {
            LcConfigXGetMessage lcConfigXGetMessage = (LcConfigXGetMessage) bidibMessage;
            int outputNumber = lcConfigXGetMessage.getPortNumber(getPortModel());
            LcOutputType lcOutputType = lcConfigXGetMessage.getPortType(getPortModel());
            Port port = null;
            Map> values = new LinkedHashMap<>();
            switch (lcOutputType) {
                case LIGHTPORT:
                    port = lightPorts.get(Integer.valueOf(outputNumber));
                    // portConfig = port.getPortConfig();
                    LightPort lightPort = ((DmxLightPort) port).getLightPort();
                    values.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_ON,
                        new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getPwmMax())));
                    values.put(BidibLibrary.BIDIB_PCFG_LEVEL_PORT_OFF,
                        new BytePortConfigValue(ByteUtils.getLowByte(lightPort.getPwmMin())));
                    values.put(BidibLibrary.BIDIB_PCFG_DIMM_UP_8_8, new Int16PortConfigValue(lightPort.getDimMax()));
                    values.put(BidibLibrary.BIDIB_PCFG_DIMM_DOWN_8_8, new Int16PortConfigValue(lightPort.getDimMin()));
                    break;
                case BACKLIGHTPORT:
                    port = backlightPorts.get(Integer.valueOf(outputNumber));
                    // portConfig = port.getPortConfig();
                    BacklightPort backlightPort = (BacklightPort) port;
                    values.put(BidibLibrary.BIDIB_PCFG_DIMM_UP_8_8,
                        new Int16PortConfigValue(backlightPort.getDimSlopeUp()));
                    values.put(BidibLibrary.BIDIB_PCFG_DIMM_DOWN_8_8,
                        new Int16PortConfigValue(backlightPort.getDimSlopeDown()));
                    values.put(BidibLibrary.BIDIB_PCFG_OUTPUT_MAP,
                        new BytePortConfigValue(ByteUtils.getLowByte(backlightPort.getDmxMapping())));
                    break;
                default:
                    LOGGER.warn("LcConfigGet request for unsupported port type detected: {}", lcOutputType);
                    break;
            }

            LOGGER.info("Return config of port: {}", port);
            BidibPort bidibPort = prepareBidibPort(getPortModel(), lcOutputType, outputNumber);
            LcConfigX lcConfigX = new LcConfigX(bidibPort, values);

            LcConfigXResponse lcConfigXResponse =
                new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(), MessageUtils.getCodedPortConfig(
                    lcConfigX, getPortModel()));
            response = lcConfigXResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcConfigX response failed.", ex);
        }
        return response;
    }

    protected void processLcConfigXGetAllRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the LcConfigXGetAll request: {}", bidibMessage);
        byte[] response = null;

        try {
            LcConfigXGetAllMessage lcConfigXGetAllMessage = (LcConfigXGetAllMessage) bidibMessage;
            LcOutputType lcOutputType = lcConfigXGetAllMessage.getPortTypeFrom(getPortModel());

            // TODO evaluate port type/range to

            Map> values = new LinkedHashMap<>();

            if (lcOutputType != null) {
                LOGGER.info("Get all ports for output type: {}", lcOutputType);

                switch (lcOutputType) {
                    case LIGHTPORT:
                        for (DmxLightPort lightPort : lightPorts.values()) {
                            values.clear();

                            LOGGER.info("Return config of light port: {}", lightPort);
                            BidibPort bidibPort = prepareBidibPort(getPortModel(), lcOutputType, lightPort.getId());
                            LcConfigX lcConfigX = new LcConfigX(bidibPort, values);

                            LcConfigXResponse lcConfigXResponse =
                                new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
                                    MessageUtils.getCodedPortConfig(lcConfigX, getPortModel()));
                            response = lcConfigXResponse.getContent();

                            LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
                            sendSpontanousResponse(response);
                            response = null;
                        }
                        break;
                    case BACKLIGHTPORT:
                        for (BacklightPort backlightPort : backlightPorts.values()) {
                            values.clear();

                            LOGGER.info("Return config of backlight port: {}", backlightPort);
                            BidibPort bidibPort = prepareBidibPort(getPortModel(), lcOutputType, backlightPort.getId());
                            LcConfigX lcConfigX = new LcConfigX(bidibPort, values);

                            LcConfigXResponse lcConfigXResponse =
                                new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
                                    MessageUtils.getCodedPortConfig(lcConfigX, getPortModel()));
                            response = lcConfigXResponse.getContent();

                            LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
                            sendSpontanousResponse(response);
                            response = null;
                        }
                        break;
                    default:
                        LOGGER.warn("Unsupported port type requested: {}", lcOutputType);
                        break;
                }
            }
            else {
                // deliver light ports
                for (DmxLightPort lightPort : lightPorts.values()) {
                    values.clear();

                    LOGGER.info("Return config of light port: {}", lightPort);
                    BidibPort bidibPort = prepareBidibPort(getPortModel(), lcOutputType, lightPort.getId());
                    LcConfigX lcConfigX = new LcConfigX(bidibPort, values);

                    LcConfigXResponse lcConfigXResponse =
                        new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
                            MessageUtils.getCodedPortConfig(lcConfigX, getPortModel()));
                    response = lcConfigXResponse.getContent();

                    LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
                    sendSpontanousResponse(response);
                    response = null;
                }

                // deliver backlight ports
                for (BacklightPort backlightPort : backlightPorts.values()) {
                    values.clear();

                    LOGGER.info("Return config of backlight port: {}", backlightPort);
                    BidibPort bidibPort = prepareBidibPort(getPortModel(), lcOutputType, backlightPort.getId());
                    LcConfigX lcConfigX = new LcConfigX(bidibPort, values);

                    LcConfigXResponse lcConfigXResponse =
                        new LcConfigXResponse(bidibMessage.getAddr(), getNextSendNum(),
                            MessageUtils.getCodedPortConfig(lcConfigX, getPortModel()));
                    response = lcConfigXResponse.getContent();

                    LOGGER.info("Prepared lcConfigXResponse: {}", ByteUtils.bytesToHex(response));
                    sendSpontanousResponse(response);
                    response = null;
                }
            }
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create lcConfigXResponse response failed.", ex);
        }

    }

    protected byte[] processLcOutputQueryRequest(BidibCommand bidibMessage) {

        LOGGER.info("Process the LcOutputQuery request: {}", bidibMessage);
        byte[] response = null;

        byte portState = 0;

        try {
            LcOutputQueryMessage lcOutputQueryMessage = (LcOutputQueryMessage) bidibMessage;
            LcOutputType outputType = lcOutputQueryMessage.getPortType(getPortModel());
            int outputNumber = lcOutputQueryMessage.getPortNumber(getPortModel());
            LOGGER.info("Get port with portNumber: {}", outputNumber);

            switch (outputType) {
                case LIGHTPORT:
                    portState = lightPorts.get(outputNumber).getStatus().getType().getType();
                    break;
                case BACKLIGHTPORT:
                    portState = backlightPorts.get(outputNumber).getStatus().getType().getType();
                    break;
                default:
                    LOGGER.warn("LcOutputQuery for unsupported port type detected: {}", outputType);
                    break;
            }
            BidibPort bidibPort = prepareBidibPort(getPortModel(), outputType, outputNumber);

            LcStatResponse lcStatResponse =
                new LcStatResponse(bidibMessage.getAddr(), getNextSendNum(), bidibPort, portState);
            response = lcStatResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcStat response failed.", ex);
        }
        return response;
    }

    protected byte[] processLcMacroParaGetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the LcMacroParaGet request: {}", bidibMessage);
        byte[] response = null;

        try {
            LcMacroParaGetMessage lcMacroParaGetMessage = (LcMacroParaGetMessage) bidibMessage;
            int macroNumber = lcMacroParaGetMessage.getMacroNumber();
            int paramId = lcMacroParaGetMessage.getParameterIndex();
            LOGGER.info("Process macroNumber: {}, paramId: {}", macroNumber, paramId);

            // return the stored parameter value
            MacroContainer container = macros.get(macroNumber);
            if (container == null) {
                LOGGER.info("Create new MacroContainer for macro number: {}", macroNumber);
                // initialize a new macro container
                container = new MacroContainer(macroNumber);
                macros.put(macroNumber, container);
            }
            byte[] parameter = container.getMacroParameter(paramId);

            LcMacroParaResponse lcMacroParaResponse =
                new LcMacroParaResponse(bidibMessage.getAddr(), getNextSendNum(), (byte) macroNumber, (byte) paramId,
                    parameter);
            response = lcMacroParaResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcMacroPara response failed.", ex);
        }
        return response;
    }

    protected byte[] processLcMacroParaSetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the LcMacroParaSet request: {}", bidibMessage);
        byte[] response = null;

        try {
            LcMacroParaSetMessage lcMacroParaSetMessage = (LcMacroParaSetMessage) bidibMessage;
            int macroNumber = lcMacroParaSetMessage.getMacroNumber();
            int paramId = lcMacroParaSetMessage.getParameterIndex();
            byte[] parameter = lcMacroParaSetMessage.getValue();

            // store the parameter value
            MacroContainer container = macros.get(macroNumber);
            if (container == null) {
                // initialize a new macro container
                container = new MacroContainer(macroNumber);
                macros.put(macroNumber, container);
            }
            container.setMacroParameter(paramId, parameter);

            LcMacroParaResponse lcMacroParaResponse =
                new LcMacroParaResponse(bidibMessage.getAddr(), getNextSendNum(), (byte) macroNumber, (byte) paramId,
                    parameter);
            response = lcMacroParaResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcMacroPara response failed.", ex);
        }
        return response;
    }

    protected byte[] processLcMacroHandleRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the LcMacroHandle request: {}", bidibMessage);
        byte[] response = null;

        try {
            LcMacroHandleMessage lcMacroHandleMessage = (LcMacroHandleMessage) bidibMessage;
            Integer macroNumber = lcMacroHandleMessage.getMacroNumber();
            LcMacroOperationCode lcMacroOperationCode = lcMacroHandleMessage.getMacroOperationCode();

            LOGGER.info("Handle macro request, macroNumber: {}, lcMacroOperationCode: {}", macroNumber,
                lcMacroOperationCode);

            // TODO store the macro state value
            LcMacroState macroState = null;
            switch (lcMacroOperationCode) {
                case START:
                    macroState = LcMacroState.RUNNING;
                    break;
                case DELETE:
                    macroState = LcMacroState.DELETE;
                    LOGGER.info("Remove macro with number: {}", macroNumber);
                    macros.remove(macroNumber);
                    break;
                case OFF:
                    macroState = LcMacroState.OFF;
                    break;
                case RESTORE:
                    macroState = LcMacroState.RESTORE;
                    break;
                case SAVE:
                    macroState = LcMacroState.SAVE;
                    break;
                default:
                    macroState = LcMacroState.NOTEXIST;
                    break;
            }

            LcMacroStateResponse lcMacroStateResponse =
                new LcMacroStateResponse(bidibMessage.getAddr(), getNextSendNum(), ByteUtils.getLowByte(macroNumber),
                    macroState);
            response = lcMacroStateResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcMacroState response failed.", ex);
        }
        return response;
    }

    protected byte[] processLcMacroGetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the LcMacroGet request: {}", bidibMessage);
        byte[] response = null;

        try {
            LcMacroGetMessage lcMacroGetMessage = (LcMacroGetMessage) bidibMessage;
            Integer macroNumber = lcMacroGetMessage.getMacroNumber();
            int stepNumber = lcMacroGetMessage.getStep();

            // fetch the macro content and test if the macro is available
            MacroContainer container = macros.get(macroNumber);
            if (container == null) {
                // initialize a new macro container
                container = new MacroContainer(macroNumber);
                macros.put(macroNumber, container);
            }
            LcMacro macroStep = container.getMacroStep(stepNumber);

            LcMacro value = macroStep;

            LcMacroResponse lcMacroResponse =
                new LcMacroResponse(bidibMessage.getAddr(), getNextSendNum(), ByteUtils.getLowByte(macroNumber),
                    ByteUtils.getLowByte(stepNumber), value);
            response = lcMacroResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcMacro response failed.", ex);
        }
        return response;
    }

    protected byte[] processLcMacroSetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the LcMacroSet request: {}", bidibMessage);
        byte[] response = null;

        try {
            LcMacroSetMessage lcMacroSetMessage = (LcMacroSetMessage) bidibMessage;
            int macroNumber = lcMacroSetMessage.getMacroNumber();
            int stepNumber = lcMacroSetMessage.getStep();

            LcMacro macroStep = MacroUtils.getMacro(this, lcMacroSetMessage.getData());
            LOGGER.info("Current macroNumber: {}, stepNumber: {}, macroStep: {}", macroNumber, stepNumber, macroStep);

            // fetch the macro content and test if the macro container is available
            MacroContainer container = macros.get(macroNumber);
            if (container == null) {
                container = new MacroContainer(macroNumber);
                macros.put(macroNumber, container);
            }
            container.setMacroStep(stepNumber, macroStep);
            try {
                LcMacroResponse lcMacroResponse =
                    new LcMacroResponse(bidibMessage.getAddr(), getNextSendNum(), ByteUtils.getLowByte(macroNumber),
                        ByteUtils.getLowByte(stepNumber), macroStep);
                response = lcMacroResponse.getContent();
            }
            catch (NullPointerException npe) {
                LOGGER.warn("create response failed.", npe);
            }
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create LcMacro response failed.", ex);
        }
        return response;
    }

    protected byte[] processAccessorySetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the AccessorySet request: {}", bidibMessage);
        byte[] response = null;

        try {
            AccessorySetMessage accessorySetMessage = (AccessorySetMessage) bidibMessage;
            int accessoryNumber = accessorySetMessage.getAccessoryNumber();
            int aspect = accessorySetMessage.getAspect();

            byte[] value = new byte[] { 0, 0, 0 };

            AccessoryStateResponse accessoryStateResponse =
                new AccessoryStateResponse(bidibMessage.getAddr(), getNextSendNum(), (byte) accessoryNumber,
                    (byte) aspect, value);
            response = accessoryStateResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create AccessoryState response failed.", ex);
        }
        return response;
    }

    protected byte[] processAccessoryGetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the AccessoryGet request: {}", bidibMessage);
        byte[] response = null;

        try {
            AccessoryGetMessage accessoryGetMessage = (AccessoryGetMessage) bidibMessage;
            int accessoryNumber = accessoryGetMessage.getAccessoryNumber();
            int aspect = 0;
            byte[] value = new byte[] { 0, 0, 0 };

            AccessoryStateResponse accessoryStateResponse =
                new AccessoryStateResponse(bidibMessage.getAddr(), getNextSendNum(), (byte) accessoryNumber,
                    (byte) aspect, value);
            response = accessoryStateResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create AccessoryState response failed.", ex);
        }
        return response;
    }

    protected byte[] processAccessoryParaSetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the AccessoryParaSet request: {}", bidibMessage);
        byte[] response = null;

        try {
            AccessoryParaSetMessage accessoryParaSetMessage = (AccessoryParaSetMessage) bidibMessage;
            int accessoryNumber = accessoryParaSetMessage.getAccessoryNumber();
            int paraNumber = accessoryParaSetMessage.getParaNumber();

            byte[] value = accessoryParaSetMessage.getValue();

            AccessoryParaResponse accessoryParaResponse =
                new AccessoryParaResponse(bidibMessage.getAddr(), getNextSendNum(),
                    ByteUtils.getLowByte(accessoryNumber), ByteUtils.getLowByte(paraNumber), value);
            response = accessoryParaResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create AccessoryPara response failed.", ex);
        }
        return response;
    }

    protected byte[] processAccessoryParaGetRequest(BidibCommand bidibMessage) {
        LOGGER.info("Process the AccessoryParaGet request: {}", bidibMessage);
        byte[] response = null;

        try {
            AccessoryParaGetMessage accessoryParaGetMessage = (AccessoryParaGetMessage) bidibMessage;
            int accessoryNumber = accessoryParaGetMessage.getAccessoryNumber();
            int paraNumber = accessoryParaGetMessage.getParaNumber();

            // TODO provide the correct data here ...
            byte[] value = new byte[] { 0, 0, 0, 0 };

            AccessoryParaResponse accessoryParaResponse =
                new AccessoryParaResponse(bidibMessage.getAddr(), getNextSendNum(),
                    ByteUtils.getLowByte(accessoryNumber), ByteUtils.getLowByte(paraNumber), value);
            response = accessoryParaResponse.getContent();
        }
        catch (ProtocolException ex) {
            LOGGER.warn("Create AccessoryPara response failed.", ex);
        }
        return response;
    }

    @Override
    public void queryStatus(Class portClass) {
        if (LightPort.class.equals(portClass)) {
            for (DmxLightPort lightPort : lightPorts.values()) {
                publishLightPortChange(lightPort.getLightPort());
            }
        }
        else if (BacklightPort.class.equals(portClass)) {
            for (BacklightPort backlightPort : backlightPorts.values()) {
                publishBacklightPortChange(backlightPort);
            }
        }
    }

    @Override
    public void setPortsConfig(PortType portType) {
        if (portType == null) {
            return;
        }

        if (portType instanceof LightPortType) {
            LightPortType lightPortType = (LightPortType) portType;
            lightPortCount = lightPortType.getCount();
            LOGGER.info("Total number of lightports: {}", lightPortCount);

            // prepare initial lightports
            for (int portId = 0; portId < lightPortCount; portId++) {

                LightPort lightPort = new LightPort();
                lightPort.setId(portId);
                DmxLightPort dmxLightPort = new DmxLightPort(lightPort);

                // add the unconfigured lightport
                lightPorts.put(dmxLightPort.getId(), dmxLightPort);
            }

            // overwrite configured ports
            if (CollectionUtils.hasElements(lightPortType.getPort())) {
                final int cvBaseOffset = 215 /* offset */;
                // evaluate the configured ports
                for (LightPortParamsType portParams : lightPortType.getPort()) {
                    LightPort lightPort = new LightPort();
                    lightPort.setId(portParams.getPortId());
                    lightPort.setDimMin(portParams.getDimSlopeDown());
                    lightPort.setDimMax(portParams.getDimSlopeUp());
                    lightPort.setPwmMax(portParams.getIntensityOn());
                    lightPort.setPwmMin(portParams.getIntensityOff());

                    lightPort.setStatus(LightPortStatus.OFF);

                    DmxLightPort dmxLightPort = new DmxLightPort(lightPort);

                    DmxChannel dmxChannel = dmxChannels.get(portParams.getDmxMapping());
                    dmxLightPort.setDmxTargetChannel(dmxChannel);

                    LOGGER.info("Add configured port: {}", lightPort);

                    // add the configured port
                    lightPorts.put(dmxLightPort.getId(), dmxLightPort);

                    // prepare the CVs
                    int cvOffset = cvBaseOffset + portParams.getPortId() * 7 /* next */;
                    if (dmxLightPort.getDmxTargetChannel() != null) {
                        configurationVariables
                            .put(String.valueOf(cvOffset), String.valueOf(portParams.getDmxMapping()));
                    }
                    else {
                        configurationVariables.put(String.valueOf(cvOffset), String.valueOf(-1));
                    }
                    configurationVariables.put(String.valueOf(cvOffset + 1), String.valueOf(lightPort.getPwmMin()));
                    configurationVariables.put(String.valueOf(cvOffset + 2), String.valueOf(lightPort.getPwmMax()));
                    configurationVariables.put(String.valueOf(cvOffset + 3),
                        String.valueOf(ByteUtils.getLowByte(lightPort.getDimMin())));
                    configurationVariables.put(String.valueOf(cvOffset + 4),
                        String.valueOf(ByteUtils.getHighByte(lightPort.getDimMin())));
                    configurationVariables.put(String.valueOf(cvOffset + 5),
                        String.valueOf(ByteUtils.getLowByte(lightPort.getDimMax())));
                    configurationVariables.put(String.valueOf(cvOffset + 6),
                        String.valueOf(ByteUtils.getHighByte(lightPort.getDimMax())));
                }

                // use the number of configured ports
                lightPortCount = lightPorts.size();
            }
        }
        else if (portType instanceof BacklightPortType) {
            BacklightPortType backlightPortType = (BacklightPortType) portType;
            backlightPortCount = portType.getCount();
            LOGGER.info("Total number of backlight ports: {}", backlightPortCount);

            // prepare initial backlight ports
            for (int portId = 0; portId < backlightPortCount; portId++) {

                BacklightPort backlightPort = new BacklightPort();
                backlightPort.setId(portId);

                // add the unconfigured backlight port
                backlightPorts.put(backlightPort.getId(), backlightPort);
            }

            // overwrite configured ports
            if (CollectionUtils.hasElements(backlightPortType.getPort())) {
                final int cvBaseOffset = 1111 /* offset */;
                // evaluate the configured ports
                for (BacklightPortParamsType portParams : backlightPortType.getPort()) {
                    BacklightPort backlightPort = new BacklightPort();
                    backlightPort.setId(portParams.getPortId());
                    backlightPort.setDmxMapping(portParams.getDmxMapping());
                    backlightPort.setDimSlopeDown(portParams.getDimSlopeDown());
                    backlightPort.setDimSlopeUp(portParams.getDimSlopeUp());

                    backlightPort.setStatus(BacklightPortStatus.START);

                    LOGGER.info("Add configured port: {}", backlightPort);

                    // add the configured port
                    backlightPorts.put(backlightPort.getId(), backlightPort);

                    // prepare the CVs
                    int cvOffset = cvBaseOffset + portParams.getPortId() * 5 /* next */;
                    // target channel
                    configurationVariables.put(String.valueOf(cvOffset), String.valueOf(backlightPort.getDmxMapping()));
                    // dimm slope down
                    configurationVariables.put(String.valueOf(cvOffset + 1),
                        String.valueOf(ByteUtils.getLowByte(backlightPort.getDimSlopeDown())));
                    configurationVariables.put(String.valueOf(cvOffset + 2),
                        String.valueOf(ByteUtils.getHighByte(backlightPort.getDimSlopeDown())));
                    configurationVariables.put(String.valueOf(cvOffset + 3),
                        String.valueOf(ByteUtils.getLowByte(backlightPort.getDimSlopeUp())));
                    configurationVariables.put(String.valueOf(cvOffset + 4),
                        String.valueOf(ByteUtils.getHighByte(backlightPort.getDimSlopeUp())));
                }

                // use the number of configured ports
                backlightPortCount = backlightPorts.size();
            }
        }
    }

    @Override
    public void setDmxConfig(DmxChannelsType dmxChannelType) {
        LOGGER.info("Prepare the DMX channels.");

        if (dmxChannelType.getCount() != null) {
            // initialize all channels with '0'
            int cvOffset = 71 /* offset */;
            for (int channelId = 0; channelId < dmxChannelType.getCount().intValue(); channelId++) {
                configurationVariables.put(String.valueOf(cvOffset + channelId), String.valueOf(0));

                // the DMX channelId starts from 1
                DmxChannel dmxChannel = new DmxChannel(channelId + 1);
                dmxChannel.setInitialState(0);
                dmxChannels.put(channelId, dmxChannel);
            }
        }

        if (CollectionUtils.hasElements(dmxChannelType.getChannel())) {
            // override with values from xml file
            int cvOffset = 71 /* offset */;

            // get the configured initial values
            for (DmxChannelParamsType dmxChannelParams : dmxChannelType.getChannel()) {
                int dmxChannelId = dmxChannelParams.getChannelId();

                if (dmxChannelId > 0 && dmxChannelId < 65) {
                    DmxChannel dmxChannel = new DmxChannel(dmxChannelId);
                    dmxChannel.setInitialState(dmxChannelParams.getInitialState());

                    dmxChannels.put(dmxChannelParams.getChannelId(), dmxChannel);

                    // -1 because dmxChannelId starts from 1 but we have the offset from cvOffset start from 0
                    configurationVariables.put(String.valueOf(cvOffset + dmxChannelId - 1),
                        String.valueOf(dmxChannelParams.getInitialState()));
                }
                else {
                    LOGGER.warn("Current DMX channelId is out of range: {}", dmxChannelId);
                }
            }
        }
    }

    @Override
    public boolean isPortFlatModelAvailable() {
        return false;
    }

    @Override
    public LcOutputType getPortType(BidibPort bidibPort) {
        return null;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy