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

org.bidib.wizard.dmx.client.model.DmxScenery Maven / Gradle / Ivy

There is a newer version: 2.0.29
Show newest version
package org.bidib.wizard.dmx.client.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.bidib.jbidibc.core.node.ConfigurationVariable;
import org.bidib.wizard.dmx.client.schema.dmxscenery.DmxChannelType;
import org.bidib.wizard.dmx.client.schema.dmxscenery.DmxDimmerType;
import org.bidib.wizard.dmx.client.schema.dmxscenery.DmxSceneryPointType;
import org.bidib.wizard.dmx.client.schema.dmxscenery.DmxSceneryPointsType;
import org.bidib.wizard.dmx.client.schema.dmxscenery.DmxSceneryType;
import org.bidib.wizard.dmx.client.schema.dmxscenery.LineColorUtils;
import org.bidib.wizard.model.dmx.DmxChannel;
import org.bidib.wizard.model.dmx.DmxChannelWrapper;
import org.bidib.wizard.model.dmx.DmxDimmer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jgoodies.binding.beans.Model;

/**
 * 
 * The DmxScenery holds the data of a single scenery. The single scenery contains points of one or more DMX
 * channels.
 */
public class DmxScenery extends Model {
    private static final Logger LOGGER = LoggerFactory.getLogger(DmxScenery.class);

    private static final long serialVersionUID = 1L;

    public static final String SCENERIES_EXTENSION = "sceneries";

    public static final String PROPERTY_NAME = "name";

    public static final String PROPERTY_DMX_DIMMERS = "dmxDimmers";

    private final String id;

    private String name;

    private List dmxDimmers = new LinkedList<>();

    /**
     * Creates a new instance of DmxScenery with the provided scenery id.
     * 
     * @param id
     *            the scenery id
     */
    public DmxScenery(final String id) {
        this.id = id;
    }

    /**
     * @return the scenery id
     */
    public String getId() {
        return id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        String oldValue = this.name;

        this.name = name;

        firePropertyChange(PROPERTY_NAME, oldValue, name);
    }

    /**
     * @return the usedChannels
     */
    public List getUsedChannels() {
        final List dmxChannels = new LinkedList<>();
        // collect the channels from the configured dimmers
        for (DmxDimmer dmxDimmer : dmxDimmers) {

            for (DmxChannel dmxChannel : dmxDimmer.getDmxChannels()) {
                dmxChannels.add(dmxChannel);
            }
        }

        return dmxChannels;
    }

    public List getDmxDimmers() {
        return dmxDimmers;
    }

    public void setDmxDimmers(List dmxDimmers) {
        List oldValue = new LinkedList<>(this.dmxDimmers);

        this.dmxDimmers.clear();
        this.dmxDimmers.addAll(dmxDimmers);

        firePropertyChange(PROPERTY_DMX_DIMMERS, oldValue, Collections.unmodifiableList(this.dmxDimmers));
    }

    public void addDmxDimmer(final DmxDimmer dmxDimmer) {
        List oldValue = new LinkedList<>(this.dmxDimmers);

        this.dmxDimmers.add(dmxDimmer);

        firePropertyChange(PROPERTY_DMX_DIMMERS, oldValue, Collections.unmodifiableList(this.dmxDimmers));
    }

    public void removeDmxDimmer(final DmxDimmer dmxDimmer) {
        List oldValue = new LinkedList<>(this.dmxDimmers);

        this.dmxDimmers.remove(dmxDimmer);

        firePropertyChange(PROPERTY_DMX_DIMMERS, oldValue, Collections.unmodifiableList(this.dmxDimmers));
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }

        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        DmxScenery that = (DmxScenery) o;

        return new EqualsBuilder().append(id, that.id).append(name, that.name).isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37).append(id).append(name).toHashCode();
    }

    @Override
    public String toString() {
        return name;
    }

    public DmxScenery withName(String name) {
        setName(name);
        return this;
    }

    public DmxScenery withDmxScenery(
        final DmxEnvironmentProvider dmxEnvironmentProvider, final DmxSceneryType dmxSceneryType,
        final Map updatedConfigVariables,
        final Consumer> checkForUnmappedChannels,
        final Consumer changedDmxChannelValue) {

        setName(dmxSceneryType.getSceneryName());

        if (CollectionUtils.isNotEmpty(dmxSceneryType.getDmxDimmer())) {
            List dmxDimmers = new ArrayList<>();
            for (DmxDimmerType dmxDimmerType : dmxSceneryType.getDmxDimmer()) {

                // create the dimmer
                final DmxDimmer dmxDimmer = new DmxDimmer().withName(dmxDimmerType.getDimmerName());
                dmxDimmers.add(dmxDimmer);

                if (CollectionUtils.isNotEmpty(dmxDimmerType.getDmxChannel())) {

                    // create the dmx channels
                    final List dmxChannels = new ArrayList<>();
                    for (DmxChannelType dmxChannelType : dmxDimmerType.getDmxChannel()) {
                        // check if the DMX channel is available
                        final int channelNumber = dmxChannelType.getChannelNumber();

                        // check if the DmxChannel is configured already
                        DmxChannelWrapper dmxChannelWrapper =
                            dmxEnvironmentProvider
                                .getConfiguredDmxChannelsMap().keySet().stream()
                                .filter(channel -> channel.getDmxChannelId().intValue() == channelNumber).findFirst()
                                .orElse(null);

                        final DmxChannel dmxChannel;
                        if (dmxChannelWrapper != null) {
                            LOGGER.info("Use existing channel wrapper: {}", dmxChannelWrapper);
                            dmxChannel = new DmxChannel(dmxDimmer, dmxChannelWrapper);
                        }
                        else {
                            LOGGER.warn("No DMX channel found in system with channel number: {}", channelNumber);
                            dmxChannel = new DmxChannel(dmxDimmer, new DmxChannelWrapper(channelNumber, -1));
                        }
                        dmxChannel.withLineColor(LineColorUtils.getColor(dmxChannelType.getLineColor()));

                        // the dmx scenery points are added after the dmx channels are mapped

                        dmxChannels.add(dmxChannel);
                    }

                    dmxDimmer.setDmxChannels(dmxChannels);

                    // check if we have unmapped channels
                    checkForUnmappedChannels.accept(dmxDimmers);

                    LOGGER.info("Checked for unmapped channels: {}", dmxDimmer);
                    for (DmxChannel dmxChannel : dmxDimmer.getDmxChannels()) {

                        if (dmxChannel.getDmxChannelWrapper().getCvNumber() == -1) {
                            DmxChannelWrapper dmxChannelWrapper =
                                dmxEnvironmentProvider
                                    .getConfiguredDmxChannelsMap().keySet().stream().filter(channel -> channel
                                        .getDmxChannelId() == dmxChannel.getDmxChannelWrapper().getDmxChannelId())
                                    .findFirst().orElse(null);
                            if (dmxChannelWrapper != null) {
                                LOGGER.info("Replace dmxChannelWrapper: {}", dmxChannelWrapper);
                                dmxChannel.setDmxChannelWrapper(dmxChannelWrapper);
                            }
                        }
                    }

                    // add the dmx scenery points
                    for (DmxChannelType dmxChannelType : dmxDimmerType.getDmxChannel()) {
                        // check if the DMX channel is available
                        final int channelNumber = dmxChannelType.getChannelNumber();

                        final DmxChannel dmxChannel =
                            dmxDimmer
                                .getDmxChannels().stream()
                                .filter(channel -> channel
                                    .getDmxChannelWrapper().getDmxChannelId().intValue() == channelNumber)
                                .findFirst().orElse(null);

                        // process the scenery points
                        if (dmxChannel != null && dmxChannelType.getDmxSceneryPoints() != null
                            && CollectionUtils.isNotEmpty(dmxChannelType.getDmxSceneryPoints().getDmxSceneryPoint())) {

                            // we must search the CV number of the dmxChannel because this is the first cv of this dmx
                            // channel
                            int cvNumber = dmxChannel.getDmxChannelWrapper().getCvNumber();

                            final List existingChannelValues =
                                dmxEnvironmentProvider
                                    .getConfiguredDmxChannelsMap().get(dmxChannel.getDmxChannelWrapper());

                            for (DmxSceneryPointType dmxSceneryPointType : dmxChannelType
                                .getDmxSceneryPoints().getDmxSceneryPoint()) {

                                // the timeOffset is the index
                                int timeOffset = dmxSceneryPointType.getTimeOffset();
                                final int brightness = dmxSceneryPointType.getBrightness();

                                // calculate the cv number of the brightness of the current time index of the dmx
                                // channel
                                int cvNum = timeOffset + cvNumber + 2;
                                final String cvName = Integer.toString(cvNum);
                                LOGGER.info("Current cvNumber: {}, cvNum: {}, cvName: {}", cvNumber, cvNum, cvName);

                                // search the existing value to update the brightness
                                existingChannelValues
                                    .stream()
                                    .filter(dcv -> Integer.toString(cvNum).equals(dcv.getConfigVar().getName()))
                                    .findFirst().ifPresentOrElse(dcv -> {
                                        LOGGER
                                            .info("Update dmxChannelValue, cvNum: {}, brightness: {}", cvNum,
                                                brightness);
                                        dcv.setNewValue(brightness);

                                        changedDmxChannelValue.accept(dcv);
                                    }, () -> {
                                        LOGGER
                                            .info("Found empty dmxChannelValue, cvNum: {}, brightness: {}", cvNum,
                                                brightness);

                                        final DmxChannelValue newValue =
                                            new DmxChannelValue(from(updatedConfigVariables, cvNum));
                                        newValue.setNewValue(brightness);

                                        existingChannelValues.add(newValue);

                                        changedDmxChannelValue.accept(newValue);
                                    });
                            }
                        }
                    }

                }
            }

            // set the dimmers
            setDmxDimmers(dmxDimmers);
        }

        return this;

    }

    private static ConfigurationVariable from(final Map configVariables, int cvNumber) {
        return configVariables.get(Integer.toString(cvNumber));
    }

    public DmxChannel withDmxChannel(
        final DmxChannel dmxChannel, DmxEnvironmentProvider dmxEnvironmentProvider, DmxChannelType dmxChannelType) {
        dmxChannel.setLineColor(LineColorUtils.getColor(dmxChannelType.getLineColor()));
        dmxChannel.setChannelName(dmxChannelType.getChannelName());
        return dmxChannel;
    }

    public DmxSceneryType fromDmxScenery(final Function> dimmerDataProvider) {

        final DmxSceneryType dmxSceneryType = new DmxSceneryType().withId(id).withSceneryName(getName());

        // TODO store the dimmers and channels
        if (CollectionUtils.isNotEmpty(dmxDimmers)) {
            for (DmxDimmer dmxDimmer : dmxDimmers) {
                DmxDimmerType dmxDimmerType =
                    new DmxDimmerType().withId(dmxDimmer.getId()).withDimmerName(dmxDimmer.getName());
                dmxSceneryType.getDmxDimmer().add(dmxDimmerType);

                // get the scenery points of the dimmer
                final List dmxDataRows = dimmerDataProvider.apply(dmxDimmer);

                if (CollectionUtils.isNotEmpty(dmxDimmer.getDmxChannels())) {

                    int dmxChannelIndex = 0;

                    for (DmxChannel dmxChannel : dmxDimmer.getDmxChannels()) {

                        Integer dmxChannelId = dmxChannel.getDmxChannelWrapper().getDmxChannelId();

                        DmxChannelType dmxChannelType =
                            new DmxChannelType()
                                .withChannelNumber(dmxChannel.getDmxChannelWrapper().getDmxChannelId())
                                .withLineColor(LineColorUtils.getColorType(dmxChannel.getLineColor()))
                                .withChannelName(dmxChannel.getChannelName());

                        dmxDimmerType.getDmxChannel().add(dmxChannelType);

                        final List dmxSceneryPoints = new LinkedList<>();
                        int timeOffset = 0;
                        // use the values from dmxDataRows
                        for (DmxDataRow dmxDataRow : dmxDataRows) {

                            // create the dmx scenery point
                            DmxSceneryPointType dmxSceneryPointType =
                                new DmxSceneryPointType()
                                    .withDmxChannelNumber(dmxChannelId)
                                    .withBrightness(dmxDataRow.getBrightness(dmxChannelIndex))
                                    .withTimeOffset(timeOffset);
                            dmxSceneryPoints.add(dmxSceneryPointType);

                            timeOffset++;
                        }

                        dmxChannelType
                            .withDmxSceneryPoints(new DmxSceneryPointsType().withDmxSceneryPoint(dmxSceneryPoints));

                        dmxChannelIndex++;
                    }
                }
            }
        }
        return dmxSceneryType;
    }

    public static DmxScenery fromDmxSceneryType(
        final DmxSceneryType dmxSceneryType, Function dmxChannelWrapperProvider) {

        final DmxScenery dmxScenery = new DmxScenery(dmxSceneryType.getId()).withName(dmxSceneryType.getSceneryName());

        for (DmxDimmerType dmxDimmerType : dmxSceneryType.getDmxDimmer()) {
            DmxDimmer dmxDimmer = new DmxDimmer(dmxDimmerType.getId());
            dmxDimmer.setName(dmxDimmerType.getDimmerName());

            for (DmxChannelType dmxChannelType : dmxDimmerType.getDmxChannel()) {

                // TODO
                final DmxChannel dmxChannel =
                    new DmxChannel(dmxDimmer, dmxChannelWrapperProvider.apply(dmxChannelType.getChannelNumber()))
                        .withChannelName(dmxChannelType.getChannelName())
                        .withLineColor(LineColorUtils.getColor(dmxChannelType.getLineColor()));

                dmxDimmer.addDmxChannel(dmxChannel);
            }

            dmxScenery.addDmxDimmer(dmxDimmer);
        }
        // TODO

        return dmxScenery;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy