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

org.bidib.wizard.api.utils.MacroUtils Maven / Gradle / Ivy

package org.bidib.wizard.api.utils;

import java.util.Arrays;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.bidib.jbidibc.messages.LcMacro;
import org.bidib.wizard.api.model.Macro;
import org.bidib.wizard.api.model.MacroRepeatDay;
import org.bidib.wizard.api.model.MacroRepeatTime;
import org.bidib.wizard.api.model.TimeStartCondition;
import org.bidib.wizard.api.model.function.Function;
import org.bidib.wizard.api.model.function.LightPortAction;
import org.bidib.wizard.api.model.function.MacroFunction;
import org.bidib.wizard.api.model.function.ServoPortAction;
import org.bidib.wizard.api.model.function.SwitchPortAction;
import org.bidib.wizard.model.status.BidibStatus;
import org.bidib.wizard.model.status.LightPortStatus;
import org.bidib.wizard.model.status.MacroStatus;
import org.bidib.wizard.model.status.SwitchPortStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

    public static Function getInvertedFunction(Function function) {
        Function currentFunction = null;
        try {
            // manipulate the function
            if (function instanceof SwitchPortAction) {
                currentFunction = (Function) function.clone();
                // invert the switch action
                SwitchPortAction switchPortAction = (SwitchPortAction) currentFunction;
                SwitchPortStatus switchPortStatus = switchPortAction.getAction();

                switchPortStatus = PortUtils.getOppositeStatus(switchPortStatus);
                switchPortAction.setAction(switchPortStatus);
            }
            else if (function instanceof LightPortAction) {
                currentFunction = (Function) function.clone();
                // change the light action
                LightPortAction lightPortAction = (LightPortAction) currentFunction;
                LightPortStatus lightPortStatus = lightPortAction.getAction();
                lightPortStatus = PortUtils.getOppositeStatus(lightPortStatus);
                lightPortAction.setAction(lightPortStatus);
            }
            else if (function instanceof ServoPortAction) {
                currentFunction = (Function) function.clone();
                // invert the servo target value
                ServoPortAction servoPortAction = (ServoPortAction) currentFunction;
                int currentValue = servoPortAction.getValue();
                int targetValue = 255 - currentValue;
                servoPortAction.setValue(targetValue);
            }
            else if (function instanceof MacroFunction) {
                currentFunction = (Function) function.clone();
                // switch the macro function
                MacroFunction macroFunction = (MacroFunction) currentFunction;
                if (MacroStatus.START.equals(macroFunction.getAction())) {
                    macroFunction.setAction(MacroStatus.STOP);
                }
                else if (MacroStatus.STOP.equals(macroFunction.getAction())) {
                    macroFunction.setAction(MacroStatus.START);
                }
            }
        }
        catch (CloneNotSupportedException ex) {
            LOGGER.warn("Clone of function is not supported: {}", function, ex);
        }
        return currentFunction;
    }

    /**
     * Apply the start clk data from the device to the macro
     * 
     * @param startClk
     *            the start clk data
     * @param macro
     *            the macro instance
     */
    public static void applyMacroStartClk(byte[] startClk, Macro macro) {

        if (startClk != null && !Arrays.equals(LcMacro.MACRO_START_OFF, startClk)) {
            int hour = startClk[1] & 0x1F;
            int minute = startClk[0] & 0x3F;
            int day = startClk[2] & 0x7;
            Calendar time = Calendar.getInstance();
            TimeStartCondition startCondition = new TimeStartCondition();

            if (hour == 25) {
                startCondition.setRepeatTime(MacroRepeatTime.WORKING_HOURLY);
                time.set(Calendar.HOUR_OF_DAY, 0);
            }
            else if (hour == 24) {
                startCondition.setRepeatTime(MacroRepeatTime.HOURLY);
                time.set(Calendar.HOUR_OF_DAY, 0);
            }
            else {
                time.set(Calendar.HOUR_OF_DAY, hour);
            }
            if (minute == 60) {
                startCondition.setRepeatTime(MacroRepeatTime.MINUTELY);
                time.set(Calendar.MINUTE, 0);
            }
            else if (minute == 61) {
                startCondition.setRepeatTime(MacroRepeatTime.HALF_HOURLY);
                time.set(Calendar.MINUTE, 0);
            }
            else if (minute == 62) {
                startCondition.setRepeatTime(MacroRepeatTime.QUARTER_HOURLY);
                time.set(Calendar.MINUTE, 0);
            }
            else {
                time.set(Calendar.MINUTE, minute);
            }
            // day handling
            if (day == 7) {
                // every day
                startCondition.setRepeatDay(MacroRepeatDay.ALL);
            }
            else {
                int d = (day + 2) % 7;
                if (d == 0) {
                    d = 7;
                }
                startCondition.setRepeatDay(MacroRepeatDay.values()[d]);
            }
            time.set(Calendar.SECOND, 0);
            startCondition.setTime(time);
            macro.addStartCondition(startCondition);
        }
        else {
            LOGGER.info("No startClk available or macro has no start time.");
        }
    }

    public static void applyMacroStartClk(int day, int hour, int minute, Macro macro) {

        Calendar time = Calendar.getInstance();
        TimeStartCondition startCondition = new TimeStartCondition();

        if (hour == 25) {
            startCondition.setRepeatTime(MacroRepeatTime.WORKING_HOURLY);
            time.set(Calendar.HOUR_OF_DAY, 0);
        }
        else if (hour == 24) {
            startCondition.setRepeatTime(MacroRepeatTime.HOURLY);
            time.set(Calendar.HOUR_OF_DAY, 0);
        }
        else {
            time.set(Calendar.HOUR_OF_DAY, hour);
        }
        if (minute == 60) {
            startCondition.setRepeatTime(MacroRepeatTime.MINUTELY);
            time.set(Calendar.MINUTE, 0);
        }
        else if (minute == 61) {
            startCondition.setRepeatTime(MacroRepeatTime.HALF_HOURLY);
            time.set(Calendar.MINUTE, 0);
        }
        else if (minute == 62) {
            startCondition.setRepeatTime(MacroRepeatTime.QUARTER_HOURLY);
            time.set(Calendar.MINUTE, 0);
        }
        else {
            time.set(Calendar.MINUTE, minute);
        }
        // day handling
        if (day == 7) {
            // every day
            startCondition.setRepeatDay(MacroRepeatDay.ALL);
        }
        else {
            int d = (day + 2) % 7;
            if (d == 0) {
                d = 7;
            }
            startCondition.setRepeatDay(MacroRepeatDay.values()[d]);
        }
        time.set(Calendar.SECOND, 0);
        startCondition.setTime(time);
        macro.addStartCondition(startCondition);
    }

    /**
     * Check if the macro has empty steps.
     * 
     * @param macro
     *            the macro
     * @return {@code true}: empty steps were detected, {@code false}: no empty steps were detected
     */
    public static boolean hasEmptySteps(Macro macro) {

        if (CollectionUtils.isEmpty(macro.getFunctions())) {
            return true;
        }

        List> tempFunctions = new LinkedList<>();
        tempFunctions.addAll(macro.getFunctions());

        boolean filtered = CollectionUtils.filter(tempFunctions, new Predicate>() {

            @Override
            public boolean evaluate(Function function) {
                return (function != null);
            }
        });

        LOGGER.info("Macro has empty steps: {}", filtered);

        return filtered;
    }

    /**
     * Remove the empty steps in the macro.
     * 
     * @param macro
     *            the macro
     * @return {@code true}: empty steps were detected and removed, {@code false}: no empty steps were detected
     */
    public static boolean removeEmptySteps(Macro macro) {

        if (CollectionUtils.isEmpty(macro.getFunctions())) {
            return true;
        }

        List> tempFunctions = new LinkedList<>();
        tempFunctions.addAll(macro.getFunctions());

        boolean filtered = CollectionUtils.filter(tempFunctions, new Predicate>() {

            @Override
            public boolean evaluate(Function function) {
                return (function != null);
            }
        });

        if (filtered) {
            LOGGER.info("Set the filtered functions.");
            macro.setFunctions(tempFunctions);
        }

        return filtered;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy