package de.ctdo.bunti.dmx; import de.ctdo.bunti.DeviceChangedEvent; import de.ctdo.bunti.artnet.SimpleArtNetSender; import de.ctdo.bunti.model.BuntiDMXDevice; import de.ctdo.bunti.model.BuntiDevice; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.scheduling.annotation.Scheduled; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class DMXMixerImpl implements DMXMixer, ApplicationListener { private static final Logger LOGGER = LoggerFactory.getLogger(DMXMixerImpl.class); private static final int NET_SEND_INTERVAL = 100; private String artNetDeviceAddress; private final Map dmxMap = Collections.synchronizedMap(new HashMap()); private SimpleArtNetSender artNetSender; private boolean hasDataChanged = true; @Autowired public final void setArtNetSender(SimpleArtNetSender artNetSender) { this.artNetSender = artNetSender; } public void setArtNetDeviceAddress(String artNetDeviceAddress) { this.artNetDeviceAddress = artNetDeviceAddress; } private void initDMXData() { for (int i = DMX.DMX_CHANNEL_INDEX_MIN; i <= DMX.DMX_CHANNEL_INDEX_MAX; i++) { dmxMap.put(i, DMX.DMX_CHANNEL_VALUE_MIN); } } @Scheduled(fixedDelay = NET_SEND_INTERVAL) public final void sendOutDMXBuffer() { if (dmxMap.size() == 0) { initDMXData(); } if (hasDataChanged) { LOGGER.debug("sending DMX Data"); artNetSender.sendDMXData(dmxMap, artNetDeviceAddress); hasDataChanged = false; } } @Override public final boolean updateDevice(BuntiDevice device, Map options) { if(device == null || options == null || options.size() == 0) { return false; } BuntiDMXDevice dmxDev = (BuntiDMXDevice) device; if (dmxDev.setValuesFromOptions(options)) { dmxMap.putAll(dmxDev.getChannelData()); LOGGER.info("setValuesFromOptions on " + device); return true; } LOGGER.info("setValuesFromOptions on " + device + " failed"); return false; } @Override public final boolean setDMX512Channel(int channel, int value) { if (!DMX.checkChannelBoundaries(channel)) { return false; } dmxMap.put(channel, DMX.sanitizeDMXValue(value)); hasDataChanged = true; return true; } @Override public final void onApplicationEvent(DeviceChangedEvent arg0) { if (arg0.getDevice() instanceof BuntiDMXDevice) { updateDevice(arg0.getDevice(), arg0.getOptions()); hasDataChanged = true; // TODO: hier kann man z.B. auch noch direkt einmal die DMX Daten zu verschicken veranlassen } } }