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

missingOldImpl.LedStripV2 Maven / Gradle / Ivy

package berlin.yuna.tinkerforgesensor.model.missing;

import berlin.yuna.tinkerforgesensor.model.exception.NetworkConnectionException;
import berlin.yuna.tinkerforgesensor.model.sensor.Sensor;
import berlin.yuna.tinkerforgesensor.model.threads.Color;
import berlin.yuna.tinkerforgesensor.model.thread.LedChipType;
import com.tinkerforge.BrickletLEDStripV2;
import com.tinkerforge.Device;
import com.tinkerforge.TinkerforgeException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static berlin.yuna.tinkerforgesensor.model.LedStatusType.LED_OFF;
import static berlin.yuna.tinkerforgesensor.model.sensor.SensorUtils.ledStatusConfig;
import static berlin.yuna.tinkerforgesensor.model.threads.Color.BLACK;
import static berlin.yuna.tinkerforgesensor.model.threads.Color.GREEN;
import static berlin.yuna.tinkerforgesensor.model.threads.Color.RAINBOW;
import static berlin.yuna.tinkerforgesensor.model.threads.Color.toRGB;
import static berlin.yuna.tinkerforgesensor.model.ValueType.DEVICE_TIMEOUT;
import static java.util.Arrays.copyOfRange;
import static java.util.Arrays.stream;
import static java.util.Collections.nCopies;

/**
 * 

{@link LedStripV2}


* Controls up to 2048 RGB(W) LEDs
* *

Before the start

* This bricklet is not starting without knowing the number of LEDs and the ChipType
*
[Setup] Setting number of leds to 30 and chip type to "WS2812" {@link LedChipType}
* sensor.send('C', 30, "WS2812"); * sensor.send('C', 30, LED_TYPE_WS2812); * *

Technical Info

* *
Set led 1 to magenta
* sensor.send(Color.Magenta); *
Set led 1 to magenta and led 2 to green
* sensor.send(Color.Magenta, Color.Green); *
Set led 4 to red
* sensor.send(4, Color.Red); *
Set all led's to black/off
* sensor.send(-1, Color.Black); *
Set all led's to Black but don't update
* sensor.send(false, -1, Color.Black); *
[Config] Set the refresh period of the led's
* sensor.refreshLimit(30); */ public class LedStripV2 extends Sensor { private LedChipType chipType; private final List ledList = new ArrayList<>(); public LedStripV2(final Device device, final String uid) throws NetworkConnectionException { super((BrickletLEDStripV2) device, uid); } @Override protected Sensor initListener() { refreshPeriod(50); return this; } @Override public Sensor send(final Object value) { return send(1, value); } @Override public Sensor send(final Object... values) { if (values.length > 0 && values[0] instanceof Boolean) { if (values.length == 1 && ((Boolean) values[0])) { update(); } return process(((Boolean) values[0]), copyOfRange(values, 1, values.length)); } return process(true, values); } public Sensor process(final boolean update, final Object... values) { if (values.length > 2 && values[0] instanceof Character && values[1] instanceof Number) { //[LedNumber, chipType] setChipTypeAndLedNumber(((Number) values[1]), values[2]); } else if (everyTypeIsColorAwt(values)) { //[awt.Color...] to [Color...] process(update, stream(values).map(Color::toColor).toArray()); } else if (everyTypeIsColor(values)) { //[Color...] to [Index, Rgb...] process(update, addIndexToColor(values)); } else if (containsNumbers(values) && (containsColor(values) || containsColorAwt(values))) { //[Index, Color...] to [Index Rgb...] process(update, stream(values).map(Color::toRGB).toArray()); } else if (values.length > 1 && stream(values).allMatch(v -> v instanceof Number)) { //[Index, Rgb...] Take Action setLeds(update, stream(values).mapToInt(o -> ((Number) o).intValue()).toArray()); } return this; } @Override public Sensor setLedStatus(final Integer value) { ledStatusConfig(this, value, result -> device.setStatusLEDConfig((short) result.intValue())); return this; } @Override public Sensor ledAdditional(final Integer value) { return this; } @Override public Sensor initLedConfig() { try { ledStatus = LedStatusType.ledStatusTypeOf(device.getStatusLEDConfig()); ledAdditional = LED_OFF; } catch (TinkerforgeException ignored) { sendEvent(DEVICE_TIMEOUT, 404L); } return this; } @Override public Sensor refreshPeriod(final int milliseconds) { try { device.setFrameDuration(milliseconds); } catch (TinkerforgeException ignored) { sendEvent(DEVICE_TIMEOUT, 404L); } return this; } private Object[] addIndexToColor(final Object[] values) { final List result = new ArrayList<>(); for (int i = 0; i < values.length; i++) { result.add(i); result.add(toRGB(values[0]).orElse(0)); } return result.toArray(); } private boolean everyTypeIsColorAwt(final Object[] values) { return stream(values).allMatch(v -> v instanceof java.awt.Color); } private boolean everyTypeIsColor(final Object[] values) { return stream(values).allMatch(v -> v instanceof Color); } private boolean containsColorAwt(final Object[] values) { return stream(values).anyMatch(v -> v instanceof java.awt.Color); } private boolean containsColor(final Object[] values) { return stream(values).anyMatch(v -> v instanceof Color); } private boolean containsNumbers(final Object[] values) { return stream(values).anyMatch(v -> v instanceof Number); } private void setChipTypeAndLedNumber(final Number LedNumber, final Object chipTypeObj) { final Optional chipType = getChipType(chipTypeObj); if (chipType.isPresent()) { if (chipType.get() != this.chipType) { setChipType(chipType.get()); } if (LedNumber.intValue() != ledList.size()) { setLedNumber(LedNumber.intValue()); } } } private Optional getChipType(final Object value) { if (value instanceof String) { final String chipType = (String) value; return stream(LedChipType.values()).filter(lt -> lt.name().toLowerCase().contains((chipType).toLowerCase())).findFirst(); } else if (value instanceof LedChipType) { return Optional.of((LedChipType) value); } // else if (value instanceof Number) { // final Integer chipType = (Integer) value; // return stream(LedChipType.values()).filter(lt -> lt.value() == chipType).findFirst().orElse(null); // } return Optional.empty(); } private void setChipType(final LedChipType ledChipType) { try { this.chipType = ledChipType; device.setChipType(ledChipType.value()); device.setChannelMapping(ledChipType.channel()); } catch (TinkerforgeException ignored) { sendEvent(DEVICE_TIMEOUT, 404L); } } private void setLedNumber(final int ledNumber) { final List rainbow = new ArrayList<>(); do { rainbow.addAll(stream(RAINBOW).boxed().collect(Collectors.toList())); } while (rainbow.size() < ledNumber); ledList.clear(); ledList.addAll(new ArrayList<>(nCopies(ledNumber, BLACK))); try { for (int i = 0; i < ledList.size(); i++) { send(i, GREEN); if (i != 0) { send(i - 1, rainbow.get(i * (rainbow.size() / 150))); } Thread.sleep(4); } ledList.clear(); ledList.addAll(new ArrayList<>(nCopies(ledNumber, BLACK))); update(); } catch (InterruptedException ignored) { sendEvent(DEVICE_TIMEOUT, 404L); } } private void setLed(final int index, final int color) { if (index >= 0 && index < ledList.size()) { ledList.set(index, color); } } private Sensor setLeds(final boolean update, final int[] colors) { //[-1, AllInt] Take Action if (((Number) colors[0]).intValue() == -1) { final int ledNumber = ledList.size(); ledList.clear(); ledList.addAll(new ArrayList<>(nCopies(ledNumber, ((Number) colors[1]).intValue()))); if (update) { update(); } return this; } else { //[Int, Int...] Take Action for (int i = 0; i < colors.length; i = i + 2) { setLed(((Number) colors[i]).intValue() - 1, ((Number) colors[i + 1]).intValue()); } if (update) { update(); } return this; } } private void update() { try { device.setLEDValues(0, ledList.stream().map(this::mapColor).flatMapToInt(Arrays::stream).toArray()); } catch (TinkerforgeException ignored) { sendEvent(DEVICE_TIMEOUT, 404L); } } private int[] mapColor(final int rgb) { return mapColor(new Color(rgb)); } private int[] mapColor(final Color color) { final int[] result = new int[chipType.mapping().length]; result[0] = color.getRed(); result[1] = color.getGreen(); result[2] = color.getBlue(); if (result.length > 3) { //TODO: how to get brightness from color? result[3] = color.getAlpha(); } return result; } }