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

org.bidib.wizard.script.node.AddMacroStepCommand Maven / Gradle / Ivy

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

import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.MapUtils;
import org.bidib.wizard.comm.BidibStatus;
import org.bidib.wizard.highlight.BidibScriptScanner;
import org.bidib.wizard.highlight.Scanner;
import org.bidib.wizard.highlight.Token;
import org.bidib.wizard.highlight.TokenTypes;
import org.bidib.wizard.main.DefaultApplicationContext;
import org.bidib.wizard.mvc.main.model.AnalogPortLabels;
import org.bidib.wizard.mvc.main.model.BacklightPortLabels;
import org.bidib.wizard.mvc.main.model.ChildLabels;
import org.bidib.wizard.mvc.main.model.FeedbackPortLabels;
import org.bidib.wizard.mvc.main.model.Flag;
import org.bidib.wizard.mvc.main.model.InputPortLabels;
import org.bidib.wizard.mvc.main.model.LabelAware;
import org.bidib.wizard.mvc.main.model.LightPortLabels;
import org.bidib.wizard.mvc.main.model.MotorPortLabels;
import org.bidib.wizard.mvc.main.model.Port;
import org.bidib.wizard.mvc.main.model.PortsProvider;
import org.bidib.wizard.mvc.main.model.ServoPort;
import org.bidib.wizard.mvc.main.model.ServoPortLabels;
import org.bidib.wizard.mvc.main.model.SoundPortLabels;
import org.bidib.wizard.mvc.main.model.SwitchPortLabels;
import org.bidib.wizard.mvc.main.model.function.Delayable;
import org.bidib.wizard.mvc.main.model.function.FlagFunction;
import org.bidib.wizard.mvc.main.model.function.Function;
import org.bidib.wizard.mvc.main.model.function.MacroFunction;
import org.bidib.wizard.mvc.main.model.function.PortAction;
import org.bidib.wizard.mvc.main.model.function.PortValueAware;
import org.bidib.wizard.mvc.main.model.function.ServoMoveQueryFunction;
import org.bidib.wizard.mvc.script.view.NodeScripting;
import org.bidib.wizard.mvc.script.view.ScriptParser;
import org.bidib.wizard.script.AbstractScriptCommand;
import org.bidib.wizard.utils.PortListUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AddMacroStepCommand extends AbstractScriptCommand
    implements LabelAware, Delayable, ActionAware, TargetAware, FunctionAware {
    private static final long serialVersionUID = 1L;

    private static final Logger LOGGER = LoggerFactory.getLogger(AddMacroStepCommand.class);

    public static final String KEY = "addMacroStep";

    private Long uuid;

    private String label;

    private Integer stepNumber;

    private Function function;

    private Integer delay;

    private Integer target;

    private BidibStatus action;

    // the port label is only used if the port number is not provided directly
    private String portLabel;

    protected AddMacroStepCommand() {
        super(KEY);
    }

    public AddMacroStepCommand(Long uuid) {
        super(KEY);
        this.uuid = uuid;
    }

    @Override
    public void setFunction(Function function) {
        this.function = function;
        if (action != null) {
            LOGGER.info("Set the action that is stored.");
            function.setAction(action);
        }
    }

    public Function getFunction() {
        return function;
    }

    /**
     * @return the stepNumber
     */
    public Integer getStepNumber() {
        return stepNumber;
    }

    /**
     * @param stepNumber
     *            the stepNumber to set
     */
    public void setStepNumber(Integer stepNumber) {
        LOGGER.info("Set the stepNumber: {}", stepNumber);
        this.stepNumber = stepNumber;
    }

    @Override
    public String getLabel() {
        return label;
    }

    @Override
    public void setLabel(String label) {
        this.label = label;
    }

    @Override
    public int getDelay() {
        return (delay != null ? delay : 0);
    }

    @Override
    public void setDelay(int delay) {
        this.delay = delay;

        if (function instanceof Delayable) {
            ((Delayable) function).setDelay(delay);
        }
    }

    public void setAction(BidibStatus action) {
        LOGGER.info("Set the action: {}", action);
        this.action = action;
        if (function != null) {
            LOGGER.info("Set the action on the function that is stored.");
            ((Function) function).setAction(action);
        }
    }

    @Override
    public void setTarget(Integer target) {
        LOGGER.info("Set the target value: {}", target);
        this.target = target;
    }

    /**
     * @return the portLabel
     */
    public String getPortLabel() {
        return portLabel;
    }

    /**
     * @param portLabel
     *            the portLabel to set
     */
    public void setPortLabel(String portLabel) {
        this.portLabel = portLabel;
    }

    @Override
    public void parse(String commandLine) {
        LOGGER.info("Parse the command line: {}", commandLine);
    }

    public void scan(Scanner scanner, int index, final Map context) {

        for (int i = index + 1; i < scanner.size(); i++) {
            Token token = scanner.getToken(i);
            LOGGER.info("scan, current index: {}, token symbol: {}, name: {}", i, token.symbol.type, token.symbol.name);
            switch (token.symbol.type) {
                case TokenTypes.KEYWORD2:
                    switch (token.symbol.name) {
                    // case BidibScriptScanner.KEY2_LABEL:
                        case BidibScriptScanner.KEY2_NAME:
                            // label detected
                            StringValueCallback labelAware = new StringValueCallback() {
                                @Override
                                public void setString(String label) {
                                    LOGGER.info("Set the port label: {}", label);
                                    portLabel = label;
                                }
                            };
                            i = NodeScriptUtils.parseLabel(scanner, i, labelAware, context);
                            break;
                        case BidibScriptScanner.KEY2_PTYPE:
                            // ptype detected
                            i = NodeScriptUtils.parsePtype(scanner, i, context, this);
                            break;
                        case BidibScriptScanner.KEY2_DELAY:
                            // delay detected
                            i = NodeScriptUtils.parseDelay(scanner, i, this, context);
                            break;
                        case BidibScriptScanner.KEY2_ACTION:
                            // action detected
                            i = NodeScriptUtils.parseAction(scanner, i, this, context);
                            break;
                        case BidibScriptScanner.KEY2_TARGET:
                            // target detected
                            i = NodeScriptUtils.parseTarget(scanner, i, this, context);
                            break;
                        case BidibScriptScanner.KEY2_NUMBER:
                            // number detected
                            NumberAware numberAware = new NumberAware() {

                                @Override
                                public void setNumber(Integer number) {
                                    // if the current function is a macro function we must set the macro id
                                    if (function != null) {
                                        if (function instanceof MacroFunction) {
                                            MacroFunction macroFunction = (MacroFunction) function;
                                            LOGGER.info("Set the macro id: {}", number);
                                            macroFunction.setMacroId(number);
                                        }
                                        else if (function instanceof PortAction) {
                                            PortAction portAction = (PortAction) function;
                                            String actionKey = portAction.getKey();
                                            LOGGER.info("Set the port id: {}, actionKey: {}", number, actionKey);

                                            Integer portId = number;
                                            // set the port with the provided number
                                            PortsProvider portsProvider =
                                                DefaultApplicationContext.getInstance().get(
                                                    DefaultApplicationContext.KEY_PORTS_PROVIDER, PortsProvider.class);
                                            Port port = null;
                                            switch (portAction.getKey()) {
                                                case Function.KEY_ANALOG:
                                                    port =
                                                        PortListUtils.findPortByPortNumber(
                                                            portsProvider.getAnalogPorts(), portId);
                                                    break;
                                                case Function.KEY_BACKLIGHT:
                                                    port =
                                                        PortListUtils.findPortByPortNumber(
                                                            portsProvider.getBacklightPorts(), portId);
                                                    break;
                                                case Function.KEY_FEEDBACK:
                                                    port =
                                                        PortListUtils.findPortByPortNumber(
                                                            portsProvider.getFeedbackPorts(), portId);
                                                    break;
                                                case Function.KEY_INPUT:
                                                    port =
                                                        PortListUtils.findPortByPortNumber(
                                                            portsProvider.getEnabledInputPorts(), portId);
                                                    break;
                                                case Function.KEY_LIGHT:
                                                    port =
                                                        PortListUtils.findPortByPortNumber(
                                                            portsProvider.getLightPorts(), portId);
                                                    break;
                                                case Function.KEY_MOTOR:
                                                    port =
                                                        PortListUtils.findPortByPortNumber(
                                                            portsProvider.getMotorPorts(), portId);
                                                    break;
                                                case Function.KEY_SERVO:
                                                    port =
                                                        PortListUtils.findPortByPortNumber(
                                                            portsProvider.getServoPorts(), portId);
                                                    break;
                                                case Function.KEY_SOUND:
                                                    port =
                                                        PortListUtils.findPortByPortNumber(
                                                            portsProvider.getSoundPorts(), portId);
                                                    break;
                                                case Function.KEY_SWITCH:
                                                    port =
                                                        PortListUtils.findPortByPortNumber(
                                                            portsProvider.getEnabledSwitchPorts(), portId);
                                                    break;
                                                default:
                                                    break;
                                            }

                                            if (port != null) {
                                                portAction.setPort(port);
                                            }
                                            else {
                                                LOGGER.warn("No port found for port number: {}, actionKey: {}", portId,
                                                    actionKey);
                                            }
                                        }
                                        else if (function instanceof FlagFunction) {
                                            FlagFunction flagFunction = (FlagFunction) function;
                                            String actionKey = flagFunction.getKey();
                                            Flag flag = flagFunction.getFlag();
                                            LOGGER.info("Set the flag number: {}, actionKey: {}, flag: {}", number,
                                                actionKey, flag);

                                        }
                                    }
                                    else {
                                        LOGGER.warn("Unknown parameter number detected, value: {}", number);
                                    }
                                }
                            };
                            i = NodeScriptUtils.parseNumber(scanner, i, numberAware, context);
                            break;
                        default:
                            break;
                    }
                    break;
                case TokenTypes.NUMBER:
                    // set the step number
                    setStepNumber(Integer.valueOf(token.symbol.name));
                    break;
                default:
                    break;
            }

            LOGGER.info("scan, i after parse: {}, last symbol name: {}", i, token.symbol.name);
        }
    }

    @Override
    protected void internalExecute(final NodeScripting scripting, final Map context) {
        LOGGER.info("Set the macro step: {}", this);
    }

    public void prepareFunction(final Map context) {

        // if the current function is a macro function we must set the macro id
        if (function != null) {
            if (function instanceof MacroFunction) {
                MacroFunction macroFunction = (MacroFunction) function;
                LOGGER.info("Search the macro with portLabel: {}", portLabel);

                // get the corresponding macro number
                // MacroLabels macroLabels =
                // DefaultApplicationContext.getInstance().get(DefaultApplicationContext.KEY_MACRO_LABELS,
                // MacroLabels.class);
                // Integer macroId = macroLabels.getIdByLabel(uuid, portLabel);

                Map macroLabels = (Map) context.get(ScriptParser.KEY_MACRO_LABELS);
                Integer macroId = MapUtils.invertMap(macroLabels).get(portLabel);
                if (macroId != null) {
                    macroFunction.setMacroId(macroId);
                }
                else {
                    LOGGER.warn("No corresponding macro number found for macroName: {}", portLabel);
                }
            }
            else if (function instanceof PortAction) {
                PortAction portAction = (PortAction) function;

                if (portAction.getPort() != null) {
                    LOGGER.info("The port is set already. Skip replace port.");

                }
                else {

                    LOGGER.info("Set the port id: {}", portLabel);

                    PortsProvider portsProvider =
                        DefaultApplicationContext.getInstance().get(DefaultApplicationContext.KEY_PORTS_PROVIDER,
                            PortsProvider.class);
                    Port port = null;
                    Integer portId = null;

                    // TODO it's to early here if the label was changed in the script before
                    // TODO we must replace the labels in the execution step
                    ChildLabels labels = null;
                    switch (portAction.getKey()) {
                        case Function.KEY_ANALOG:
                            labels =
                                DefaultApplicationContext.getInstance().get(
                                    DefaultApplicationContext.KEY_ANALOGPORT_LABELS, AnalogPortLabels.class);
                            portId = labels.getIdByLabel(uuid, portLabel);
                            if (portId != null) {
                                port = PortListUtils.findPortByPortNumber(portsProvider.getAnalogPorts(), portId);
                            }
                            else {
                                LOGGER.warn("The analog port name could no be resolved: {}", label);
                            }
                            break;
                        case Function.KEY_BACKLIGHT:
                            labels =
                                DefaultApplicationContext.getInstance().get(
                                    DefaultApplicationContext.KEY_BACKLIGHTPORT_LABELS, BacklightPortLabels.class);
                            portId = labels.getIdByLabel(uuid, portLabel);
                            if (portId != null) {
                                port = PortListUtils.findPortByPortNumber(portsProvider.getBacklightPorts(), portId);
                            }
                            else {
                                LOGGER.warn("The backlight port name could no be resolved: {}", label);
                            }
                            break;
                        case Function.KEY_FEEDBACK:
                            labels =
                                DefaultApplicationContext.getInstance().get(
                                    DefaultApplicationContext.KEY_FEEDBACKPORT_LABELS, FeedbackPortLabels.class);
                            portId = labels.getIdByLabel(uuid, portLabel);
                            if (portId != null) {
                                port = PortListUtils.findPortByPortNumber(portsProvider.getFeedbackPorts(), portId);
                            }
                            else {
                                LOGGER.warn("The feedback port name could no be resolved: {}", portLabel);
                            }
                            break;
                        case Function.KEY_INPUT:
                            labels =
                                DefaultApplicationContext.getInstance().get(
                                    DefaultApplicationContext.KEY_INPUTPORT_LABELS, InputPortLabels.class);
                            portId = labels.getIdByLabel(uuid, portLabel);
                            if (portId != null) {
                                port = PortListUtils.findPortByPortNumber(portsProvider.getEnabledInputPorts(), portId);
                            }
                            else {
                                LOGGER.warn("The input port name could no be resolved: {}", portLabel);
                            }
                            break;
                        case Function.KEY_LIGHT:
                            labels =
                                DefaultApplicationContext.getInstance().get(
                                    DefaultApplicationContext.KEY_LIGHTPORT_LABELS, LightPortLabels.class);
                            portId = labels.getIdByLabel(uuid, portLabel);
                            if (portId != null) {
                                port = PortListUtils.findPortByPortNumber(portsProvider.getLightPorts(), portId);
                            }
                            else {
                                LOGGER.warn("The light port name could no be resolved: {}", portLabel);
                            }
                            break;
                        case Function.KEY_MOTOR:
                            labels =
                                DefaultApplicationContext.getInstance().get(
                                    DefaultApplicationContext.KEY_MOTORPORT_LABELS, MotorPortLabels.class);
                            portId = labels.getIdByLabel(uuid, portLabel);
                            if (portId != null) {
                                port = PortListUtils.findPortByPortNumber(portsProvider.getMotorPorts(), portId);
                            }
                            else {
                                LOGGER.warn("The motor port name could no be resolved: {}", portLabel);
                            }
                            break;
                        case Function.KEY_SERVO:
                            labels =
                                DefaultApplicationContext.getInstance().get(
                                    DefaultApplicationContext.KEY_SERVOPORT_LABELS, ServoPortLabels.class);
                            portId = labels.getIdByLabel(uuid, portLabel);
                            if (portId != null) {
                                port = PortListUtils.findPortByPortNumber(portsProvider.getServoPorts(), portId);
                            }
                            else {
                                LOGGER.warn("The servo port name could no be resolved: {}", portLabel);
                            }
                            break;
                        case Function.KEY_SOUND:
                            labels =
                                DefaultApplicationContext.getInstance().get(
                                    DefaultApplicationContext.KEY_SOUNDPORT_LABELS, SoundPortLabels.class);
                            portId = labels.getIdByLabel(uuid, portLabel);
                            if (portId != null) {
                                port = PortListUtils.findPortByPortNumber(portsProvider.getSoundPorts(), portId);
                            }
                            else {
                                LOGGER.warn("The sound port name could no be resolved: {}", portLabel);
                            }
                            break;
                        case Function.KEY_SWITCH:
                            labels =
                                DefaultApplicationContext.getInstance().get(
                                    DefaultApplicationContext.KEY_SWITCHPORT_LABELS, SwitchPortLabels.class);
                            portId = labels.getIdByLabel(uuid, portLabel);
                            LOGGER.info("Lookup for switchPort with label: {}, returned portId: {}", portLabel, portId);
                            if (portId != null) {
                                port =
                                    PortListUtils.findPortByPortNumber(portsProvider.getEnabledSwitchPorts(), portId);
                            }
                            else {
                                LOGGER.warn("The switch port name could no be resolved: {}", label);
                            }
                            break;
                        default:
                            LOGGER.warn("Unsupported port key detected: {}", portAction.getKey());
                            break;
                    }
                    LOGGER.info("Set the port: {}", port);
                    portAction.setPort(port);
                }

                if (target != null && portAction instanceof PortValueAware) {
                    ServoPort servoPort = (ServoPort) portAction.getPort();
                    int absoluteValue = servoPort.getAbsoluteValue(target);
                    LOGGER.info("Prepared absolute value: {} from target: {}", absoluteValue, target);
                    ((PortValueAware) portAction).setValue(absoluteValue);
                }
            }
            else if (function instanceof FlagFunction) {
                FlagFunction flagFunction = (FlagFunction) function;
                LOGGER.info("Set the flag function: {}", flagFunction);

                PortsProvider portsProvider =
                    DefaultApplicationContext.getInstance().get(DefaultApplicationContext.KEY_PORTS_PROVIDER,
                        PortsProvider.class);

                List flags = portsProvider.getFlags();

                // set the flag
                if (target != null) {
                    LOGGER.info("Get the flag for target: {}", target);
                    flagFunction.setFlag(flags.get(target));
                }
            }
            else if (function instanceof ServoMoveQueryFunction) {
                ServoMoveQueryFunction servoMoveQueryFunction = (ServoMoveQueryFunction) function;
                LOGGER.info("Set the servoMoveQuery function: {}", servoMoveQueryFunction);

                ChildLabels labels =
                    DefaultApplicationContext.getInstance().get(DefaultApplicationContext.KEY_SERVOPORT_LABELS,
                        ServoPortLabels.class);
                Integer portId = labels.getIdByLabel(uuid, portLabel);
                if (portId != null) {
                    PortsProvider portsProvider =
                        DefaultApplicationContext.getInstance().get(DefaultApplicationContext.KEY_PORTS_PROVIDER,
                            PortsProvider.class);

                    ServoPort port = PortListUtils.findPortByPortNumber(portsProvider.getServoPorts(), portId);

                    LOGGER.info("Set the port: {}", port);
                    servoMoveQueryFunction.setPort(port);
                }
                else {
                    LOGGER.warn("The servo port name could no be resolved: {}", portLabel);
                }
            }

            // check for delay
            if (function instanceof Delayable) {
                ((Delayable) function).setDelay(getDelay());
            }
        }
        else {
            LOGGER.warn("No function available.");
        }
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer("[");
        sb.append(getClass().getSimpleName());
        sb.append(", uuid: ").append(uuid);
        sb.append(", stepNumber: ").append(stepNumber).append(", function: ").append(function);
        sb.append(", action: ").append(action).append(", label: ").append(label);
        if (target != null) {
            sb.append(", target: ").append(target);
        }
        sb.append("]");
        return sb.toString();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy