/**
 * 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.thing.CommonTriggerEvents;
import org.eclipse.smarthome.core.library.types.OpenClosedType;

import com.tinkerforge.BrickletCAN;
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 CAN Bricklet.
 * @author Erik Fleckstein - Initial contribution
 */
@NonNullByDefault
public class BrickletCANWrapper extends BrickletCAN implements StandardFlashable, DeviceWrapper {
    public static final DeviceInfo DEVICE_INFO = new DeviceInfo(BrickletCAN.DEVICE_DISPLAY_NAME, "brickletcan", BrickletCAN.DEVICE_IDENTIFIER, BrickletCANWrapper.class, BrickletCANActions.class, "2.0.1", false);

    public BrickletCANWrapper(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(BrickletCANWrapper.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);
        BrickletCANConfig cfg = (BrickletCANConfig) config.as(BrickletCANConfig.class);
        this.addFrameReadableListener(this.reg(() -> {if(true) {triggerChannelFn.accept("BrickletCANFrameReadable", transformBrickletCANFrameReadableCallback0(cfg));}}, this::removeFrameReadableListener));
        this.setConfiguration(cfg.baudRate.shortValue(), cfg.transceiverMode.shortValue(), cfg.writeTimeout);
		    this.setFrameReadableCallbackConfiguration(true);
		{
		BrickletCANWriteErrorLevelConfig channelCfg = getChannelConfigFn.apply("BrickletCANWriteErrorLevel").as(BrickletCANWriteErrorLevelConfig.class);
		
		if(channelCfg.updateInterval > 0) {
    this.manualChannelUpdates.add(scheduler.scheduleWithFixedDelay(() -> {if(handler.getThing().getStatus() == ThingStatus.ONLINE) {handler.handleCommand(new ChannelUID(handler.getThing().getUID(), "BrickletCANWriteErrorLevel"), RefreshType.REFRESH);}}, channelCfg.updateInterval, channelCfg.updateInterval, TimeUnit.MILLISECONDS));
}
		}
		{
		BrickletCANReadErrorLevelConfig channelCfg = getChannelConfigFn.apply("BrickletCANReadErrorLevel").as(BrickletCANReadErrorLevelConfig.class);
		
		if(channelCfg.updateInterval > 0) {
    this.manualChannelUpdates.add(scheduler.scheduleWithFixedDelay(() -> {if(handler.getThing().getStatus() == ThingStatus.ONLINE) {handler.handleCommand(new ChannelUID(handler.getThing().getUID(), "BrickletCANReadErrorLevel"), RefreshType.REFRESH);}}, channelCfg.updateInterval, channelCfg.updateInterval, TimeUnit.MILLISECONDS));
}
		}
		{
		BrickletCANTransceiverDisabledConfig channelCfg = getChannelConfigFn.apply("BrickletCANTransceiverDisabled").as(BrickletCANTransceiverDisabledConfig.class);
		
		if(channelCfg.updateInterval > 0) {
    this.manualChannelUpdates.add(scheduler.scheduleWithFixedDelay(() -> {if(handler.getThing().getStatus() == ThingStatus.ONLINE) {handler.handleCommand(new ChannelUID(handler.getThing().getUID(), "BrickletCANTransceiverDisabled"), RefreshType.REFRESH);}}, channelCfg.updateInterval, channelCfg.updateInterval, TimeUnit.MILLISECONDS));
}
		}
		{
		BrickletCANWriteTimeoutCountConfig channelCfg = getChannelConfigFn.apply("BrickletCANWriteTimeoutCount").as(BrickletCANWriteTimeoutCountConfig.class);
		
		if(channelCfg.updateInterval > 0) {
    this.manualChannelUpdates.add(scheduler.scheduleWithFixedDelay(() -> {if(handler.getThing().getStatus() == ThingStatus.ONLINE) {handler.handleCommand(new ChannelUID(handler.getThing().getUID(), "BrickletCANWriteTimeoutCount"), RefreshType.REFRESH);}}, channelCfg.updateInterval, channelCfg.updateInterval, TimeUnit.MILLISECONDS));
}
		}
		{
		BrickletCANReadRegisterOverflowCountConfig channelCfg = getChannelConfigFn.apply("BrickletCANReadRegisterOverflowCount").as(BrickletCANReadRegisterOverflowCountConfig.class);
		
		if(channelCfg.updateInterval > 0) {
    this.manualChannelUpdates.add(scheduler.scheduleWithFixedDelay(() -> {if(handler.getThing().getStatus() == ThingStatus.ONLINE) {handler.handleCommand(new ChannelUID(handler.getThing().getUID(), "BrickletCANReadRegisterOverflowCount"), RefreshType.REFRESH);}}, channelCfg.updateInterval, channelCfg.updateInterval, TimeUnit.MILLISECONDS));
}
		}
		{
		BrickletCANReadBufferOverflowCountConfig channelCfg = getChannelConfigFn.apply("BrickletCANReadBufferOverflowCount").as(BrickletCANReadBufferOverflowCountConfig.class);
		
		if(channelCfg.updateInterval > 0) {
    this.manualChannelUpdates.add(scheduler.scheduleWithFixedDelay(() -> {if(handler.getThing().getStatus() == ThingStatus.ONLINE) {handler.handleCommand(new ChannelUID(handler.getThing().getUID(), "BrickletCANReadBufferOverflowCount"), RefreshType.REFRESH);}}, channelCfg.updateInterval, channelCfg.updateInterval, TimeUnit.MILLISECONDS));
}
		}
    }

    @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{
        List<String> result = new ArrayList<String>();
        result.add("BrickletCANFrameReadable");
		result.add("BrickletCANWriteErrorLevel");
		result.add("BrickletCANReadErrorLevel");
		result.add("BrickletCANTransceiverDisabled");
		result.add("BrickletCANWriteTimeoutCount");
		result.add("BrickletCANReadRegisterOverflowCount");
		result.add("BrickletCANReadBufferOverflowCount");
        return result;
    }

    public static @Nullable ChannelType getChannelType(ChannelTypeUID channelTypeUID) {
        switch(channelTypeUID.getId()) {
            case "BrickletCANWriteErrorLevel":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletCANWriteErrorLevel"), "Write Error Level", "Number:Dimensionless").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletCANWriteErrorLevel")).withDescription("The write error level indicates the current level of checksum, acknowledgement, form, bit and stuffing errors during CAN bus write operations.<br/><br/>When the write error level extends 255 then the CAN transceiver gets disabled and no frames can be transmitted or received anymore. The CAN transceiver will automatically be activated again after the CAN bus is idle for a while.<br/><br/>The write error level is not available in read-only transceiver mode and is reset to 0 as a side effect of changing the configuration or the read filter.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%d").withReadOnly(true).build().toStateDescription()).build();
            case "BrickletCANReadErrorLevel":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletCANReadErrorLevel"), "Read Error Level", "Number:Dimensionless").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletCANReadErrorLevel")).withDescription("The read error level indicates the current level of checksum, acknowledgement, form, bit and stuffing errors during CAN bus read operations.<br/><br/>The read error level is not available in read-only transceiver mode and is reset to 0 as a side effect of changing the configuration or the read filter.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%d").withReadOnly(true).build().toStateDescription()).build();
            case "BrickletCANTransceiverDisabled":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletCANTransceiverDisabled"), "Transceiver Disabled", "Contact").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletCANTransceiverDisabled")).withDescription("When the write error level extends 255 then the CAN transceiver gets disabled and no frames can be transmitted or received anymore. The CAN transceiver will automatically be activated again after the CAN bus is idle for a while.").build();
            case "BrickletCANWriteTimeoutCount":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletCANWriteTimeoutCount"), "Write Timeouts", "Number:Dimensionless").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletCANWriteTimeoutCount")).withDescription("A write timeout occurs if a frame could not be transmitted before the configured write timeout expired.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%d").withReadOnly(true).build().toStateDescription()).build();
            case "BrickletCANReadRegisterOverflowCount":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletCANReadRegisterOverflowCount"), "Read Register Overflows", "Number:Dimensionless").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletCANReadRegisterOverflowCount")).withDescription("A read register overflow occurs if the read register of the CAN transceiver still contains the last received frame when the next frame arrives. In this case the newly arrived frame is lost. This happens if the CAN transceiver receives more frames than the Bricklet can handle. Using the read filter (see the setReadFilter action) can help to reduce the amount of received frames. This count is not exact, but a lower bound, because the Bricklet might not able detect all overflows if they occur in rapid succession.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%d").withReadOnly(true).build().toStateDescription()).build();
            case "BrickletCANReadBufferOverflowCount":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletCANReadBufferOverflowCount"), "Read Buffer Overflow Count", "Number:Dimensionless").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletCANReadBufferOverflowCount")).withDescription("A read buffer overflow occurs if the read buffer of the Bricklet is already full when the next frame should be read from the read register of the CAN transceiver. In this case the frame in the read register is lost. This happens if the CAN transceiver receives more frames to be added to the read buffer than are removed from the read buffer using the readFrame action.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%d").withReadOnly(true).build().toStateDescription()).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 CAN Bricklet").isListed(false).withSupportedBridgeTypeUIDs(Arrays.asList(TinkerforgeBindingConstants.THING_TYPE_BRICK_DAEMON.toString())).withConfigDescriptionURI(URI.create("thing-type:tinkerforge:" + thingTypeUID.getId())).withDescription("Communicates with CAN bus devices").withChannelDefinitions(Arrays.asList(new ChannelDefinitionBuilder("BrickletCANFrameReadable", new ChannelTypeUID("system", "trigger")).withLabel("Frame Readable").withDescription("This channel is triggered when a new frame was received and can be read out. The channel will only trigger again if the frame was read.").build(), new ChannelDefinitionBuilder("BrickletCANWriteErrorLevel", new ChannelTypeUID("tinkerforge", "BrickletCANWriteErrorLevel")).withLabel("Write Error Level").build(), new ChannelDefinitionBuilder("BrickletCANReadErrorLevel", new ChannelTypeUID("tinkerforge", "BrickletCANReadErrorLevel")).withLabel("Read Error Level").build(), new ChannelDefinitionBuilder("BrickletCANTransceiverDisabled", new ChannelTypeUID("tinkerforge", "BrickletCANTransceiverDisabled")).withLabel("Transceiver Disabled").build(), new ChannelDefinitionBuilder("BrickletCANWriteTimeoutCount", new ChannelTypeUID("tinkerforge", "BrickletCANWriteTimeoutCount")).withLabel("Write Timeouts").build(), new ChannelDefinitionBuilder("BrickletCANReadRegisterOverflowCount", new ChannelTypeUID("tinkerforge", "BrickletCANReadRegisterOverflowCount")).withLabel("Read Register Overflows").build(), new ChannelDefinitionBuilder("BrickletCANReadBufferOverflowCount", new ChannelTypeUID("tinkerforge", "BrickletCANReadBufferOverflowCount")).withLabel("Read Buffer Overflow Count").build())).withProperties(props).build();
    }

    public static @Nullable ConfigDescription getConfigDescription(URI uri) {
        switch(uri.toASCIIString()) {
            case "thing-type:tinkerforge:brickletcan":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList(ConfigDescriptionParameterBuilder.create("baudRate", Type.INTEGER).withDefault("3").withDescription("The baud rate to send/receive with.").withLabel("Baud Rate").withLimitToOptions(true).withOptions(Arrays.asList(new ParameterOption("0", "10kbps"), new ParameterOption("1", "20kbps"), new ParameterOption("2", "50kbps"), new ParameterOption("3", "125kbps"), new ParameterOption("4", "250kbps"), new ParameterOption("5", "500kbps"), new ParameterOption("6", "800kbps"), new ParameterOption("7", "1000kbps"))).build(), ConfigDescriptionParameterBuilder.create("transceiverMode", Type.INTEGER).withDefault("0").withDescription("The CAN transceiver has three different modes:<ul><li>Normal: Reads from and writes to the CAN bus and performs active bus error detection and acknowledgement.</li><li>Loopback: All reads and writes are performed internally. The transceiver is disconnected from the actual CAN bus.</li><li>Read-Only: Only reads from the CAN bus, but does neither active bus error detection nor acknowledgement. Only the receiving part of the transceiver is connected to the CAN bus.</li></ul>").withLabel("Transceiver Mode").withLimitToOptions(true).withOptions(Arrays.asList(new ParameterOption("0", "Normal"), new ParameterOption("1", "Loopback"), new ParameterOption("2", "Read Only"))).build(), ConfigDescriptionParameterBuilder.create("writeTimeout", Type.INTEGER).withDefault("0").withDescription("The write timeout has three different modes that define how a failed frame transmission should be handled:<ul><li>One-Shot (= -1): Only one transmission attempt will be made. If the transmission fails then the frame is discarded.</li><li>Infinite (= 0): Infinite transmission attempts will be made. The frame will never be discarded.</li><li>Milliseconds (> 0): A limited number of transmission attempts will be made. If the frame could not be transmitted successfully after the configured number of milliseconds then the frame is discarded.</li></ul>").withLabel("Write Timeout").withMinimum(BigDecimal.valueOf(-1)).withMaximum(BigDecimal.valueOf(2147483647)).build())).withParameterGroups(Arrays.asList(new ConfigDescriptionParameterGroup("update_intervals", "null", true, "Update Intervals", "Update Intervals"))).build();
            case "channel-type:tinkerforge:BrickletCANWriteErrorLevel":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList(ConfigDescriptionParameterBuilder.create("updateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval in milliseconds. A value of 0 disables automatic updates.").withLabel("Update Interval").withUnit("ms").build())).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletCANReadErrorLevel":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList(ConfigDescriptionParameterBuilder.create("updateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval in milliseconds. A value of 0 disables automatic updates.").withLabel("Update Interval").withUnit("ms").build())).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletCANTransceiverDisabled":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList(ConfigDescriptionParameterBuilder.create("updateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval in milliseconds. A value of 0 disables automatic updates.").withLabel("Update Interval").withUnit("ms").build())).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletCANWriteTimeoutCount":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList(ConfigDescriptionParameterBuilder.create("updateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval in milliseconds. A value of 0 disables automatic updates.").withLabel("Update Interval").withUnit("ms").build())).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletCANReadRegisterOverflowCount":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList(ConfigDescriptionParameterBuilder.create("updateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval in milliseconds. A value of 0 disables automatic updates.").withLabel("Update Interval").withUnit("ms").build())).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletCANReadBufferOverflowCount":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList(ConfigDescriptionParameterBuilder.create("updateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval in milliseconds. A value of 0 disables automatic updates.").withLabel("Update Interval").withUnit("ms").build())).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 {
        BrickletCANConfig cfg = (BrickletCANConfig) config.as(BrickletCANConfig.class);
switch(channel) {
            case "BrickletCANFrameReadable":
               return;
            case "BrickletCANWriteErrorLevel":
                   {
            BrickletCAN.ErrorLog value = this.getErrorLog();
            if(true)
                updateStateFn.accept(channel, transformBrickletCANWriteErrorLevelGetter0(value, cfg));
        }
                   return;
            case "BrickletCANReadErrorLevel":
                   {
            BrickletCAN.ErrorLog value = this.getErrorLog();
            if(true)
                updateStateFn.accept(channel, transformBrickletCANReadErrorLevelGetter0(value, cfg));
        }
                   return;
            case "BrickletCANTransceiverDisabled":
                   {
            BrickletCAN.ErrorLog value = this.getErrorLog();
            if(true)
                updateStateFn.accept(channel, transformBrickletCANTransceiverDisabledGetter0(value, cfg));
        }
                   return;
            case "BrickletCANWriteTimeoutCount":
                   {
            BrickletCAN.ErrorLog value = this.getErrorLog();
            if(true)
                updateStateFn.accept(channel, transformBrickletCANWriteTimeoutCountGetter0(value, cfg));
        }
                   return;
            case "BrickletCANReadRegisterOverflowCount":
                   {
            BrickletCAN.ErrorLog value = this.getErrorLog();
            if(true)
                updateStateFn.accept(channel, transformBrickletCANReadRegisterOverflowCountGetter0(value, cfg));
        }
                   return;
            case "BrickletCANReadBufferOverflowCount":
                   {
            BrickletCAN.ErrorLog value = this.getErrorLog();
            if(true)
                updateStateFn.accept(channel, transformBrickletCANReadBufferOverflowCountGetter0(value, cfg));
        }
                   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) {
            default:
                logger.warn("Command for unknown channel {}", channel);
        }
        return result;
    }

        private String transformBrickletCANFrameReadableCallback0(BrickletCANConfig cfg) {
        return "";
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletCANWriteErrorLevelGetter0(BrickletCAN.ErrorLog value, BrickletCANConfig cfg) {
        return new DecimalType(value.writeErrorLevel);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletCANReadErrorLevelGetter0(BrickletCAN.ErrorLog value, BrickletCANConfig cfg) {
        return new DecimalType(value.readErrorLevel);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletCANTransceiverDisabledGetter0(BrickletCAN.ErrorLog value, BrickletCANConfig cfg) {
        return value.transceiverDisabled ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletCANWriteTimeoutCountGetter0(BrickletCAN.ErrorLog value, BrickletCANConfig cfg) {
        return new DecimalType(value.writeTimeoutCount);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletCANReadRegisterOverflowCountGetter0(BrickletCAN.ErrorLog value, BrickletCANConfig cfg) {
        return new DecimalType(value.readRegisterOverflowCount);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletCANReadBufferOverflowCountGetter0(BrickletCAN.ErrorLog value, BrickletCANConfig cfg) {
        return new DecimalType(value.readBufferOverflowCount);
    }

}