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

org.bidib.wizard.utils.NodeUtils Maven / Gradle / Ivy

There is a newer version: 2.0.29
Show newest version
package org.bidib.wizard.utils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.bidib.jbidibc.core.node.ConfigurationVariable;
import org.bidib.jbidibc.core.schema.BidibFactory;
import org.bidib.jbidibc.core.schema.bidib2.Accessories;
import org.bidib.jbidibc.core.schema.bidib2.Aspect;
import org.bidib.jbidibc.core.schema.bidib2.Aspects;
import org.bidib.jbidibc.core.schema.bidib2.BiDiB;
import org.bidib.jbidibc.core.schema.bidib2.ConfigurationVariables;
import org.bidib.jbidibc.core.schema.bidib2.Features;
import org.bidib.jbidibc.core.schema.bidib2.FeedbackPorts;
import org.bidib.jbidibc.core.schema.bidib2.Flags;
import org.bidib.jbidibc.core.schema.bidib2.HourExtension;
import org.bidib.jbidibc.core.schema.bidib2.IOInputBehaviour;
import org.bidib.jbidibc.core.schema.bidib2.IOSwitchBehaviour;
import org.bidib.jbidibc.core.schema.bidib2.InputKey;
import org.bidib.jbidibc.core.schema.bidib2.LoadType;
import org.bidib.jbidibc.core.schema.bidib2.MacroParameter;
import org.bidib.jbidibc.core.schema.bidib2.MacroParameterClockStart;
import org.bidib.jbidibc.core.schema.bidib2.MacroParameterRepeat;
import org.bidib.jbidibc.core.schema.bidib2.MacroParameterSlowdown;
import org.bidib.jbidibc.core.schema.bidib2.MacroParameters;
import org.bidib.jbidibc.core.schema.bidib2.MacroPoint;
import org.bidib.jbidibc.core.schema.bidib2.MacroPoints;
import org.bidib.jbidibc.core.schema.bidib2.Macros;
import org.bidib.jbidibc.core.schema.bidib2.MinuteExtension;
import org.bidib.jbidibc.core.schema.bidib2.Nodes;
import org.bidib.jbidibc.core.schema.bidib2.OutputBacklight;
import org.bidib.jbidibc.core.schema.bidib2.OutputLight;
import org.bidib.jbidibc.core.schema.bidib2.OutputMotor;
import org.bidib.jbidibc.core.schema.bidib2.OutputServo;
import org.bidib.jbidibc.core.schema.bidib2.OutputSound;
import org.bidib.jbidibc.core.schema.bidib2.OutputSwitch;
import org.bidib.jbidibc.core.schema.bidib2.OutputSwitchPair;
import org.bidib.jbidibc.core.schema.bidib2.Ports;
import org.bidib.jbidibc.core.schema.bidib2.Weekday;
import org.bidib.jbidibc.core.schema.bidib2.WeekdayExtension;
import org.bidib.jbidibc.core.schema.bidibbase.BaseLabel;
import org.bidib.jbidibc.core.schema.bidiblabels.AccessoryLabel;
import org.bidib.jbidibc.core.schema.bidiblabels.NodeLabels;
import org.bidib.jbidibc.exchange.vendorcv.ModeType;
import org.bidib.jbidibc.messages.BidibLibrary;
import org.bidib.jbidibc.messages.Feature;
import org.bidib.jbidibc.messages.StringData;
import org.bidib.jbidibc.messages.enums.CurveFormEnum;
import org.bidib.jbidibc.messages.enums.IoBehaviourInputEnum;
import org.bidib.jbidibc.messages.enums.IoBehaviourSwitchEnum;
import org.bidib.jbidibc.messages.enums.LcOutputType;
import org.bidib.jbidibc.messages.enums.LoadTypeEnum;
import org.bidib.jbidibc.messages.port.PortConfigValue;
import org.bidib.jbidibc.messages.port.ReconfigPortConfigValue;
import org.bidib.jbidibc.messages.utils.ByteUtils;
import org.bidib.wizard.api.context.ApplicationContext;
import org.bidib.wizard.api.model.Accessory;
import org.bidib.wizard.api.model.Flag;
import org.bidib.wizard.api.model.Macro;
import org.bidib.wizard.api.model.MacroRef;
import org.bidib.wizard.api.model.MacroRepeatDay;
import org.bidib.wizard.api.model.MacroRepeatTime;
import org.bidib.wizard.api.model.MacroSaveState;
import org.bidib.wizard.api.model.NodeInterface;
import org.bidib.wizard.api.model.StartCondition;
import org.bidib.wizard.api.model.TimeStartCondition;
import org.bidib.wizard.api.model.function.EmptyFunction;
import org.bidib.wizard.api.model.function.Function;
import org.bidib.wizard.api.service.node.NodeService;
import org.bidib.wizard.api.service.node.SwitchingNodeService;
import org.bidib.wizard.api.utils.AccessoryListUtils;
import org.bidib.wizard.api.utils.PortListUtils;
import org.bidib.wizard.client.common.view.cvdef.CvContainer;
import org.bidib.wizard.client.common.view.cvdef.CvDefinitionTreeHelper;
import org.bidib.wizard.client.common.view.cvdef.CvDefinitionTreeModelRegistry;
import org.bidib.wizard.client.common.view.cvdef.CvDefinitionTreeTableModel;
import org.bidib.wizard.client.common.view.cvdef.CvNode;
import org.bidib.wizard.common.context.DefaultApplicationContext;
import org.bidib.wizard.common.labels.AccessoryLabelUtils;
import org.bidib.wizard.common.labels.BidibLabelUtils;
import org.bidib.wizard.common.labels.WizardLabelFactory;
import org.bidib.wizard.common.labels.WizardLabelWrapper;
import org.bidib.wizard.common.utils.FlagListUtils;
import org.bidib.wizard.common.utils.MacroListUtils;
import org.bidib.wizard.core.model.connection.ConnectionRegistry;
import org.bidib.wizard.model.ports.AnalogPort;
import org.bidib.wizard.model.ports.BacklightPort;
import org.bidib.wizard.model.ports.FeedbackPort;
import org.bidib.wizard.model.ports.GenericPort;
import org.bidib.wizard.model.ports.InputPort;
import org.bidib.wizard.model.ports.LightPort;
import org.bidib.wizard.model.ports.MotorPort;
import org.bidib.wizard.model.ports.Port;
import org.bidib.wizard.model.ports.ServoPort;
import org.bidib.wizard.model.ports.SoundPort;
import org.bidib.wizard.model.ports.SwitchPairPort;
import org.bidib.wizard.model.ports.SwitchPort;
import org.bidib.wizard.model.status.BidibStatus;
import org.bidib.wizard.mvc.main.controller.CvDefinitionPanelController;
import org.bidib.wizard.mvc.main.view.component.SaveNodeConfigurationDialog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NodeUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(NodeUtils.class);

    public static final String IMPORT_ERRORS = "importErrors";

    /**
     * Find a node by its node uuid in the provided list of nodes.
     * 
     * @param nodes
     *            the list of nodes
     * @param uuid
     *            the uuid of the node to find
     * @return the found node or null if no node was found with the provided node uuid
     */
    public static NodeInterface findNodeByUuid(Iterable nodes, final long uuid) {
        NodeInterface node = IterableUtils.find(nodes, new Predicate() {

            @Override
            public boolean evaluate(final NodeInterface node) {
                if (node.getUniqueId() == uuid) {
                    LOGGER.debug("Found node: {}", node);
                    return true;
                }
                return false;
            }
        });
        return node;
    }

    /**
     * Prepare the node label based on the user string with fallback to node.toString().
     * 
     * @param node
     *            the node
     * @return the node label
     */
    public static String prepareLabel(final NodeInterface node) {
        String nodeLabel = null;

        if (node != null) {
            if (node.getNode().hasStoredStrings()) {
                // the node has stored strings, prepare the label with the stored strings
                String userString = node.getNode().getStoredString(StringData.INDEX_USERNAME);
                if (StringUtils.isNotBlank(userString)) {
                    // user string is available
                    String label = node.toString();
                    if (label.startsWith(userString)) {
                        nodeLabel = label;
                    }
                    else {
                        nodeLabel = userString;
                    }
                }
            }
            if (StringUtils.isBlank(nodeLabel)) {
                nodeLabel = node.toString();
            }
        }
        return nodeLabel;
    }

    /**
     * Configure the node from the provided BiDiB data.
     * 
     * @param node
     *            the node
     * @param bidib
     *            the BiDiB data
     * @return the configured node
     */
    public static NodeInterface configureFromBiDiB(
        String connectionId, final NodeService nodeService, final SwitchingNodeService switchingNodeService,
        CvDefinitionTreeModelRegistry cvDefinitionTreeModelRegistry, final NodeInterface node,
        final Map importParams, final BiDiB bidib, final WizardLabelWrapper wizardLabelWrapper,
        boolean restoreCVs, boolean restoreFeatures, boolean restoreNodeString, boolean restoreMacroContent,
        boolean restoreAccessoryContent) {
        if (bidib == null) {
            throw new IllegalArgumentException("A bidib must be provided.");
        }

        Nodes nodes = bidib.getNodes();

        if (nodes != null && CollectionUtils.isNotEmpty(nodes.getNode())) {

            List schemaNodes = nodes.getNode();
            for (org.bidib.jbidibc.core.schema.bidib2.Node schemaNode : schemaNodes) {

                final NodeLabels nodeLabels = wizardLabelWrapper.getWizardLabelFactory().loadLabels(node.getUniqueId());

                // set the node name
                if (restoreNodeString && StringUtils.isNotBlank(schemaNode.getUserName())) {
                    LOGGER.info("Restore the userName of the node: {}", schemaNode.getUserName());
                    final String label = schemaNode.getUserName();
                    node.setLabel(label);
                    node.getNode().setStoredString(StringData.INDEX_USERNAME, label);

                    // save the node label
                    nodeLabels.getNodeLabel().setUserName(label);

                    wizardLabelWrapper.saveNodeLabels(node.getUniqueId());
                }
                org.bidib.jbidibc.messages.Node coreNode = node.getNode();

                // configuration variables
                if (restoreCVs && schemaNode.getConfigurationVariables() != null
                    && CollectionUtils.isNotEmpty(schemaNode.getConfigurationVariables().getConfigurationVariable())) {
                    List schemaCvs =
                        schemaNode.getConfigurationVariables().getConfigurationVariable();

                    CollectionUtils
                        .filter(schemaCvs, new Predicate() {

                            @Override
                            public boolean evaluate(org.bidib.jbidibc.core.schema.bidib2.ConfigurationVariable cv) {
                                Boolean timeoutDetected = cv.isTimeout();

                                if (timeoutDetected != null && timeoutDetected.booleanValue()) {
                                    LOGGER.warn("Skip restore CV with timeout: {}", cv);
                                    return false;
                                }

                                return true;
                            }
                        });
                    LOGGER.info("filtered CVs: {}", schemaCvs);

                    // update the CV values in the CV map of the node and not on the mainModel

                    // Use the cvNumberToNode map to set the new values
                    final CvContainer cvContainer = cvDefinitionTreeModelRegistry.getCvContainer(node.getUniqueId());
                    if (cvContainer != null) {

                        Map map = cvContainer.getCvNumberToNodeMap();
                        for (org.bidib.jbidibc.core.schema.bidib2.ConfigurationVariable cv : schemaCvs) {
                            CvNode cvNode = map.get(cv.getName());
                            if (cvNode != null && !(ModeType.RO.equals(cvNode.getCV().getMode())
                                || ModeType.H.equals(cvNode.getCV().getMode()))) {

                                try {
                                    cvNode.setNewValue(cv.getValue());
                                }
                                catch (Exception ex) {
                                    LOGGER.warn("Set the CV value failed: {}", cv, ex);
                                    addImportError(importParams, "Set the CV value failed: " + cv);
                                }
                            }
                        }

                        CvDefinitionTreeTableModel treeModel = cvContainer.getCvTreeModel();
                        if (treeModel != null) {

                            boolean hasPendingCVChanges = CvDefinitionTreeHelper.hasPendingChanges(treeModel);
                            LOGGER
                                .info("After import of CV values from file, hasPendingCVChanges: {}",
                                    hasPendingCVChanges);
                        }
                    }
                    importParams.put(SaveNodeConfigurationDialog.CV_VALUES_RESTORED, Boolean.TRUE);
                }

                // features
                if (restoreFeatures && schemaNode.getFeatures() != null
                    && CollectionUtils.isNotEmpty(schemaNode.getFeatures().getFeature())) {
                    List schemaFeatures =
                        schemaNode.getFeatures().getFeature();
                    List features = coreNode.getFeatures();

                    for (org.bidib.jbidibc.core.schema.bidib2.Feature schemaFeature : schemaFeatures) {

                        Feature feature = Feature.findFeature(features, schemaFeature.getFeatureCodeId());
                        if (feature != null) {
                            feature.setValue(schemaFeature.getValue());
                        }
                        else {
                            LOGGER.warn("Skip set unknown feature: {}", schemaFeature);
                        }
                    }

                    importParams.put(SaveNodeConfigurationDialog.FEATURES_RESTORED, Boolean.TRUE);
                }

                // restore the feedback ports
                if (schemaNode.getFeedbackPorts() != null
                    && CollectionUtils.isNotEmpty(schemaNode.getFeedbackPorts().getFeedbackPort())) {
                    LOGGER.info("Restore the feedback ports.");

                    List feedbackPorts = new ArrayList<>(node.getFeedbackPorts());

                    List schemaFeedbackPorts =
                        schemaNode.getFeedbackPorts().getFeedbackPort();
                    for (org.bidib.jbidibc.core.schema.bidib2.FeedbackPort schemaFeedbackPort : schemaFeedbackPorts) {
                        FeedbackPort feedbackPort =
                            PortListUtils.findPortByPortNumber(feedbackPorts, schemaFeedbackPort.getNumber());
                        if (feedbackPort != null) {
                            feedbackPort.setLabel(schemaFeedbackPort.getName());

                            // replace the labels
                            BidibLabelUtils
                                .replaceFeedbackPortLabel(nodeLabels, feedbackPort.getId(), feedbackPort.getLabel());
                        }
                    }

                    node.setFeedbackPorts(feedbackPorts);
                }

                if (CollectionUtils.isNotEmpty(schemaNode.getPorts().getPort())) {
                    LOGGER.info("Restore the ports.");

                    List schemaPorts = schemaNode.getPorts().getPort();

                    // backlight ports
                    List schemaBacklightPorts =
                        BidibFactory.getPortsOfType(schemaPorts, LcOutputType.BACKLIGHTPORT);

                    if (CollectionUtils.isNotEmpty(schemaBacklightPorts)) {
                        final List backlightPorts = new ArrayList<>(node.getBacklightPorts());

                        for (OutputBacklight schemaBacklight : schemaBacklightPorts) {

                            BacklightPort backlightPort =
                                PortListUtils.findPortByPortNumber(backlightPorts, schemaBacklight.getNumber());
                            if (backlightPort != null) {
                                if (schemaBacklight.getDimmingDownSpeed() != null) {
                                    backlightPort.setDimSlopeDown(schemaBacklight.getDimmingDownSpeed());
                                }
                                if (schemaBacklight.getDimmingUpSpeed() != null) {
                                    backlightPort.setDimSlopeUp(schemaBacklight.getDimmingUpSpeed());
                                }
                                if (schemaBacklight.getDmxChannel() != null) {
                                    backlightPort.setDmxMapping(schemaBacklight.getDmxChannel());
                                }

                                backlightPort.setLabel(schemaBacklight.getName());

                                // replace the labels
                                BidibLabelUtils
                                    .replaceLabel(nodeLabels, WizardLabelFactory.LabelTypes.backlightPort,
                                        backlightPort.getId(), backlightPort.getLabel());
                            }
                            else {
                                LOGGER.warn("No backlight port available for schemaBacklight: {}", schemaBacklight);
                            }
                        }
                        node.setBacklightPorts(backlightPorts);
                    }

                    // input ports
                    List schemaInputPorts =
                        BidibFactory.getPortsOfType(schemaPorts, LcOutputType.INPUTPORT);

                    if (CollectionUtils.isNotEmpty(schemaInputPorts)) {
                        final List inputPorts = new ArrayList<>(node.getInputPorts());

                        for (InputKey schemaInput : schemaInputPorts) {

                            InputPort inputPort =
                                PortListUtils.findPortByPortNumber(inputPorts, schemaInput.getNumber());
                            if (inputPort != null && !schemaInput.isDisabled()) {

                                if (inputPort.getGenericPort() != null
                                    && !inputPort.getGenericPort().isMatchingPortType(LcOutputType.INPUTPORT)) {
                                    setCurrentPortType(inputPort.getGenericPort(), LcOutputType.INPUTPORT);
                                }

                                // TODO check if the port is enabled
                                inputPort.setEnabled(!schemaInput.isDisabled());

                                if (schemaInput.getSwitchOffTime() != null) {
                                    inputPort.setSwitchOffTime(schemaInput.getSwitchOffTime());
                                }
                                if (schemaInput.getIoInputBehaviour() != null) {
                                    inputPort
                                        .setInputBehaviour(
                                            IoBehaviourInputEnum.valueOf(schemaInput.getIoInputBehaviour().name()));
                                }

                                inputPort.setLabel(schemaInput.getName());
                                // replace the labels
                                BidibLabelUtils
                                    .replaceLabel(nodeLabels, WizardLabelFactory.LabelTypes.inputPort,
                                        inputPort.getId(), inputPort.getLabel());
                            }
                            else {
                                LOGGER.warn("No input port available for schemaInput: {}", schemaInput);
                            }
                        }
                        node.setInputPorts(inputPorts);
                    }

                    // light ports
                    List schemaLightPorts =
                        BidibFactory.getPortsOfType(schemaPorts, LcOutputType.LIGHTPORT);

                    if (CollectionUtils.isNotEmpty(schemaLightPorts)) {
                        final List lightPorts = new ArrayList<>(node.getLightPorts());

                        for (OutputLight schemaLight : schemaLightPorts) {

                            LightPort lightPort =
                                PortListUtils.findPortByPortNumber(lightPorts, schemaLight.getNumber());
                            if (lightPort != null) {
                                if (schemaLight.getBrightnessOff() != null) {
                                    lightPort.setPwmMin(schemaLight.getBrightnessOff());
                                }
                                if (schemaLight.getBrightnessOn() != null) {
                                    lightPort.setPwmMax(schemaLight.getBrightnessOn());
                                }
                                if (schemaLight.getDimmingDownSpeed() != null) {
                                    lightPort.setDimMin(schemaLight.getDimmingDownSpeed());
                                }
                                if (schemaLight.getDimmingUpSpeed() != null) {
                                    lightPort.setDimMax(schemaLight.getDimmingUpSpeed());
                                }
                                if (schemaLight.getRgbValue() != null) {
                                    lightPort.setRgbValue(schemaLight.getRgbValue());
                                }
                                if (schemaLight.getTransitionTime() != null) {
                                    lightPort.setTransitionTime(schemaLight.getTransitionTime());
                                }

                                lightPort.setLabel(schemaLight.getName());
                                // replace the labels
                                BidibLabelUtils
                                    .replaceLabel(nodeLabels, WizardLabelFactory.LabelTypes.lightPort,
                                        lightPort.getId(), lightPort.getLabel());
                            }
                            else {
                                LOGGER.warn("No light port available for schemaLight: {}", schemaLight);
                            }
                        }
                        node.setLightPorts(lightPorts);
                    }

                    // motor ports
                    List schemaMotorPorts =
                        BidibFactory.getPortsOfType(schemaPorts, LcOutputType.MOTORPORT);

                    if (CollectionUtils.isNotEmpty(schemaMotorPorts)) {
                        final List motorPorts = new ArrayList<>(node.getMotorPorts());

                        for (OutputMotor schemaMotor : schemaMotorPorts) {

                            MotorPort motorPort =
                                PortListUtils.findPortByPortNumber(motorPorts, schemaMotor.getNumber());
                            if (motorPort != null) {

                                motorPort.setLabel(schemaMotor.getName());
                                // replace the labels
                                BidibLabelUtils
                                    .replaceLabel(nodeLabels, WizardLabelFactory.LabelTypes.motorPort,
                                        motorPort.getId(), motorPort.getLabel());
                            }
                            else {
                                LOGGER.warn("No motor port available for schemaMotor: {}", schemaMotor);
                            }
                        }
                        node.setMotorPorts(motorPorts);
                    }

                    // servo ports
                    List schemaServoPorts =
                        BidibFactory.getPortsOfType(schemaPorts, LcOutputType.SERVOPORT);

                    if (CollectionUtils.isNotEmpty(schemaServoPorts)) {
                        final List servoPorts = new ArrayList<>(node.getServoPorts());

                        for (OutputServo schemaServo : schemaServoPorts) {

                            ServoPort servoPort =
                                PortListUtils.findPortByPortNumber(servoPorts, schemaServo.getNumber());
                            if (servoPort != null) {
                                if (schemaServo.getLowerLimit() != null) {
                                    servoPort.setTrimDown(schemaServo.getLowerLimit());
                                }
                                if (schemaServo.getUpperLimit() != null) {
                                    servoPort.setTrimUp(schemaServo.getUpperLimit());
                                }
                                if (schemaServo.getMovingTime() != null) {
                                    servoPort.setSpeed(schemaServo.getMovingTime());
                                }

                                // curve forms are optional
                                if (schemaServo.getCurveFormUp() != null) {
                                    servoPort.setCurveFormUp(CurveFormEnum.valueOf(schemaServo.getCurveFormUp()));
                                }
                                if (schemaServo.getCurveFormDown() != null) {
                                    servoPort.setCurveFormDown(CurveFormEnum.valueOf(schemaServo.getCurveFormDown()));
                                }
                                schemaServo.setServoExtra(servoPort.getServoExtra());

                                servoPort.setLabel(schemaServo.getName());
                                // replace the labels
                                BidibLabelUtils
                                    .replaceLabel(nodeLabels, WizardLabelFactory.LabelTypes.servoPort,
                                        servoPort.getId(), servoPort.getLabel());
                            }
                            else {
                                LOGGER.warn("No servo port available for schemaServo: {}", schemaServo);
                            }
                        }
                        node.setServoPorts(servoPorts);
                    }

                    // sound ports
                    List schemaSoundPorts =
                        BidibFactory.getPortsOfType(schemaPorts, LcOutputType.SOUNDPORT);

                    if (CollectionUtils.isNotEmpty(schemaSoundPorts)) {
                        final List soundPorts = new ArrayList<>(node.getSoundPorts());

                        for (OutputSound schemaSound : schemaSoundPorts) {

                            SoundPort soundPort =
                                PortListUtils.findPortByPortNumber(soundPorts, schemaSound.getNumber());
                            if (soundPort != null) {

                                soundPort.setLabel(schemaSound.getName());
                                // replace the labels
                                BidibLabelUtils
                                    .replaceLabel(nodeLabels, WizardLabelFactory.LabelTypes.soundPort,
                                        soundPort.getId(), soundPort.getLabel());
                            }
                            else {
                                LOGGER.warn("No sound port available for schemaSound: {}", schemaSound);
                            }
                        }
                        node.setSoundPorts(soundPorts);
                    }

                    // switch ports
                    List schemaOutputSwitchPorts =
                        BidibFactory.getPortsOfType(schemaPorts, LcOutputType.SWITCHPORT);

                    if (CollectionUtils.isNotEmpty(schemaOutputSwitchPorts)) {
                        final List switchPorts = new ArrayList<>(node.getSwitchPorts());

                        for (OutputSwitch schemaOutputSwitch : schemaOutputSwitchPorts) {

                            SwitchPort switchPort =
                                PortListUtils.findPortByPortNumber(switchPorts, schemaOutputSwitch.getNumber());
                            if (switchPort != null && !schemaOutputSwitch.isDisabled()) {

                                if (switchPort.getGenericPort() != null
                                    && !switchPort.getGenericPort().isMatchingPortType(LcOutputType.SWITCHPORT)) {
                                    setCurrentPortType(switchPort.getGenericPort(), LcOutputType.SWITCHPORT);
                                }

                                // TODO check if the port is enabled
                                switchPort.setEnabled(!schemaOutputSwitch.isDisabled());

                                if (schemaOutputSwitch.getSwitchOffTime() != null) {
                                    switchPort.setSwitchOffTime(schemaOutputSwitch.getSwitchOffTime());
                                }
                                if (schemaOutputSwitch.getIoSwitchBehaviour() != null) {
                                    switchPort
                                        .setOutputBehaviour(IoBehaviourSwitchEnum
                                            .valueOf(schemaOutputSwitch.getIoSwitchBehaviour().name()));
                                }
                                if (schemaOutputSwitch.getLoadType() != null) {
                                    switchPort
                                        .setLoadType(LoadTypeEnum.valueOf(schemaOutputSwitch.getLoadType().name()));
                                }

                                switchPort.setLabel(schemaOutputSwitch.getName());
                                // replace the labels
                                BidibLabelUtils
                                    .replaceLabel(nodeLabels, WizardLabelFactory.LabelTypes.switchPort,
                                        switchPort.getId(), switchPort.getLabel());
                            }
                            else {
                                LOGGER.warn("No switch port available for schemaOutputSwitch: {}", schemaOutputSwitch);
                            }
                        }
                        node.setSwitchPorts(switchPorts);
                    }

                    // switchPair ports
                    List schemaOutputSwitchPairPorts =
                        BidibFactory.getPortsOfType(schemaPorts, LcOutputType.SWITCHPAIRPORT);

                    if (CollectionUtils.isNotEmpty(schemaOutputSwitchPairPorts)) {
                        final List switchPairPorts = new ArrayList<>(node.getSwitchPairPorts());

                        for (OutputSwitchPair schemaOutputSwitchPair : schemaOutputSwitchPairPorts) {

                            SwitchPairPort switchPairPort =
                                PortListUtils.findPortByPortNumber(switchPairPorts, schemaOutputSwitchPair.getNumber());
                            if (switchPairPort != null && !schemaOutputSwitchPair.isDisabled()) {

                                if (switchPairPort.getGenericPort() != null && !switchPairPort
                                    .getGenericPort().isMatchingPortType(LcOutputType.SWITCHPAIRPORT)) {
                                    setCurrentPortType(switchPairPort.getGenericPort(), LcOutputType.SWITCHPAIRPORT);
                                }

                                // TODO check if the port is enabled
                                switchPairPort.setEnabled(!schemaOutputSwitchPair.isDisabled());

                                if (schemaOutputSwitchPair.getSwitchOffTime() != null) {
                                    switchPairPort.setSwitchOffTime(schemaOutputSwitchPair.getSwitchOffTime());
                                }

                                if (schemaOutputSwitchPair.getLoadType() != null) {
                                    switchPairPort
                                        .setLoadType(LoadTypeEnum.valueOf(schemaOutputSwitchPair.getLoadType().name()));
                                }

                                switchPairPort.setLabel(schemaOutputSwitchPair.getName());
                                // replace the labels
                                BidibLabelUtils
                                    .replaceLabel(nodeLabels, WizardLabelFactory.LabelTypes.switchPairPort,
                                        switchPairPort.getId(), switchPairPort.getLabel());
                            }
                            else {
                                LOGGER
                                    .warn("No switchPair port available for schemaOutputSwitchPair: {}",
                                        schemaOutputSwitchPair);
                            }
                        }
                        node.setSwitchPairPorts(switchPairPorts);
                    }
                }

                // restore the flag labels
                if (schemaNode.getFlags() != null && CollectionUtils.isNotEmpty(schemaNode.getFlags().getFlag())) {
                    LOGGER.info("Restore the flag names.");

                    final List flags = new ArrayList<>(node.getFlags());

                    for (org.bidib.jbidibc.core.schema.bidib2.Flag schemaFlag : schemaNode.getFlags().getFlag()) {

                        Flag flag = FlagListUtils.findFlagByNumber(flags, schemaFlag.getNumber());
                        if (flag != null) {
                            flag.setLabel(schemaFlag.getName());

                            BidibLabelUtils.replaceFlagLabel(nodeLabels, flag.getId(), flag.getLabel());
                        }
                    }
                    // set the flags triggers the refresh of the table
                    node.setFlags(flags);
                }

                if (restoreMacroContent && schemaNode.getMacros() != null
                    && CollectionUtils.isNotEmpty(schemaNode.getMacros().getMacro())) {
                    LOGGER.info("Restore the macro content.");

                    int maxMacroLength =
                        Feature.getIntFeatureValue(node.getNode().getFeatures(), BidibLibrary.FEATURE_CTRL_MAC_SIZE);

                    List macros = new ArrayList<>(node.getMacros());

                    List schemaMacros = schemaNode.getMacros().getMacro();
                    for (org.bidib.jbidibc.core.schema.bidib2.Macro schemaMacro : schemaMacros) {

                        Macro macro = MacroListUtils.findMacroByMacroNumber(macros, schemaMacro.getNumber());

                        if (macro == null) {
                            LOGGER
                                .warn("No macro available on node with macro number: {}. The macro is not imported!",
                                    schemaMacro.getNumber());
                            addImportError(importParams,
                                "No macro available on node with macro number: " + schemaMacro.getNumber());
                            continue;
                        }

                        macro.initialize();
                        macro.setFunctionSize(maxMacroLength);

                        MacroParameterSlowdown slowdown =
                            findMacroParameter(schemaMacro.getMacroParameters().getMacroParameter(),
                                MacroParameterSlowdown.class);
                        if (slowdown != null) {
                            macro.setSpeed(slowdown.getSpeed());
                        }

                        MacroParameterRepeat repeat =
                            findMacroParameter(schemaMacro.getMacroParameters().getMacroParameter(),
                                MacroParameterRepeat.class);
                        if (repeat != null) {
                            macro.setCycles(repeat.getRepetitions());
                        }

                        // restore the MacroParameterClockStart
                        // 
                        MacroParameterClockStart clockStart =
                            findMacroParameter(schemaMacro.getMacroParameters().getMacroParameter(),
                                MacroParameterClockStart.class);
                        if (clockStart != null) {
                            LinkedList startConditions = new LinkedList();
                            if (clockStart.isIsEnabled()) {

                                // handle startClk ...
                                TimeStartCondition timeStartCondition = new TimeStartCondition();
                                LOGGER.info("Apply start condition: {}", clockStart);

                                if (StringUtils.isNotBlank(clockStart.getPeriodicalRepetition())) {

                                    try {
                                        MinuteExtension minuteExtension =
                                            MinuteExtension.fromValue(clockStart.getPeriodicalRepetition());

                                        switch (minuteExtension) {
                                            case NO_REPETITION:
                                                break;
                                            case EVERY_MINUTE:
                                                timeStartCondition.setRepeatTime(MacroRepeatTime.MINUTELY);
                                                timeStartCondition.setMinutely(true);
                                                break;
                                            case EVERY_15_MINUTES:
                                                timeStartCondition.setRepeatTime(MacroRepeatTime.QUARTER_HOURLY);
                                                break;
                                            case EVERY_30_MINUTES:
                                                timeStartCondition.setRepeatTime(MacroRepeatTime.HALF_HOURLY);
                                                break;
                                            default:
                                                LOGGER.warn("Unsupported repeat period: {}", minuteExtension);
                                                break;
                                        }
                                    }
                                    catch (IllegalArgumentException ex) {

                                        try {
                                            HourExtension hourExtension =
                                                HourExtension.fromValue(clockStart.getPeriodicalRepetition());
                                            switch (hourExtension) {
                                                case EVERY_HOUR:
                                                    timeStartCondition.setRepeatTime(MacroRepeatTime.HOURLY);
                                                    timeStartCondition.setHourly(true);
                                                    break;
                                                case EVERY_HOUR_IN_DAYTIME:
                                                    timeStartCondition.setRepeatTime(MacroRepeatTime.WORKING_HOURLY);
                                                    timeStartCondition.setHourly(true);
                                                    break;
                                                default:
                                                    LOGGER.warn("Unsupported repeat period: {}", hourExtension);
                                                    break;
                                            }
                                        }
                                        catch (IllegalArgumentException ex1) {
                                            LOGGER
                                                .warn("Set the repeat period failed: {}",
                                                    clockStart.getPeriodicalRepetition(), ex1);

                                            // add import error
                                            addImportError(importParams, "Set the repeat period failed for macro num: "
                                                + macro.getId() + ",  repeat: " + clockStart.getPeriodicalRepetition());
                                        }
                                    }
                                }
                                if (StringUtils.isNotBlank(clockStart.getWeekday())) {

                                    try {
                                        WeekdayExtension weekdayExtension =
                                            WeekdayExtension.fromValue(clockStart.getWeekday());
                                        switch (weekdayExtension) {
                                            case EVERY_DAY:
                                                timeStartCondition.setRepeatDay(MacroRepeatDay.ALL);
                                                break;
                                            default:
                                                LOGGER.warn("Unsupported weekdayExtension: {}", weekdayExtension);
                                                break;
                                        }
                                    }
                                    catch (IllegalArgumentException ex) {

                                        try {
                                            Weekday weekday = Weekday.fromValue(clockStart.getWeekday());
                                            switch (weekday) {
                                                case MONDAY:
                                                    timeStartCondition.setRepeatDay(MacroRepeatDay.MONDAY);
                                                    break;
                                                case TUESDAY:
                                                    timeStartCondition.setRepeatDay(MacroRepeatDay.TUESDAY);
                                                    break;
                                                case WEDNESDAY:
                                                    timeStartCondition.setRepeatDay(MacroRepeatDay.WEDNESDAY);
                                                    break;
                                                case THURSDAY:
                                                    timeStartCondition.setRepeatDay(MacroRepeatDay.THURSDAY);
                                                    break;
                                                case FRIDAY:
                                                    timeStartCondition.setRepeatDay(MacroRepeatDay.FRIDAY);
                                                    break;
                                                case SATURDAY:
                                                    timeStartCondition.setRepeatDay(MacroRepeatDay.SATURDAY);
                                                    break;
                                                case SUNDAY:
                                                    timeStartCondition.setRepeatDay(MacroRepeatDay.SUNDAY);
                                                    break;
                                                default:
                                                    LOGGER.warn("Unsupported weekday: {}", weekday);
                                                    break;
                                            }
                                        }
                                        catch (IllegalArgumentException ex1) {
                                            LOGGER
                                                .warn("Set the repeat weekday failed: {}", clockStart.getWeekday(),
                                                    ex1);

                                            // add import error
                                            addImportError(importParams, "Set the repeat weekday failed for macro num: "
                                                + macro.getId() + ",  weekday: " + clockStart.getWeekday());
                                        }
                                    }
                                }
                                Calendar cal = GregorianCalendar.getInstance();
                                cal.set(Calendar.HOUR_OF_DAY, clockStart.getHour());
                                cal.set(Calendar.MINUTE, clockStart.getMinute());
                                timeStartCondition.setTime(cal);

                                startConditions.add(timeStartCondition);
                                macro.setStartConditions(startConditions);
                            }
                            else {
                                macro.setStartConditions(startConditions);
                            }
                        }

                        if (schemaMacro.getMacroPoints() != null
                            && CollectionUtils.isNotEmpty(schemaMacro.getMacroPoints().getMacroPoint())) {
                            FunctionConversionFactory functionConversionFactory = new FunctionConversionFactory();

                            List> functions = new ArrayList<>();
                            for (MacroPoint schemaMacroPoint : schemaMacro.getMacroPoints().getMacroPoint()) {

                                // convert the macro point into a macroStep by extending the
                                Function function =
                                    functionConversionFactory.convert(schemaMacroPoint, node);
                                if (function != null) {
                                    functions.add(function);
                                }
                                else {
                                    LOGGER.warn("Conver macroPoint to function failed: {}", schemaMacroPoint);
                                    // add empty step
                                    functions.add(new EmptyFunction());
                                }
                            }

                            LOGGER.info("Set the functions: {}", functions);
                            macro.setFunctions(functions);
                        }

                        macro.setLabel(schemaMacro.getName());

                        BidibLabelUtils.replaceMacroLabel(nodeLabels, macro.getId(), macro.getLabel());

                        macro.setMacroSaveState(MacroSaveState.PENDING_CHANGES);
                    }

                    node.setMacros(macros);

                    LOGGER.info("Restore the macro content has finished.");
                }

                // restore accessories
                if (restoreAccessoryContent && schemaNode.getAccessories() != null
                    && CollectionUtils.isNotEmpty(schemaNode.getAccessories().getAccessory())) {
                    LOGGER.info("Restore the accessory content.");

                    int maxAccessoryLength =
                        Feature
                            .getIntFeatureValue(node.getNode().getFeatures(),
                                BidibLibrary.FEATURE_ACCESSORY_MACROMAPPED);

                    List accessories = new ArrayList<>(node.getAccessories());

                    List schemaAccessories =
                        schemaNode.getAccessories().getAccessory();
                    for (org.bidib.jbidibc.core.schema.bidib2.Accessory schemaAccessory : schemaAccessories) {

                        Accessory accessory =
                            AccessoryListUtils.findAccessoryByAccessoryNumber(accessories, schemaAccessory.getNumber());
                        if (accessory != null) {

                            // keep total aspects
                            int totalAspects = accessory.getTotalAspects();

                            accessory.initialize();
                            accessory.setMaximumMacroMappedAspects(maxAccessoryLength);

                            // set the accessory label
                            accessory.setLabel(schemaAccessory.getName());
                            AccessoryLabelUtils
                                .replaceAccessoryLabel(nodeLabels, accessory.getId(), schemaAccessory.getName());

                            if (schemaAccessory.getAspects() != null
                                && CollectionUtils.isNotEmpty(schemaAccessory.getAspects().getAspect())) {

                                // prepare the aspects
                                List aspects = new ArrayList<>();
                                for (Aspect schemaAspect : schemaAccessory.getAspects().getAspect()) {

                                    int aspectNumber = schemaAspect.getNumber();

                                    MacroRef aspect = null;
                                    if (schemaAspect.getMacroNumber() != null) {
                                        aspect = new MacroRef();
                                        aspect.setId(aspectNumber);
                                        aspects.add(aspect);

                                        // macro-mapped aspect
                                        aspect.setId(schemaAspect.getMacroNumber());
                                    }

                                    String aspectName = schemaAspect.getName();
                                    if (aspect != null) {
                                        aspect.setLabel(aspectName);
                                    }

                                    // prepare the aspect label
                                    AccessoryLabelUtils
                                        .replaceAspectLabel(nodeLabels, accessory.getId(), aspectNumber, aspectName);

                                }

                                accessory.setAspects(aspects);
                                // set the total size of aspects
                                accessory.setTotalAspects(totalAspects);
                            }
                            else {
                                LOGGER.info("No aspects in accessory: {}", schemaAccessory);
                            }

                            accessory.setStartupState(schemaAccessory.getStartupState());
                        }
                        else {
                            LOGGER.info("No matching accessory found for schemaAccessory: {}", schemaAccessory);
                        }
                    }

                    LOGGER.info("Set the accessories: {}", accessories);
                    node.setAccessories(accessories);

                    importParams.put(SaveNodeConfigurationDialog.MACRO_AND_ACCESSORIES_RESTORED, Boolean.TRUE);
                    LOGGER.info("Restore the accessories has finished.");
                }

            }
        }
        return node;
    }

    public static void setCurrentPortType(final GenericPort genericPort, LcOutputType portType) {

        Map> portConfigX = genericPort.getPortConfigX();

        ReconfigPortConfigValue reconfig = (ReconfigPortConfigValue) portConfigX.get(BidibLibrary.BIDIB_PCFG_RECONFIG);
        ReconfigPortConfigValue newReconfig =
            new ReconfigPortConfigValue(ByteUtils.getInt(portType.getType()), reconfig.getPortMap());

        LOGGER.info("Set the new BIDIB_PCFG_RECONFIG: {}", newReconfig);

        portConfigX.put(BidibLibrary.BIDIB_PCFG_RECONFIG, newReconfig);
        genericPort.setPortConfigX(portConfigX);
        genericPort.getKnownPortConfigKeys().add(BidibLibrary.BIDIB_PCFG_RECONFIG);
    }

    public static void addImportError(Map params, String message) {
        List saveErrors = (List) params.get(NodeUtils.IMPORT_ERRORS);
        if (saveErrors == null) {
            saveErrors = new LinkedList();
            params.put(NodeUtils.IMPORT_ERRORS, saveErrors);
        }
        saveErrors.add(message);
    }

    private static  T findMacroParameter(
        List macroParameters, Class paramClazz) {

        for (MacroParameter param : macroParameters) {
            if (paramClazz.isInstance(param)) {
                return (T) param;
            }
        }
        return null;
    }

    /**
     * Convert the node to BiDiB data.
     * 
     * @param node
     *            the node
     * @return the BiDiB data
     */
    public static BiDiB convertToBiDiB(
        final NodeInterface node, final Map cvNumberToNodeMap, final String lang, boolean skipCvValues,
        final WizardLabelWrapper wizardLabelWrapper) {
        LOGGER.info("Convert node to BiDiB: {}", node);

        if (node == null) {
            throw new IllegalArgumentException("A node must be provided.");
        }

        final NodeLabels nodeLabels = wizardLabelWrapper.getWizardLabelFactory().loadLabels(node.getUniqueId());

        org.bidib.jbidibc.messages.Node coreNode = node.getNode();

        long uniqueId = coreNode.getUniqueId();

        BiDiB bidib = new BiDiB();
        bidib.withSchemaVersion("1.0");

        org.bidib.jbidibc.core.schema.bidib2.Node schemaNode = new org.bidib.jbidibc.core.schema.bidib2.Node();
        schemaNode
            .withUserName(coreNode.getStoredString(StringData.INDEX_USERNAME))
            .withProductName(coreNode.getStoredString(StringData.INDEX_PRODUCTNAME))
            .withManufacturerId(org.bidib.jbidibc.messages.utils.NodeUtils.getVendorId(uniqueId))
            .withProductId(org.bidib.jbidibc.messages.utils.NodeUtils.getPid(uniqueId, coreNode.getRelevantPidBits()))
            .withUniqueId(uniqueId).withFirmwareRelease(coreNode.getSoftwareVersion().toString())
            .withProtocol(coreNode.getProtocolVersion().toString());

        List nodes = bidib.withNodes(new Nodes()).getNodes().getNode();
        nodes.add(schemaNode);

        // features
        List features = coreNode.getFeatures();
        if (CollectionUtils.isNotEmpty(features)) {

            Collections.sort(features, (f1, f2) -> f1.getType() - f2.getType());

            schemaNode.withFeatures(new Features());
            List schemaFeatures = schemaNode.getFeatures().getFeature();
            for (Feature feature : features) {

                org.bidib.jbidibc.core.schema.bidib2.Feature schemaFeature =
                    new org.bidib.jbidibc.core.schema.bidib2.Feature();
                schemaFeature.withFeatureCodeId(feature.getType()).withValue(feature.getValue());

                schemaFeatures.add(schemaFeature);
            }
        }

        // configuration variables
        if (!skipCvValues) {
            final List cvs =
                node.getConfigVariables().values().stream().collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(cvs)) {

                // sort the CV variables by number
                ConfigurationVariable.sortCvVariables(cvs);

                schemaNode.withConfigurationVariables(new ConfigurationVariables());
                final List schemaCvs =
                    schemaNode.getConfigurationVariables().getConfigurationVariable();
                for (ConfigurationVariable cv : cvs) {

                    if (cv.isTimeout()) {
                        // skip CV with timeout
                        LOGGER.debug("Skip CV with timeout: {}", cv);
                        continue;
                    }

                    org.bidib.jbidibc.core.schema.bidib2.ConfigurationVariable schemaCv =
                        new org.bidib.jbidibc.core.schema.bidib2.ConfigurationVariable();
                    schemaCv
                        .withName(cv.getName())//
                        .withDefaultValue(cv.getDefaultValue())//
                        .withValue(cv.getValue());//

                    CvNode cvNode = cvNumberToNodeMap.get(cv.getName());
                    if (cvNode != null) {
                        String description = CvNode.getDescription(cvNode.getCV().getDescription(), lang);
                        schemaCv.withDescription(description);
                    }

                    schemaCvs.add(schemaCv);
                }
            }
        }
        else {
            LOGGER.info("Add CV values to export data is skipped.");
        }

        // feedback ports
        List feedbackPorts = node.getFeedbackPorts();
        if (CollectionUtils.isNotEmpty(feedbackPorts)) {
            schemaNode.withFeedbackPorts(new FeedbackPorts());
            List schemaFeedbackPorts =
                schemaNode.getFeedbackPorts().getFeedbackPort();

            // prepare the feedback ports
            for (FeedbackPort feedbackPort : feedbackPorts) {

                org.bidib.jbidibc.core.schema.bidib2.FeedbackPort port =
                    new org.bidib.jbidibc.core.schema.bidib2.FeedbackPort();
                port.setNumber(feedbackPort.getId());

                BaseLabel label = BidibLabelUtils.getFeedbackPortLabel(nodeLabels, feedbackPort.getId());
                if (label != null) {
                    port.setName(label.getLabel());
                }
                else {
                    // set the default name
                    port.setName(feedbackPort.toString());
                }
                schemaFeedbackPorts.add(port);
            }
        }

        // ports
        schemaNode.withPorts(new Ports());
        List ports = schemaNode.getPorts().getPort();

        // analog ports
        List analogPorts = node.getAnalogPorts();
        if (CollectionUtils.isNotEmpty(analogPorts)) {
            // prepare the analog ports
        }

        // input ports
        List inputPorts = node.getInputPorts();
        if (CollectionUtils.isNotEmpty(inputPorts)) {

            // prepare the input ports
            for (InputPort inputPort : inputPorts) {

                InputKey inputKey = new InputKey();
                inputKey.setNumber(inputPort.getId());
                inputKey.setDisabled(!inputPort.isEnabled());

                try {
                    if (inputPort.getInputBehaviour() != IoBehaviourInputEnum.UNKNOWN) {
                        inputKey.setIoInputBehaviour(IOInputBehaviour.valueOf(inputPort.getInputBehaviour().name()));
                    }
                }
                catch (Exception ex) {
                    LOGGER.warn("Set the ioBehaviour for inputKey failed.", ex);
                }

                inputKey.setSwitchOffTime(inputPort.getSwitchOffTime());

                BaseLabel label =
                    BidibLabelUtils
                        .getLabel(nodeLabels.getPortLabels(), WizardLabelFactory.LabelTypes.inputPort,
                            inputPort.getId());
                if (label != null) {
                    inputKey.setName(label.getLabel());
                }
                else {
                    // set the default name
                    inputKey.setName(inputPort.toString());
                }
                ports.add(inputKey);
            }
        }

        // backlight ports
        List backlightPorts = node.getBacklightPorts();
        if (CollectionUtils.isNotEmpty(backlightPorts)) {

            // prepare the backlight ports
            for (BacklightPort backlightPort : backlightPorts) {

                OutputBacklight backlight = new OutputBacklight();
                backlight.setNumber(backlightPort.getId());
                backlight.setDisabled(!backlightPort.isEnabled());
                backlight.setDimmingDownSpeed(backlightPort.getDimSlopeDown());
                backlight.setDimmingUpSpeed(backlightPort.getDimSlopeUp());
                backlight.setDmxChannel(backlightPort.getDmxMapping());

                BaseLabel label =
                    BidibLabelUtils
                        .getLabel(nodeLabels.getPortLabels(), WizardLabelFactory.LabelTypes.backlightPort,
                            backlightPort.getId());
                if (label != null) {
                    backlight.setName(label.getLabel());
                }
                else {
                    // set the default name
                    backlight.setName(backlightPort.toString());
                }
                ports.add(backlight);
            }
        }

        // light ports
        List lightPorts = node.getLightPorts();
        if (CollectionUtils.isNotEmpty(lightPorts)) {

            // prepare the light ports
            for (LightPort lightPort : lightPorts) {

                OutputLight light = new OutputLight();
                light.setNumber(lightPort.getId());
                light.setDisabled(!lightPort.isEnabled());
                light.setBrightnessOff(lightPort.getPwmMin());
                light.setBrightnessOn(lightPort.getPwmMax());
                light.setDimmingDownSpeed(lightPort.getDimMin());
                light.setDimmingUpSpeed(lightPort.getDimMax());
                light.setRgbValue(lightPort.getRgbValue());
                light.setTransitionTime(lightPort.getTransitionTime());
                light.setOutputMap(lightPort.getDmxMapping());

                BaseLabel label =
                    BidibLabelUtils
                        .getLabel(nodeLabels.getPortLabels(), WizardLabelFactory.LabelTypes.lightPort,
                            lightPort.getId());
                if (label != null) {
                    light.setName(label.getLabel());
                }
                else {
                    // set the default name
                    light.setName(lightPort.toString());
                }
                ports.add(light);
            }
        }

        // servo ports
        List servoPorts = node.getServoPorts();
        if (CollectionUtils.isNotEmpty(servoPorts)) {

            // prepare the servo ports
            for (ServoPort servoPort : servoPorts) {

                final OutputServo servo = new OutputServo();
                servo.setDisabled(!servoPort.isEnabled());
                servo.setLowerLimit(servoPort.getTrimDown());
                servo.setUpperLimit(servoPort.getTrimUp());
                servo.setMovingTime(servoPort.getSpeed());

                // curve forms are optional
                if (servoPort.getCurveFormUp() != null) {
                    servo.setCurveFormUp(ByteUtils.getInteger(servoPort.getCurveFormUp().getType()));
                }
                if (servoPort.getCurveFormDown() != null) {
                    servo.setCurveFormDown(ByteUtils.getInteger(servoPort.getCurveFormDown().getType()));
                }
                servo.setServoExtra(servoPort.getServoExtra());

                servo.setNumber(servoPort.getId());
                BaseLabel label =
                    BidibLabelUtils
                        .getLabel(nodeLabels.getPortLabels(), WizardLabelFactory.LabelTypes.servoPort,
                            servoPort.getId());
                if (label != null) {
                    servo.setName(label.getLabel());
                }
                else {
                    // set the default name
                    servo.setName(servoPort.toString());
                }
                ports.add(servo);
            }
        }

        // sound ports
        List soundPorts = node.getSoundPorts();
        if (CollectionUtils.isNotEmpty(soundPorts)) {

            // prepare the sound ports
            for (SoundPort soundPort : soundPorts) {

                OutputSound sound = new OutputSound();
                sound.setDisabled(!soundPort.isEnabled());
                sound.setPulseTime(soundPort.getPulseTime());
                sound.setNumber(soundPort.getId());
                BaseLabel label =
                    BidibLabelUtils
                        .getLabel(nodeLabels.getPortLabels(), WizardLabelFactory.LabelTypes.soundPort,
                            soundPort.getId());
                if (label != null) {
                    sound.setName(label.getLabel());
                }
                else {
                    // set the default name
                    sound.setName(soundPort.toString());
                }
                ports.add(sound);
            }
        }

        // switch ports
        List switchPorts = node.getSwitchPorts();
        if (CollectionUtils.isNotEmpty(switchPorts)) {

            // prepare the switch ports
            for (SwitchPort switchPort : switchPorts) {

                OutputSwitch outputSwitch = new OutputSwitch();
                outputSwitch.setNumber(switchPort.getId());
                outputSwitch.setDisabled(!switchPort.isEnabled());
                try {
                    if (switchPort.getOutputBehaviour() != IoBehaviourSwitchEnum.UNKNOWN) {
                        outputSwitch
                            .setIoSwitchBehaviour(IOSwitchBehaviour.valueOf(switchPort.getOutputBehaviour().name()));
                    }
                }
                catch (Exception ex) {
                    LOGGER.warn("Set the ioBehaviour for outputSwitch failed.", ex);
                }
                try {
                    if (switchPort.getLoadType() != LoadTypeEnum.UNKNOWN) {
                        outputSwitch.setLoadType(LoadType.valueOf(switchPort.getLoadType().name()));
                    }
                }
                catch (Exception ex) {
                    LOGGER.warn("Set the loadType for outputSwitch failed.", ex);
                }
                outputSwitch.setSwitchOffTime(switchPort.getSwitchOffTime());

                BaseLabel label =
                    BidibLabelUtils
                        .getLabel(nodeLabels.getPortLabels(), WizardLabelFactory.LabelTypes.switchPort,
                            switchPort.getId());
                if (label != null) {
                    outputSwitch.setName(label.getLabel());
                }
                else {
                    // set the default name
                    outputSwitch.setName(switchPort.toString());
                }
                ports.add(outputSwitch);
            }
        }

        // switchPair ports
        List switchPairPorts = node.getSwitchPairPorts();
        if (CollectionUtils.isNotEmpty(switchPairPorts)) {

            // prepare the switch ports
            for (SwitchPairPort switchPairPort : switchPairPorts) {

                OutputSwitchPair outputSwitchPair = new OutputSwitchPair();
                outputSwitchPair.setNumber(switchPairPort.getId());
                outputSwitchPair.setDisabled(!switchPairPort.isEnabled());
                try {
                    if (switchPairPort.getLoadType() != LoadTypeEnum.UNKNOWN) {
                        outputSwitchPair.setLoadType(LoadType.valueOf(switchPairPort.getLoadType().name()));
                    }
                }
                catch (Exception ex) {
                    LOGGER.warn("Set the loadType for outputSwitchPair failed.", ex);
                }
                outputSwitchPair.setSwitchOffTime(switchPairPort.getSwitchOffTime());

                BaseLabel label =
                    BidibLabelUtils
                        .getLabel(nodeLabels.getPortLabels(), WizardLabelFactory.LabelTypes.switchPairPort,
                            switchPairPort.getId());
                if (label != null) {
                    outputSwitchPair.setName(label.getLabel());
                }
                else {
                    // set the default name
                    outputSwitchPair.setName(switchPairPort.toString());
                }
                ports.add(outputSwitchPair);
            }
        }

        // sort the porty by port number if flat port model
        if (node.isFlatPortModel()) {

            Collections.sort(ports, (p1, p2) -> {
                return Integer.compare(p1.getNumber(), p2.getNumber());
            });

        }

        // macros
        List macros = node.getMacros();
        if (CollectionUtils.isNotEmpty(macros)) {

            final FunctionConversionFactory functionConversionFactory = new FunctionConversionFactory();

            Macros schemaMacros = new Macros();

            for (Macro macro : macros) {

                org.bidib.jbidibc.core.schema.bidib2.Macro schemaMacro =
                    new org.bidib.jbidibc.core.schema.bidib2.Macro();
                schemaMacro.setNumber(macro.getId());

                // TODO get the name from the labels
                schemaMacro.setName(macro.getLabel());

                // prepare macro parameters
                MacroParameters macroParameters = createMacroParameters(macro);
                schemaMacro.setMacroParameters(macroParameters);

                // prepare macro points
                List> functions = macro.getFunctions();
                if (CollectionUtils.isNotEmpty(functions)) {

                    MacroPoints macroPoints = new MacroPoints();
                    schemaMacro.withMacroPoints(macroPoints);

                    for (Function function : functions) {

                        LOGGER.info("Convert function: {}", function);
                        // prepare macro point
                        MacroPoint macroPoint = functionConversionFactory.convert(function);

                        macroPoints.withMacroPoint(macroPoint);
                    }
                }

                schemaMacros.withMacro(schemaMacro);
            }

            schemaNode.setMacros(schemaMacros);

            // flags
            if (CollectionUtils.isNotEmpty(node.getFlags())) {
                Flags schemaFlags = new Flags();
                for (Flag flag : node.getFlags()) {
                    if (StringUtils.isNotBlank(flag.getLabel())) {
                        org.bidib.jbidibc.core.schema.bidib2.Flag schemaFlag =
                            new org.bidib.jbidibc.core.schema.bidib2.Flag()
                                .withNumber(flag.getId()).withName(flag.getLabel());
                        schemaFlags.getFlag().add(schemaFlag);
                    }
                }
                if (CollectionUtils.isNotEmpty(schemaFlags.getFlag())) {
                    schemaNode.setFlags(schemaFlags);
                }
                else {
                    LOGGER.info("No flags with labels.");
                }
            }

        }
        else {
            LOGGER.info("No macros available.");
        }

        // accessories
        List accessories = node.getAccessories();
        if (CollectionUtils.isNotEmpty(accessories)) {

            Accessories schemaAccessories = new Accessories();

            for (Accessory accessory : accessories) {
                org.bidib.jbidibc.core.schema.bidib2.Accessory schemaAccessory =
                    new org.bidib.jbidibc.core.schema.bidib2.Accessory();
                schemaAccessory.setNumber(accessory.getId());

                final AccessoryLabel accessoryLabel =
                    AccessoryLabelUtils.getAccessoryLabel(nodeLabels, accessory.getId());

                if (accessoryLabel != null) {
                    schemaAccessory.setName(accessoryLabel.getLabel());
                }

                if (accessory.getMaximumMacroMappedAspects() > 0) {
                    // macro-mapped aspects

                    // prepare the aspects
                    Collection aspects = accessory.getAspects();
                    if (CollectionUtils.isNotEmpty(aspects)) {

                        Aspects schemaAspects = new Aspects();
                        schemaAccessory.withAspects(schemaAspects);

                        int aspectNumber = 0;
                        for (MacroRef macroRef : aspects) {
                            // prepare aspect
                            Aspect aspect = new Aspect();
                            aspect.setMacroNumber(macroRef.getId());
                            aspect.setNumber(aspectNumber);
                            schemaAspects.withAspect(aspect);

                            // prepare the aspect label
                            BaseLabel aspectLabel =
                                AccessoryLabelUtils.getAccessoryAspectLabel(accessoryLabel, aspectNumber);
                            if (aspectLabel != null) {
                                aspect.setName(aspectLabel.getLabel());
                            }

                            aspectNumber++;
                        }
                    }
                }
                else {
                    // fixed aspects
                    if (accessory.getTotalAspects() > 0) {

                        Aspects schemaAspects = new Aspects();
                        schemaAccessory.withAspects(schemaAspects);

                        // prepare the aspects
                        for (int aspectNumber = 0; aspectNumber < accessory.getTotalAspects(); aspectNumber++) {
                            // prepare aspect
                            Aspect aspect = new Aspect();
                            aspect.setNumber(aspectNumber);
                            schemaAspects.withAspect(aspect);

                            // prepare the aspect label
                            BaseLabel aspectLabel =
                                AccessoryLabelUtils.getAccessoryAspectLabel(accessoryLabel, aspectNumber);
                            if (aspectLabel != null) {
                                aspect.setName(aspectLabel.getLabel());
                            }
                        }
                    }
                }

                // set the startup accessory
                if (accessory.getStartupState() != null) {
                    schemaAccessory.setStartupState(accessory.getStartupState());
                }
                schemaAccessories.withAccessory(schemaAccessory);
            }

            schemaNode.setAccessories(schemaAccessories);
        }
        else {
            LOGGER.info("No accessories available.");
        }

        return bidib;
    }

    private static MacroParameters createMacroParameters(Macro macro) {
        MacroParameters macroParameters = new MacroParameters();

        MacroParameterSlowdown macroParameterSlowdown = new MacroParameterSlowdown();
        macroParameterSlowdown.setSpeed(macro.getSpeed());
        macroParameters.withMacroParameter(macroParameterSlowdown);

        MacroParameterRepeat macroParameterRepeat = new MacroParameterRepeat();
        macroParameterRepeat.setRepetitions(macro.getCycles());
        macroParameters.withMacroParameter(macroParameterRepeat);

        MacroParameterClockStart macroParameterClockStart = new MacroParameterClockStart();

        if (CollectionUtils.isNotEmpty(macro.getStartConditions())) {
            List startConditions = new LinkedList<>(macro.getStartConditions());
            if (startConditions.get(0) instanceof TimeStartCondition) {
                TimeStartCondition timeStartCondition = (TimeStartCondition) startConditions.get(0);

                macroParameterClockStart.setHour(timeStartCondition.getTime().get(Calendar.HOUR_OF_DAY));
                macroParameterClockStart.setMinute(timeStartCondition.getTime().get(Calendar.MINUTE));
                macroParameterClockStart.setIsEnabled(true);

                // set the repeat day
                if (timeStartCondition.getRepeatDay() != null) {
                    switch (timeStartCondition.getRepeatDay()) {
                        case ALL:
                            macroParameterClockStart.setWeekday(WeekdayExtension.EVERY_DAY.value());
                            break;
                        case MONDAY:
                            macroParameterClockStart.setWeekday(Weekday.MONDAY.value());
                            break;
                        case TUESDAY:
                            macroParameterClockStart.setWeekday(Weekday.TUESDAY.value());
                            break;
                        case WEDNESDAY:
                            macroParameterClockStart.setWeekday(Weekday.WEDNESDAY.value());
                            break;
                        case THURSDAY:
                            macroParameterClockStart.setWeekday(Weekday.THURSDAY.value());
                            break;
                        case FRIDAY:
                            macroParameterClockStart.setWeekday(Weekday.FRIDAY.value());
                            break;
                        case SATURDAY:
                            macroParameterClockStart.setWeekday(Weekday.SATURDAY.value());
                            break;
                        case SUNDAY:
                            macroParameterClockStart.setWeekday(Weekday.SUNDAY.value());
                            break;
                        default:
                            LOGGER.warn("Unknown repeat day: {}", timeStartCondition.getRepeatDay());
                            break;
                    }
                }
                else {
                    LOGGER.info("No repeat day specified for macro: {}", macro.getLabel());
                }

                // set the repeat time
                if (timeStartCondition.getRepeatTime() != null) {
                    switch (timeStartCondition.getRepeatTime()) {
                        case HOURLY:
                            macroParameterClockStart.setPeriodicalRepetition(HourExtension.EVERY_HOUR.value());
                            // macroParameterClockStart.setMinute(null);
                            break;
                        case WORKING_HOURLY:
                            macroParameterClockStart
                                .setPeriodicalRepetition(HourExtension.EVERY_HOUR_IN_DAYTIME.value());
                            // macroParameterClockStart.setMinute(null);
                            break;
                        case HALF_HOURLY:
                            macroParameterClockStart.setPeriodicalRepetition(MinuteExtension.EVERY_30_MINUTES.value());
                            // macroParameterClockStart.setHour(null);
                            break;
                        case QUARTER_HOURLY:
                            macroParameterClockStart.setPeriodicalRepetition(MinuteExtension.EVERY_15_MINUTES.value());
                            // macroParameterClockStart.setHour(null);
                            break;
                        case MINUTELY:
                            macroParameterClockStart.setPeriodicalRepetition(MinuteExtension.EVERY_MINUTE.value());
                            // macroParameterClockStart.setHour(null);
                            break;
                        case NONE:
                            break;
                    }
                }
                else {
                    LOGGER.info("No repeat time specified for macro: {}", macro.getLabel());
                }
            }
        }
        else {
            macroParameterClockStart.setIsEnabled(false);
        }
        macroParameters.withMacroParameter(macroParameterClockStart);

        return macroParameters;
    }

    public static 

> P getPort( List

ports, int portNumber, boolean sourceIsFlatPortModel, boolean targetIsFlatPortModel) { LOGGER .info("Get port with portNumber: {}, sourceIsFlatPortModel: {}, targetIsFlatPortModel: {}", portNumber, sourceIsFlatPortModel, targetIsFlatPortModel); if (sourceIsFlatPortModel != targetIsFlatPortModel) { // the models are different if (!sourceIsFlatPortModel) { // the source is type-oriented and the target is flat try { P port = ports.get(portNumber); if (!port.isEnabled()) { LOGGER.warn("Found disabled port at index: {}, port: {}", portNumber, port); return null; } else { LOGGER.info("Searched port at index: {}, return found port: {}", portNumber, port); return port; } } catch (IndexOutOfBoundsException ex) { LOGGER.warn("Port not available, portNumber: {}, message: {}", portNumber, ex.getMessage()); } } else { LOGGER.warn("Cannot calculate port from flat to type-oriented model."); } } else { LOGGER.info("Get the port from the portNumber: {}", portNumber); for (P port : ports) { if (port.getId() == portNumber) { LOGGER.info("Return found port: {}", port); return port; } } } return null; } public static Map getCvNumberToNodeMap(final NodeInterface node, final ApplicationContext context) { // get the prepared CvDefinitionTreeTableModel from the CvDefinitionPanelController CvDefinitionPanelController cvDefinitionPanelController = context.get(DefaultApplicationContext.KEY_CVDEFINITIONPANEL_CONTROLLER, CvDefinitionPanelController.class); Map cvNumberToNodeMap = cvDefinitionPanelController.getCvNumberToNodeMap(node); return cvNumberToNodeMap; } public static CvDefinitionTreeTableModel getCvDefinitionTreeTableModel( final NodeInterface node, final ApplicationContext context) { // get the prepared CvDefinitionTreeTableModel from the CvDefinitionPanelController CvDefinitionPanelController cvDefinitionPanelController = context.get(DefaultApplicationContext.KEY_CVDEFINITIONPANEL_CONTROLLER, CvDefinitionPanelController.class); CvDefinitionTreeTableModel cvDefinitionTreeTableModel = cvDefinitionPanelController.getCvDefinitionTreeTableModel(node); return cvDefinitionTreeTableModel; } /** * Load data from node. * * @param connectionId * the connection id * @param nodeService * the node service * @param switchingNodeService * the switching node service * @param node * the node * @param loadMacroContent * load macro content from node * @param loadCvs * load CVs from node */ public static void loadDataFromNode( String connectionId, final NodeService nodeService, final SwitchingNodeService switchingNodeService, NodeInterface node, boolean loadMacroContent, boolean loadCvs) { // load CVs if (loadCvs) { LOGGER.info("Load the CVs of the node before export: {}", node); // use the CV list from the model List configurationVariables = node.getConfigVariables().values().stream().distinct().collect(Collectors.toList()); // sort the CV variables by number ConfigurationVariable.sortCvVariables(configurationVariables); configurationVariables = nodeService.queryConfigVariables(connectionId, node, configurationVariables); LOGGER.info("Current configurationVariables: {}", configurationVariables); node.setConfigVariables(configurationVariables); } else { LOGGER.warn("The CV values of the node are not exported!"); } boolean nodeHasFlatPortModel = node.getNode().isPortFlatModelAvailable(); LOGGER.info("Prepare the nodeState, nodeHasFlatPortModel: {}", nodeHasFlatPortModel); if (loadMacroContent && node.hasUnloadedMacros()) { LOGGER.info("Load the macro content of the node before export: {}", node); List macroList = new LinkedList<>(); for (Macro macro : node.getMacros()) { if (macro.getMacroSaveState() != MacroSaveState.PERMANENTLY_STORED_ON_NODE) { LOGGER.info("Load macro content for macro: {}", macro); NodeUtils .loadMacroContentFromNode(ConnectionRegistry.CONNECTION_ID_MAIN, nodeService, switchingNodeService, node, macro); } // // check if the node was removed ... // if (!node.getNode().isRegistered()) { // break; // } // // Macro macroWithContent = // switchingNodeService.getMacroContent(connectionId, node.getSwitchingNode(), macro); // LOGGER.info("Load macro content: {}", macroWithContent); // // // reset the changed flag on the macro // macroWithContent.setMacroSaveState(MacroSaveState.PERMANENTLY_STORED_ON_NODE); // macroWithContent.setFlatPortModel(nodeHasFlatPortModel); // // macroList.add(macroWithContent); } // LOGGER.info("Set the new macros for the node: {}", macroList); // node.setMacros(macroList); // TODO check if the accessories are loaded !!! } } public static Macro loadMacroContentFromNode( String connectionId, final NodeService nodeService, final SwitchingNodeService switchingNodeService, final NodeInterface node, final Macro macro) { // check if the node was removed ... if (!node.getNode().isRegistered()) { return macro; } Macro macroWithContent = switchingNodeService.getMacroContent(connectionId, node.getSwitchingNode(), macro); LOGGER.info("Load macro content: {}", macroWithContent); // transfer the functions to the macro macro.setFunctions(macroWithContent.getFunctions()); // reset the changed flag on the macro macro.setMacroSaveState(MacroSaveState.PERMANENTLY_STORED_ON_NODE); return macro; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy