/**
 * Copyright (c) 2010-2020 Contributors to the openHAB project
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */

 /* ***********************************************************
 * This file was automatically generated on 2022-01-03.      *
 *                                                           *
 * openHAB Bindings Version 2.0.0                            *
 *                                                           *
 * If you have a bugfix for this file and want to commit it, *
 * please fix the bug in the generator. You can find a link  *
 * to the generators git repository on tinkerforge.com       *
 *************************************************************/

package org.openhab.binding.tinkerforge.internal.device;

import java.net.URI;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.eclipse.smarthome.config.core.Configuration;
import org.eclipse.smarthome.config.core.ConfigDescription;
import org.eclipse.smarthome.config.core.ConfigDescriptionBuilder;
import org.eclipse.smarthome.config.core.ConfigDescriptionParameter.Type;
import org.eclipse.smarthome.config.core.ConfigDescriptionParameterBuilder;
import org.eclipse.smarthome.config.core.ConfigDescriptionParameterGroup;
import org.eclipse.smarthome.config.core.ParameterOption;
import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.core.types.StateOption;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.CommandDescriptionBuilder;
import org.eclipse.smarthome.core.types.CommandOption;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.ThingStatus;
import org.eclipse.smarthome.core.thing.ThingTypeUID;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;
import org.eclipse.smarthome.core.thing.type.ChannelDefinitionBuilder;
import org.eclipse.smarthome.core.thing.type.ChannelType;
import org.eclipse.smarthome.core.thing.type.ChannelTypeBuilder;
import org.eclipse.smarthome.core.thing.type.ChannelTypeUID;
import org.eclipse.smarthome.core.types.RefreshType;
import org.eclipse.smarthome.core.thing.type.ThingType;
import org.eclipse.smarthome.core.thing.type.ThingTypeBuilder;
import org.eclipse.smarthome.core.types.StateDescriptionFragmentBuilder;
import org.openhab.binding.tinkerforge.internal.TinkerforgeBindingConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.smarthome.core.library.types.DecimalType;
import org.eclipse.smarthome.core.library.types.QuantityType;
import org.eclipse.smarthome.core.library.unit.MetricPrefix;
import org.eclipse.smarthome.core.library.unit.SIUnits;
import org.eclipse.smarthome.core.library.unit.SmartHomeUnits;
import org.eclipse.smarthome.core.library.types.OpenClosedType;
import org.eclipse.smarthome.core.library.types.StringType;

import com.tinkerforge.BrickletMultiTouchV2;
import com.tinkerforge.IPConnection;
import com.tinkerforge.TinkerforgeException;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;

/**
 * Wraps the Java Bindings of the Multi Touch Bricklet 2.0.
 * @author Erik Fleckstein - Initial contribution
 */
@NonNullByDefault
public class BrickletMultiTouchV2Wrapper extends BrickletMultiTouchV2 implements CoMCUFlashable, DeviceWrapper {
    public static final DeviceInfo DEVICE_INFO = new DeviceInfo(BrickletMultiTouchV2.DEVICE_DISPLAY_NAME, "brickletmultitouchv2", BrickletMultiTouchV2.DEVICE_IDENTIFIER, BrickletMultiTouchV2Wrapper.class, BrickletMultiTouchV2Actions.class, "2.0.0", true);

    public BrickletMultiTouchV2Wrapper(String uid, IPConnection ipcon) {
        super(uid, ipcon);
    }

    private List<ScheduledFuture<?>> manualChannelUpdates = new ArrayList<>();
    private List<ListenerReg<?>> listenerRegs = new ArrayList<>();

    public void cancelManualUpdates() {
        manualChannelUpdates.forEach(f -> f.cancel(true));
    }

    public <T> T reg(T listener, Consumer<T> toRemove) {
        listenerRegs.add(new ListenerReg<T>(listener, toRemove));
        return listener;
    }

    
    private final Logger logger = LoggerFactory.getLogger(BrickletMultiTouchV2Wrapper.class);

    @Override
    public void initialize(org.eclipse.smarthome.config.core.Configuration config, Function<String, org.eclipse.smarthome.config.core.Configuration> getChannelConfigFn, BiConsumer<String, org.eclipse.smarthome.core.types.State> updateStateFn, BiConsumer<String, String> triggerChannelFn, ScheduledExecutorService scheduler, BaseThingHandler handler) throws TinkerforgeException {
        this.setResponseExpectedAll(true);
        BrickletMultiTouchV2Config cfg = (BrickletMultiTouchV2Config) config.as(BrickletMultiTouchV2Config.class);
        if(cfg.electrode0Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode0", transformBrickletMultiTouchV2Electrode0Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode1Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode1", transformBrickletMultiTouchV2Electrode1Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode2Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode2", transformBrickletMultiTouchV2Electrode2Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode3Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode3", transformBrickletMultiTouchV2Electrode3Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode4Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode4", transformBrickletMultiTouchV2Electrode4Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode5Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode5", transformBrickletMultiTouchV2Electrode5Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode6Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode6", transformBrickletMultiTouchV2Electrode6Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode7Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode7", transformBrickletMultiTouchV2Electrode7Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode8Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode8", transformBrickletMultiTouchV2Electrode8Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode9Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode9", transformBrickletMultiTouchV2Electrode9Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode10Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode10", transformBrickletMultiTouchV2Electrode10Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.electrode11Enabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Electrode11", transformBrickletMultiTouchV2Electrode11Callback0(state, cfg));}}, this::removeTouchStateListener));}
		if(cfg.proximityEnabled) {
this.addTouchStateListener(this.reg((state) -> {if(true) {updateStateFn.accept("BrickletMultiTouchV2Proximity", transformBrickletMultiTouchV2ProximityCallback0(state, cfg));}}, this::removeTouchStateListener));}
        this.setElectrodeSensitivity(cfg.sensitivity.shortValue());
		        this.recalibrate();
		        this.setElectrodeConfig(new boolean[]{cfg.electrode0Enabled, cfg.electrode1Enabled, cfg.electrode2Enabled, cfg.electrode3Enabled, cfg.electrode4Enabled, cfg.electrode5Enabled, cfg.electrode6Enabled, cfg.electrode7Enabled, cfg.electrode8Enabled, cfg.electrode9Enabled, cfg.electrode10Enabled, cfg.electrode11Enabled, cfg.proximityEnabled});
		        this.setTouchLEDConfig(cfg.touchLEDMode);
		        this.setTouchStateCallbackConfiguration(cfg.electrodeUpdateInterval, true);
		this.setStatusLEDConfig(cfg.statusLEDConfig);
    }

    @Override
    public void dispose(org.eclipse.smarthome.config.core.Configuration config) throws TinkerforgeException {
        listenerRegs.forEach(ListenerReg::deregister);

        
        
    }

    @Override
    public List<String> getEnabledChannels(org.eclipse.smarthome.config.core.Configuration config) throws TinkerforgeException{
        BrickletMultiTouchV2Config cfg = (BrickletMultiTouchV2Config) config.as(BrickletMultiTouchV2Config.class);
List<String> result = new ArrayList<String>();
        if (cfg.electrode0Enabled) {
                result.add("BrickletMultiTouchV2Electrode0");
            }
		if (cfg.electrode1Enabled) {
                result.add("BrickletMultiTouchV2Electrode1");
            }
		if (cfg.electrode2Enabled) {
                result.add("BrickletMultiTouchV2Electrode2");
            }
		if (cfg.electrode3Enabled) {
                result.add("BrickletMultiTouchV2Electrode3");
            }
		if (cfg.electrode4Enabled) {
                result.add("BrickletMultiTouchV2Electrode4");
            }
		if (cfg.electrode5Enabled) {
                result.add("BrickletMultiTouchV2Electrode5");
            }
		if (cfg.electrode6Enabled) {
                result.add("BrickletMultiTouchV2Electrode6");
            }
		if (cfg.electrode7Enabled) {
                result.add("BrickletMultiTouchV2Electrode7");
            }
		if (cfg.electrode8Enabled) {
                result.add("BrickletMultiTouchV2Electrode8");
            }
		if (cfg.electrode9Enabled) {
                result.add("BrickletMultiTouchV2Electrode9");
            }
		if (cfg.electrode10Enabled) {
                result.add("BrickletMultiTouchV2Electrode10");
            }
		if (cfg.electrode11Enabled) {
                result.add("BrickletMultiTouchV2Electrode11");
            }
		if (cfg.proximityEnabled) {
                result.add("BrickletMultiTouchV2Proximity");
            }
		result.add("BrickletMultiTouchV2Recalibrate");
        return result;
    }

    public static @Nullable ChannelType getChannelType(ChannelTypeUID channelTypeUID) {
        switch(channelTypeUID.getId()) {
            case "BrickletMultiTouchV2Electrode":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode"), "NOT USED", "Contact").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletMultiTouchV2Electrode")).withDescription("The current touch state. An electrode is already counted as touched if a finger is nearly touching the electrode. This means that you can put a piece of paper or foil or similar on top of a electrode to build a touch panel with a professional look.").build();
            case "BrickletMultiTouchV2Recalibrate":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Recalibrate"), "Recalibrate Electrodes", "String").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletMultiTouchV2Recalibrate")).withDescription("Recalibrates the electrodes. Trigger this channel whenever you changed or moved you electrodes.")
.withCommandDescription(CommandDescriptionBuilder.create().withCommandOption(new CommandOption("TRIGGER", "Trigger")).build()).build();
default:
                break;
        }

        return null;
    }

    public static ThingType getThingType(ThingTypeUID thingTypeUID) {
             Map<String, String> thingTypeProperties = ThingTypeBuilder.instance(thingTypeUID, "unused").build().getProperties();
             Map<String, String> props = new HashMap<String, String>(thingTypeProperties);
             props.putIfAbsent(TinkerforgeBindingConstants.PROPERTY_MINIMUM_FIRMWARE_VERSION, DEVICE_INFO.minimumFWVersion);
        return ThingTypeBuilder.instance(thingTypeUID, "Tinkerforge Multi Touch Bricklet 2.0").isListed(false).withSupportedBridgeTypeUIDs(Arrays.asList(TinkerforgeBindingConstants.THING_TYPE_BRICK_DAEMON.toString())).withConfigDescriptionURI(URI.create("thing-type:tinkerforge:" + thingTypeUID.getId())).withDescription("Capacitive touch sensor for 12 electrodes").withChannelDefinitions(Arrays.asList(new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode0", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 0").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode1", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 1").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode2", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 2").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode3", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 3").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode4", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 4").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode5", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 5").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode6", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 6").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode7", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 7").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode8", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 8").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode9", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 9").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode10", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 10").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Electrode11", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Electrode 11").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Proximity", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Electrode")).withLabel("Proximity").withDescription("If a hand or similar is in proximity to the electrodes, this channel is toggled. The proximity is activated with a distance of 1-2cm. This means that you can put a piece of paper or foil or similar on top of a electrode to build a touch panel with a professional look.").build(), new ChannelDefinitionBuilder("BrickletMultiTouchV2Recalibrate", new ChannelTypeUID("tinkerforge", "BrickletMultiTouchV2Recalibrate")).withLabel("Recalibrate Electrodes").build())).withProperties(props).build();
    }

    public static @Nullable ConfigDescription getConfigDescription(URI uri) {
        switch(uri.toASCIIString()) {
            case "thing-type:tinkerforge:brickletmultitouchv2":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList(ConfigDescriptionParameterBuilder.create("sensitivity", Type.INTEGER).withDefault("181").withDescription("The sensitivity of the electrodes. An electrode with a high sensitivity will register a touch earlier then an electrode with a low sensitivity.<br/><br/>If you build a big electrode you might need to decrease the sensitivity, since the area that can be charged will get bigger. If you want to be able to activate an electrode from further away you need to increase the sensitivity.").withLabel("Sensitivity").withMinimum(BigDecimal.valueOf(5)).withMaximum(BigDecimal.valueOf(201)).build(), ConfigDescriptionParameterBuilder.create("proximityEnabled", Type.BOOLEAN).withDefault("true").withDescription("It is recommended that you disable the proximity feature if not needed. This will reduce the amount of traffic that is produced.").withLabel("Proximity Detection").build(), ConfigDescriptionParameterBuilder.create("touchLEDMode", Type.INTEGER).withDefault("3").withDescription("Configures the touch LED to be either turned off, turned on, blink in heartbeat mode or show the touch state (electrode touched = LED on).").withLabel("Touch LED").withLimitToOptions(true).withOptions(Arrays.asList(new ParameterOption("0", "Off"), new ParameterOption("1", "On"), new ParameterOption("2", "Show Heartbeat"), new ParameterOption("3", "Show Touch"))).build(), ConfigDescriptionParameterBuilder.create("electrodeUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the electrode and proximity state in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Electrode Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("electrode0Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 0 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode1Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 1 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode2Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 2 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode3Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 3 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode4Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 4 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode5Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 5 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode6Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 6 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode7Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 7 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode8Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 8 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode9Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 9 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode10Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 10 Enabled").build(), ConfigDescriptionParameterBuilder.create("electrode11Enabled", Type.BOOLEAN).withDefault("true").withDescription("A disabled electrode will always return false as its state. If you don't need all electrodes you can disable the electrodes that are not needed. Disabling electrodes will also reduce power consumption.").withLabel("Electrode 11 Enabled").build(), ConfigDescriptionParameterBuilder.create("statusLEDConfig", Type.INTEGER).withDefault("3").withDescription("The status LED configuration. By default the LED shows communication traffic between Brick and Bricklet, it flickers once for every 10 received data packets.<br/><br/>You can also turn the LED permanently on/off or show a heartbeat.<br/><br/>If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.").withLabel("Status LED Configuration").withAdvanced(true).withLimitToOptions(true).withOptions(Arrays.asList(new ParameterOption("0", "Off"), new ParameterOption("1", "On"), new ParameterOption("2", "Show Heartbeat"), new ParameterOption("3", "Show Status"))).build())).withParameterGroups(Arrays.asList(new ConfigDescriptionParameterGroup("update_intervals", "null", true, "Update Intervals", "Update Intervals"))).build();
            case "channel-type:tinkerforge:BrickletMultiTouchV2Electrode":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletMultiTouchV2Recalibrate":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            default:
                break;
        }
        return null;
    }

        @Override
    public void refreshValue(String channel, org.eclipse.smarthome.config.core.Configuration config, org.eclipse.smarthome.config.core.Configuration channelConfig, BiConsumer<String, org.eclipse.smarthome.core.types.State> updateStateFn, BiConsumer<String, String> triggerChannelFn) throws TinkerforgeException {
        BrickletMultiTouchV2Config cfg = (BrickletMultiTouchV2Config) config.as(BrickletMultiTouchV2Config.class);
switch(channel) {
            case "BrickletMultiTouchV2Electrode0":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode0Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode1":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode1Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode2":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode2Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode3":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode3Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode4":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode4Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode5":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode5Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode6":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode6Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode7":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode7Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode8":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode8Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode9":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode9Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode10":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode10Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Electrode11":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2Electrode11Getter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Proximity":
                   {
            boolean[] value = this.getTouchState();
            if(true)
                updateStateFn.accept(channel, transformBrickletMultiTouchV2ProximityGetter0(value, cfg));
        }
                   return;
            case "BrickletMultiTouchV2Recalibrate":
               return;
default:
                logger.warn("Refresh for unknown channel {}", channel);
                break;
        }
    }
    

        @Override
    public List<SetterRefresh> handleCommand(org.eclipse.smarthome.config.core.Configuration config, org.eclipse.smarthome.config.core.Configuration channelConfig, String channel, Command command) throws TinkerforgeException {
        List<SetterRefresh> result = Collections.emptyList();
        
        switch(channel) {
            case "BrickletMultiTouchV2Recalibrate":
                if (command instanceof StringType) {
                    this.recalibrate();
                }
        
                else {
                    logger.warn("Command type {} not supported for channel {}. Please use one of StringType.", command.getClass().getName(), channel);
                }
                
                break;
default:
                logger.warn("Command for unknown channel {}", channel);
        }
        return result;
    }

        private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode0Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[0] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode1Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[1] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode2Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[2] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode3Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[3] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode4Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[4] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode5Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[5] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode6Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[6] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode7Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[7] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode8Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[8] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode9Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[9] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode10Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[10] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode11Callback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[11] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2ProximityCallback0(boolean[] state, BrickletMultiTouchV2Config cfg) {
        return state[12] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode0Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[0] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode1Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[1] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode2Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[2] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode3Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[3] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode4Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[4] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode5Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[5] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode6Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[6] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode7Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[7] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode8Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[8] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode9Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[9] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode10Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[10] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2Electrode11Getter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[11] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletMultiTouchV2ProximityGetter0(boolean[] value, BrickletMultiTouchV2Config cfg) {
        return value[12] ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }

}