/**
 * 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.OnOffType;

import com.tinkerforge.BrickIMUV2;
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 IMU Brick 2.0.
 * @author Erik Fleckstein - Initial contribution
 */
@NonNullByDefault
public class BrickIMUV2Wrapper extends BrickIMUV2 implements DeviceWrapper {
    public static final DeviceInfo DEVICE_INFO = new DeviceInfo(BrickIMUV2.DEVICE_DISPLAY_NAME, "brickimuv2", BrickIMUV2.DEVICE_IDENTIFIER, BrickIMUV2Wrapper.class, BrickIMUV2Actions.class, "2.0.10", false);

    public BrickIMUV2Wrapper(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(BrickIMUV2Wrapper.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);
        BrickIMUV2Config cfg = (BrickIMUV2Config) config.as(BrickIMUV2Config.class);
        this.addAccelerationListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2AccelerationX", transformBrickIMUV2AccelerationXCallback0(x, y, z, cfg));}}, this::removeAccelerationListener));
		this.addAccelerationListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2AccelerationY", transformBrickIMUV2AccelerationYCallback0(x, y, z, cfg));}}, this::removeAccelerationListener));
		this.addAccelerationListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2AccelerationZ", transformBrickIMUV2AccelerationZCallback0(x, y, z, cfg));}}, this::removeAccelerationListener));
		this.addMagneticFieldListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2MagneticFieldX", transformBrickIMUV2MagneticFieldXCallback0(x, y, z, cfg));}}, this::removeMagneticFieldListener));
		this.addMagneticFieldListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2MagneticFieldY", transformBrickIMUV2MagneticFieldYCallback0(x, y, z, cfg));}}, this::removeMagneticFieldListener));
		this.addMagneticFieldListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2MagneticFieldZ", transformBrickIMUV2MagneticFieldZCallback0(x, y, z, cfg));}}, this::removeMagneticFieldListener));
		this.addAngularVelocityListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2AngularVelocityX", transformBrickIMUV2AngularVelocityXCallback0(x, y, z, cfg));}}, this::removeAngularVelocityListener));
		this.addAngularVelocityListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2AngularVelocityY", transformBrickIMUV2AngularVelocityYCallback0(x, y, z, cfg));}}, this::removeAngularVelocityListener));
		this.addAngularVelocityListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2AngularVelocityZ", transformBrickIMUV2AngularVelocityZCallback0(x, y, z, cfg));}}, this::removeAngularVelocityListener));
		this.addOrientationListener(this.reg((heading, roll, pitch) -> {if(true) {updateStateFn.accept("BrickIMUV2OrientationHeading", transformBrickIMUV2OrientationHeadingCallback0(heading, roll, pitch, cfg));}}, this::removeOrientationListener));
		this.addOrientationListener(this.reg((heading, roll, pitch) -> {if(true) {updateStateFn.accept("BrickIMUV2OrientationRoll", transformBrickIMUV2OrientationRollCallback0(heading, roll, pitch, cfg));}}, this::removeOrientationListener));
		this.addOrientationListener(this.reg((heading, roll, pitch) -> {if(true) {updateStateFn.accept("BrickIMUV2OrientationPitch", transformBrickIMUV2OrientationPitchCallback0(heading, roll, pitch, cfg));}}, this::removeOrientationListener));
		this.addQuaternionListener(this.reg((w, x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2QuaternionW", transformBrickIMUV2QuaternionWCallback0(w, x, y, z, cfg));}}, this::removeQuaternionListener));
		this.addQuaternionListener(this.reg((w, x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2QuaternionX", transformBrickIMUV2QuaternionXCallback0(w, x, y, z, cfg));}}, this::removeQuaternionListener));
		this.addQuaternionListener(this.reg((w, x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2QuaternionY", transformBrickIMUV2QuaternionYCallback0(w, x, y, z, cfg));}}, this::removeQuaternionListener));
		this.addQuaternionListener(this.reg((w, x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2QuaternionZ", transformBrickIMUV2QuaternionZCallback0(w, x, y, z, cfg));}}, this::removeQuaternionListener));
		this.addLinearAccelerationListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2LinearAccelerationX", transformBrickIMUV2LinearAccelerationXCallback0(x, y, z, cfg));}}, this::removeLinearAccelerationListener));
		this.addLinearAccelerationListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2LinearAccelerationY", transformBrickIMUV2LinearAccelerationYCallback0(x, y, z, cfg));}}, this::removeLinearAccelerationListener));
		this.addLinearAccelerationListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2LinearAccelerationZ", transformBrickIMUV2LinearAccelerationZCallback0(x, y, z, cfg));}}, this::removeLinearAccelerationListener));
		this.addGravityVectorListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2GravityVectorX", transformBrickIMUV2GravityVectorXCallback0(x, y, z, cfg));}}, this::removeGravityVectorListener));
		this.addGravityVectorListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2GravityVectorY", transformBrickIMUV2GravityVectorYCallback0(x, y, z, cfg));}}, this::removeGravityVectorListener));
		this.addGravityVectorListener(this.reg((x, y, z) -> {if(true) {updateStateFn.accept("BrickIMUV2GravityVectorZ", transformBrickIMUV2GravityVectorZCallback0(x, y, z, cfg));}}, this::removeGravityVectorListener));
		this.addTemperatureListener(this.reg((temperature) -> {if(true) {updateStateFn.accept("BrickIMUV2Temperature", transformBrickIMUV2TemperatureCallback0(temperature, cfg));}}, this::removeTemperatureListener));
        
		    this.setAccelerationPeriod(cfg.accelerationUpdateInterval);
		    this.setMagneticFieldPeriod(cfg.magneticFieldUpdateInterval);
		    this.setAngularVelocityPeriod(cfg.angularVelocityUpdateInterval);
		    this.setOrientationPeriod(cfg.orientationUpdateInterval);
		    this.setQuaternionPeriod(cfg.quaternionUpdateInterval);
		    this.setLinearAccelerationPeriod(cfg.linearAccelerationUpdateInterval);
		    this.setGravityVectorPeriod(cfg.gravityVectorUpdateInterval);
		    this.setTemperaturePeriod(cfg.temperatureUpdateInterval);
		    this.setSensorConfiguration(cfg.magnetometerRate.shortValue(), cfg.gyroscopeRange.shortValue(), cfg.gyroscopeBandwidth.shortValue(), cfg.accelerometerRange.shortValue(), cfg.accelerometerBandwidth.shortValue());
		    this.setSensorFusionMode(cfg.sensorFusionMode.shortValue());
		    
		if(cfg.statusLEDConfig) {
		                this.enableStatusLED();
		            } else {
		                this.disableStatusLED();
		            }
		this.setSPITFPBaudrateConfig(cfg.spitfpEnableDynamicBaudrate, cfg.spitfpMinimumDynamicBaudrate);
		this.setSPITFPBaudrate('a', cfg.spitfpBaudratePortA);
		            this.setSPITFPBaudrate('b', cfg.spitfpBaudratePortB);
    }

    @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("BrickIMUV2AccelerationX");
		result.add("BrickIMUV2AccelerationY");
		result.add("BrickIMUV2AccelerationZ");
		result.add("BrickIMUV2MagneticFieldX");
		result.add("BrickIMUV2MagneticFieldY");
		result.add("BrickIMUV2MagneticFieldZ");
		result.add("BrickIMUV2AngularVelocityX");
		result.add("BrickIMUV2AngularVelocityY");
		result.add("BrickIMUV2AngularVelocityZ");
		result.add("BrickIMUV2OrientationHeading");
		result.add("BrickIMUV2OrientationRoll");
		result.add("BrickIMUV2OrientationPitch");
		result.add("BrickIMUV2QuaternionW");
		result.add("BrickIMUV2QuaternionX");
		result.add("BrickIMUV2QuaternionY");
		result.add("BrickIMUV2QuaternionZ");
		result.add("BrickIMUV2LinearAccelerationX");
		result.add("BrickIMUV2LinearAccelerationY");
		result.add("BrickIMUV2LinearAccelerationZ");
		result.add("BrickIMUV2GravityVectorX");
		result.add("BrickIMUV2GravityVectorY");
		result.add("BrickIMUV2GravityVectorZ");
		result.add("BrickIMUV2Temperature");
		result.add("BrickIMUV2EnableLEDs");
        return result;
    }

    public static @Nullable ChannelType getChannelType(ChannelTypeUID channelTypeUID) {
        switch(channelTypeUID.getId()) {
            case "BrickIMUV2Acceleration":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickIMUV2Acceleration"), "NOT USED", "Number:Acceleration").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickIMUV2Acceleration")).withDescription("The acceleration from the accelerometer for the x, y and z axis in m/s².")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%.2f %unit%").withReadOnly(true).build().toStateDescription()).build();
            case "BrickIMUV2MagneticField":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickIMUV2MagneticField"), "NOT USED", "Number:MagneticFluxDensity").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickIMUV2MagneticField")).withDescription("The calibrated magnetic field from the magnetometer for the x, y and z axis in Tesla.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withMinimum(BigDecimal.valueOf(-0.0025)).withMaximum(BigDecimal.valueOf(0.0025)).withStep(BigDecimal.valueOf(6.25e-08)).withPattern("%.8f %unit%").withReadOnly(true).build().toStateDescription()).build();
            case "BrickIMUV2AngularVelocity":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickIMUV2AngularVelocity"), "NOT USED", "Number:Dimensionless").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickIMUV2AngularVelocity")).withDescription("The calibrated angular velocity from the gyroscope for the x, y and z axis in °/s.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%.2f").withReadOnly(true).build().toStateDescription()).build();
            case "BrickIMUV2Orientation":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickIMUV2Orientation"), "NOT USED", "Number:Angle").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickIMUV2Orientation")).withDescription("The current orientation (heading, roll, pitch) of the IMU Brick as independent Euler angles in 1/16 degree. Note that Euler angles always experience a gimbal lock. We recommend that you use quaternions instead, if you need the absolute orientation.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withMinimum(BigDecimal.valueOf(-180)).withMaximum(BigDecimal.valueOf(360)).withStep(BigDecimal.valueOf(0.0625)).withPattern("%.2f %unit%").withReadOnly(true).build().toStateDescription()).build();
            case "BrickIMUV2Quaternion":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickIMUV2Quaternion"), "NOT USED", "Number:Dimensionless").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickIMUV2Quaternion")).withDescription("The current orientation (w, x, y, z) of the IMU Brick as quaternions.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withMinimum(BigDecimal.valueOf(-1)).withMaximum(BigDecimal.valueOf(1)).withStep(BigDecimal.valueOf(6.103888176768602e-05)).withPattern("%.5f").withReadOnly(true).build().toStateDescription()).build();
            case "BrickIMUV2LinearAcceleration":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickIMUV2LinearAcceleration"), "NOT USED", "Number:Acceleration").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickIMUV2LinearAcceleration")).withDescription("The linear acceleration from the accelerometer for the x, y and z axis in m/s. The linear acceleration is the acceleration in each of the three axis of the IMU Brick with the influences of gravity removed.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%.2f %unit%").withReadOnly(true).build().toStateDescription()).build();
            case "BrickIMUV2GravityVector":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickIMUV2GravityVector"), "NOT USED", "Number:Acceleration").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickIMUV2GravityVector")).withDescription("The current gravity vector of the IMU Brick for the x, y and z axis in g (1g = 9.80665m/s²). The gravity vector is the acceleration that occurs due to gravity. Influences of additional linear acceleration are removed.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withMinimum(BigDecimal.valueOf(-1.0003416049313476)).withMaximum(BigDecimal.valueOf(1.0003416049313476)).withStep(BigDecimal.valueOf(0.0010197162129779282)).withPattern("%.3f %unit%").withReadOnly(true).build().toStateDescription()).build();
            case "BrickIMUV2Temperature":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickIMUV2Temperature"), "NOT USED", "Number:Temperature").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickIMUV2Temperature")).withDescription("The temperature of the IMU Brick. The temperature is given in °C. The temperature is measured in the core of the BNO055 IC, it is not the ambient temperature.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%d %unit%").withReadOnly(true).build().toStateDescription()).build();
            case "BrickIMUV2EnableLEDs":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickIMUV2EnableLEDs"), "Enable LEDs", "Switch").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickIMUV2EnableLEDs")).withDescription("Enable/disable the orientation and direction LEDs of the IMU Brick.").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 IMU Brick 2.0").isListed(false).withSupportedBridgeTypeUIDs(Arrays.asList(TinkerforgeBindingConstants.THING_TYPE_BRICK_DAEMON.toString())).withConfigDescriptionURI(URI.create("thing-type:tinkerforge:" + thingTypeUID.getId())).withDescription("Full fledged AHRS with 9 degrees of freedom").withChannelDefinitions(Arrays.asList(new ChannelDefinitionBuilder("BrickIMUV2AccelerationX", new ChannelTypeUID("tinkerforge", "BrickIMUV2Acceleration")).withLabel("Acceleration - X").build(), new ChannelDefinitionBuilder("BrickIMUV2AccelerationY", new ChannelTypeUID("tinkerforge", "BrickIMUV2Acceleration")).withLabel("Acceleration - Y").build(), new ChannelDefinitionBuilder("BrickIMUV2AccelerationZ", new ChannelTypeUID("tinkerforge", "BrickIMUV2Acceleration")).withLabel("Acceleration - Z").build(), new ChannelDefinitionBuilder("BrickIMUV2MagneticFieldX", new ChannelTypeUID("tinkerforge", "BrickIMUV2MagneticField")).withLabel("Magnetic Field - X").build(), new ChannelDefinitionBuilder("BrickIMUV2MagneticFieldY", new ChannelTypeUID("tinkerforge", "BrickIMUV2MagneticField")).withLabel("Magnetic Field - Y").build(), new ChannelDefinitionBuilder("BrickIMUV2MagneticFieldZ", new ChannelTypeUID("tinkerforge", "BrickIMUV2MagneticField")).withLabel("Magnetic Field - Z").build(), new ChannelDefinitionBuilder("BrickIMUV2AngularVelocityX", new ChannelTypeUID("tinkerforge", "BrickIMUV2AngularVelocity")).withLabel("Angular Velocity - X").build(), new ChannelDefinitionBuilder("BrickIMUV2AngularVelocityY", new ChannelTypeUID("tinkerforge", "BrickIMUV2AngularVelocity")).withLabel("Angular Velocity - Y").build(), new ChannelDefinitionBuilder("BrickIMUV2AngularVelocityZ", new ChannelTypeUID("tinkerforge", "BrickIMUV2AngularVelocity")).withLabel("Angular Velocity - Z").build(), new ChannelDefinitionBuilder("BrickIMUV2OrientationHeading", new ChannelTypeUID("tinkerforge", "BrickIMUV2Orientation")).withLabel("Orientation - Heading").build(), new ChannelDefinitionBuilder("BrickIMUV2OrientationRoll", new ChannelTypeUID("tinkerforge", "BrickIMUV2Orientation")).withLabel("Orientation - Roll").build(), new ChannelDefinitionBuilder("BrickIMUV2OrientationPitch", new ChannelTypeUID("tinkerforge", "BrickIMUV2Orientation")).withLabel("Orientation - Pitch").build(), new ChannelDefinitionBuilder("BrickIMUV2QuaternionW", new ChannelTypeUID("tinkerforge", "BrickIMUV2Quaternion")).withLabel("Quaternion - W").build(), new ChannelDefinitionBuilder("BrickIMUV2QuaternionX", new ChannelTypeUID("tinkerforge", "BrickIMUV2Quaternion")).withLabel("Quaternion - X").build(), new ChannelDefinitionBuilder("BrickIMUV2QuaternionY", new ChannelTypeUID("tinkerforge", "BrickIMUV2Quaternion")).withLabel("Quaternion - Y").build(), new ChannelDefinitionBuilder("BrickIMUV2QuaternionZ", new ChannelTypeUID("tinkerforge", "BrickIMUV2Quaternion")).withLabel("Quaternion - Z").build(), new ChannelDefinitionBuilder("BrickIMUV2LinearAccelerationX", new ChannelTypeUID("tinkerforge", "BrickIMUV2LinearAcceleration")).withLabel("Linear Acceleration - X").build(), new ChannelDefinitionBuilder("BrickIMUV2LinearAccelerationY", new ChannelTypeUID("tinkerforge", "BrickIMUV2LinearAcceleration")).withLabel("Linear Acceleration - Y").build(), new ChannelDefinitionBuilder("BrickIMUV2LinearAccelerationZ", new ChannelTypeUID("tinkerforge", "BrickIMUV2LinearAcceleration")).withLabel("Linear Acceleration - Z").build(), new ChannelDefinitionBuilder("BrickIMUV2GravityVectorX", new ChannelTypeUID("tinkerforge", "BrickIMUV2GravityVector")).withLabel("Gravity Vector - X").build(), new ChannelDefinitionBuilder("BrickIMUV2GravityVectorY", new ChannelTypeUID("tinkerforge", "BrickIMUV2GravityVector")).withLabel("Gravity Vector - Y").build(), new ChannelDefinitionBuilder("BrickIMUV2GravityVectorZ", new ChannelTypeUID("tinkerforge", "BrickIMUV2GravityVector")).withLabel("Gravity Vector - Z").build(), new ChannelDefinitionBuilder("BrickIMUV2Temperature", new ChannelTypeUID("tinkerforge", "BrickIMUV2Temperature")).withLabel("Temperature").build(), new ChannelDefinitionBuilder("BrickIMUV2EnableLEDs", new ChannelTypeUID("tinkerforge", "BrickIMUV2EnableLEDs")).withLabel("Enable LEDs").build())).withProperties(props).build();
    }

    public static @Nullable ConfigDescription getConfigDescription(URI uri) {
        switch(uri.toASCIIString()) {
            case "thing-type:tinkerforge:brickimuv2":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList(ConfigDescriptionParameterBuilder.create("magnetometerRate", Type.INTEGER).withDefault("5").withDescription("This option is auto-controlled in fusion mode.").withLabel("Magnetometer Rate").withAdvanced(true).withLimitToOptions(true).withOptions(Arrays.asList(new ParameterOption("0", "2Hz"), new ParameterOption("1", "6Hz"), new ParameterOption("2", "8Hz"), new ParameterOption("3", "10Hz"), new ParameterOption("4", "15Hz"), new ParameterOption("5", "20Hz"), new ParameterOption("6", "25Hz"), new ParameterOption("7", "30Hz"))).build(), ConfigDescriptionParameterBuilder.create("gyroscopeRange", Type.INTEGER).withDefault("0").withDescription("This option is auto-controlled in fusion mode.").withLabel("Gyroscope Range").withAdvanced(true).withLimitToOptions(true).withOptions(Arrays.asList(new ParameterOption("0", "2000°/s"), new ParameterOption("1", "1000°/s"), new ParameterOption("2", "500°/s"), new ParameterOption("3", "250°/s"), new ParameterOption("4", "125°/s"))).build(), ConfigDescriptionParameterBuilder.create("gyroscopeBandwidth", Type.INTEGER).withDefault("7").withDescription("This option is auto-controlled in fusion mode.").withLabel("Gyroscope Bandwidth").withAdvanced(true).withLimitToOptions(true).withOptions(Arrays.asList(new ParameterOption("0", "523Hz"), new ParameterOption("1", "230Hz"), new ParameterOption("2", "116Hz"), new ParameterOption("3", "47Hz"), new ParameterOption("4", "23Hz"), new ParameterOption("5", "12Hz"), new ParameterOption("6", "64Hz"), new ParameterOption("7", "32Hz"))).build(), ConfigDescriptionParameterBuilder.create("accelerometerRange", Type.INTEGER).withDefault("1").withDescription("This option is user selectable in all fusion modes.").withLabel("Accelerometer Range").withAdvanced(true).withLimitToOptions(true).withOptions(Arrays.asList(new ParameterOption("0", "±2G"), new ParameterOption("1", "±4G"), new ParameterOption("2", "±8G"), new ParameterOption("3", "±16G"))).build(), ConfigDescriptionParameterBuilder.create("accelerometerBandwidth", Type.INTEGER).withDefault("3").withDescription("This option is auto-controlled in fusion mode.").withLabel("Accelerometer Bandwidth").withAdvanced(true).withLimitToOptions(true).withOptions(Arrays.asList(new ParameterOption("0", "7.81Hz"), new ParameterOption("1", "15.63Hz"), new ParameterOption("2", "31.25Hz"), new ParameterOption("3", "62.5Hz"), new ParameterOption("4", "125Hz"), new ParameterOption("5", "250Hz"), new ParameterOption("6", "500Hz"), new ParameterOption("7", "1000Hz"))).build(), ConfigDescriptionParameterBuilder.create("sensorFusionMode", Type.INTEGER).withDefault("1").withDescription("If the fusion mode is turned off, the Acceleration, Magnetic Field and Angular Velocity channels return uncalibrated and uncompensated sensor data. All other sensor channels return no data.<br/><br/>Since firmware version 2.0.6 you can also use a fusion mode without magnetometer. In this mode the calculated orientation is relative (with magnetometer it is absolute with respect to the earth). However, the calculation can't be influenced by spurious magnetic fields.<br/><br/>Since firmware version 2.0.13 you can also use a fusion mode without fast magnetometer calibration. This mode is the same as the normal fusion mode, but the fast magnetometer calibration is turned off. So to find the orientation the first time will likely take longer, but small magnetic influences might not affect the automatic calibration as much.<br/><br/>By default sensor fusion is on.").withLabel("Sensor Fusion Mode").withAdvanced(true).withLimitToOptions(true).withOptions(Arrays.asList(new ParameterOption("0", "Off"), new ParameterOption("1", "On"), new ParameterOption("2", "On Without Magnetometer"), new ParameterOption("3", "On Without Fast Magnetometer Calibration"))).build(), ConfigDescriptionParameterBuilder.create("accelerationUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the acceleration in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Acceleration Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("magneticFieldUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the magnetic field in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Magnetic Field Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("angularVelocityUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the angular velocity in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Angular Velocity Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("orientationUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the orientation as euler angles in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Orientation Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("quaternionUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the orientation as quaternion in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Quaternion Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("linearAccelerationUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the linear acceleration in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Linear Acceleration Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("gravityVectorUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the gravity vector in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Gravity Vector Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("temperatureUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the temperature in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Temperature Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("statusLEDConfig", Type.BOOLEAN).withDefault("true").withDescription("The status LED is the blue LED next to the USB connector. If enabled is is on and it flickers if data is transfered. If disabled it is always off.").withLabel("Status LED Configuration").build(), ConfigDescriptionParameterBuilder.create("spitfpEnableDynamicBaudrate", Type.BOOLEAN).withDefault("true").withDescription("The SPITF protocol can be used with a dynamic baudrate. If the dynamic baudrate is enabled, the Brick will try to adapt the baudrate for the communication between Bricks and Bricklets according to the amount of data that is transferred.<br/><br/>The baudrate will be increased exponentially if lots of data is sent/received and decreased linearly if little data is sent/received.<br/><br/>This lowers the baudrate in applications where little data is transferred (e.g. a weather station) and increases the robustness. If there is lots of data to transfer (e.g. Thermal Imaging Bricklet) it automatically increases the baudrate as needed.<br/><br/>In cases where some data has to transferred as fast as possible every few seconds (e.g. RS485 Bricklet with a high baudrate but small payload) you may want to turn the dynamic baudrate off to get the highest possible performance.<br/><br/>The maximum value of the baudrate can be set per port. If the dynamic baudrate is disabled, the maximum baudrate will be used statically.").withLabel("SPITFP Enable Dynamic Baudrate").withAdvanced(true).build(), ConfigDescriptionParameterBuilder.create("spitfpMinimumDynamicBaudrate", Type.INTEGER).withDefault("400000").withDescription("See SPITFP Enable Dynamic Baudrate").withLabel("SPITFP Minimum Dynamic Baudrate").withAdvanced(true).withMinimum(BigDecimal.valueOf(400000)).withMaximum(BigDecimal.valueOf(2000000)).build(), ConfigDescriptionParameterBuilder.create("spitfpBaudratePortA", Type.INTEGER).withDefault("1400000").withDescription("The baudrate for Bricklet port A.<br/><br/>If you want to increase the throughput of Bricklets you can increase the baudrate. If you get a high error count because of high interference you can decrease the baudrate.<br/><br/>If the dynamic baudrate feature is enabled, this is the maximum baudrate.<br/><br/>Regulatory testing is done with the default baudrate. If CE compatibility or similar is necessary in your applications we recommend to not change the baudrate.").withLabel("(Maximum) SPITFP Baudrate Port A").withAdvanced(true).withMinimum(BigDecimal.valueOf(400000)).withMaximum(BigDecimal.valueOf(2000000)).build(), ConfigDescriptionParameterBuilder.create("spitfpBaudratePortB", Type.INTEGER).withDefault("1400000").withDescription("The baudrate for Bricklet port B.<br/><br/>If you want to increase the throughput of Bricklets you can increase the baudrate. If you get a high error count because of high interference you can decrease the baudrate.<br/><br/>If the dynamic baudrate feature is enabled, this is the maximum baudrate.<br/><br/>Regulatory testing is done with the default baudrate. If CE compatibility or similar is necessary in your applications we recommend to not change the baudrate.").withLabel("(Maximum) SPITFP Baudrate Port B").withAdvanced(true).withMinimum(BigDecimal.valueOf(400000)).withMaximum(BigDecimal.valueOf(2000000)).build())).withParameterGroups(Arrays.asList(new ConfigDescriptionParameterGroup("update_intervals", "null", true, "Update Intervals", "Update Intervals"))).build();
            case "channel-type:tinkerforge:BrickIMUV2Acceleration":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickIMUV2MagneticField":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickIMUV2AngularVelocity":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickIMUV2Orientation":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickIMUV2Quaternion":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickIMUV2LinearAcceleration":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickIMUV2GravityVector":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickIMUV2Temperature":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickIMUV2EnableLEDs":
                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 {
        BrickIMUV2Config cfg = (BrickIMUV2Config) config.as(BrickIMUV2Config.class);
switch(channel) {
            case "BrickIMUV2AccelerationX":
                   {
            BrickIMUV2.Acceleration value = this.getAcceleration();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2AccelerationXGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2AccelerationY":
                   {
            BrickIMUV2.Acceleration value = this.getAcceleration();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2AccelerationYGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2AccelerationZ":
                   {
            BrickIMUV2.Acceleration value = this.getAcceleration();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2AccelerationZGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2MagneticFieldX":
                   {
            BrickIMUV2.MagneticField value = this.getMagneticField();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2MagneticFieldXGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2MagneticFieldY":
                   {
            BrickIMUV2.MagneticField value = this.getMagneticField();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2MagneticFieldYGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2MagneticFieldZ":
                   {
            BrickIMUV2.MagneticField value = this.getMagneticField();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2MagneticFieldZGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2AngularVelocityX":
                   {
            BrickIMUV2.AngularVelocity value = this.getAngularVelocity();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2AngularVelocityXGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2AngularVelocityY":
                   {
            BrickIMUV2.AngularVelocity value = this.getAngularVelocity();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2AngularVelocityYGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2AngularVelocityZ":
                   {
            BrickIMUV2.AngularVelocity value = this.getAngularVelocity();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2AngularVelocityZGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2OrientationHeading":
                   {
            BrickIMUV2.Orientation value = this.getOrientation();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2OrientationHeadingGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2OrientationRoll":
                   {
            BrickIMUV2.Orientation value = this.getOrientation();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2OrientationRollGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2OrientationPitch":
                   {
            BrickIMUV2.Orientation value = this.getOrientation();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2OrientationPitchGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2QuaternionW":
                   {
            BrickIMUV2.Quaternion value = this.getQuaternion();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2QuaternionWGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2QuaternionX":
                   {
            BrickIMUV2.Quaternion value = this.getQuaternion();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2QuaternionXGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2QuaternionY":
                   {
            BrickIMUV2.Quaternion value = this.getQuaternion();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2QuaternionYGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2QuaternionZ":
                   {
            BrickIMUV2.Quaternion value = this.getQuaternion();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2QuaternionZGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2LinearAccelerationX":
                   {
            BrickIMUV2.LinearAcceleration value = this.getLinearAcceleration();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2LinearAccelerationXGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2LinearAccelerationY":
                   {
            BrickIMUV2.LinearAcceleration value = this.getLinearAcceleration();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2LinearAccelerationYGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2LinearAccelerationZ":
                   {
            BrickIMUV2.LinearAcceleration value = this.getLinearAcceleration();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2LinearAccelerationZGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2GravityVectorX":
                   {
            BrickIMUV2.GravityVector value = this.getGravityVector();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2GravityVectorXGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2GravityVectorY":
                   {
            BrickIMUV2.GravityVector value = this.getGravityVector();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2GravityVectorYGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2GravityVectorZ":
                   {
            BrickIMUV2.GravityVector value = this.getGravityVector();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2GravityVectorZGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2Temperature":
                   {
            byte value = this.getTemperature();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2TemperatureGetter0(value, cfg));
        }
                   return;
            case "BrickIMUV2EnableLEDs":
                   {
            boolean value = this.areLedsOn();
            if(true)
                updateStateFn.accept(channel, transformBrickIMUV2EnableLEDsGetter0(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) {
            case "BrickIMUV2EnableLEDs":
                if (command instanceof OnOffType) {
                    OnOffType cmd = (OnOffType) command;
if(cmd == OnOffType.ON) {
    this.ledsOn();
}
                }
        
if (command instanceof OnOffType) {
                    OnOffType cmd = (OnOffType) command;
if(cmd == OnOffType.OFF) {
    this.ledsOff();
}
                }
        
                else {
                    logger.warn("Command type {} not supported for channel {}. Please use one of OnOffType, OnOffType.", command.getClass().getName(), channel);
                }
                
                break;
default:
                logger.warn("Command for unknown channel {}", channel);
        }
        return result;
    }

        private org.eclipse.smarthome.core.types.State transformBrickIMUV2AccelerationXCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(x / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AccelerationYCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(y / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AccelerationZCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(z / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2MagneticFieldXCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(x / 16000000.0, SmartHomeUnits.TESLA);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2MagneticFieldYCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(y / 16000000.0, SmartHomeUnits.TESLA);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2MagneticFieldZCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(z / 16000000.0, SmartHomeUnits.TESLA);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AngularVelocityXCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new DecimalType(x / 16.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AngularVelocityYCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new DecimalType(y / 16.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AngularVelocityZCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new DecimalType(z / 16.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2OrientationHeadingCallback0(short heading, short roll, short pitch, BrickIMUV2Config cfg) {
        return new QuantityType<>(heading / 16.0, SmartHomeUnits.DEGREE_ANGLE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2OrientationRollCallback0(short heading, short roll, short pitch, BrickIMUV2Config cfg) {
        return new QuantityType<>(roll / 16.0, SmartHomeUnits.DEGREE_ANGLE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2OrientationPitchCallback0(short heading, short roll, short pitch, BrickIMUV2Config cfg) {
        return new QuantityType<>(pitch / 16.0, SmartHomeUnits.DEGREE_ANGLE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2QuaternionWCallback0(short w, short x, short y, short z, BrickIMUV2Config cfg) {
        return new DecimalType(w / 16383.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2QuaternionXCallback0(short w, short x, short y, short z, BrickIMUV2Config cfg) {
        return new DecimalType(x / 16383.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2QuaternionYCallback0(short w, short x, short y, short z, BrickIMUV2Config cfg) {
        return new DecimalType(y / 16383.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2QuaternionZCallback0(short w, short x, short y, short z, BrickIMUV2Config cfg) {
        return new DecimalType(z / 16383.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2LinearAccelerationXCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(x / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2LinearAccelerationYCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(y / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2LinearAccelerationZCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(z / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2GravityVectorXCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(x / 980.665, SmartHomeUnits.STANDARD_GRAVITY);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2GravityVectorYCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(y / 980.665, SmartHomeUnits.STANDARD_GRAVITY);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2GravityVectorZCallback0(short x, short y, short z, BrickIMUV2Config cfg) {
        return new QuantityType<>(z / 980.665, SmartHomeUnits.STANDARD_GRAVITY);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2TemperatureCallback0(byte temperature, BrickIMUV2Config cfg) {
        return new QuantityType<>(temperature, SIUnits.CELSIUS);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AccelerationXGetter0(BrickIMUV2.Acceleration value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.x / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AccelerationYGetter0(BrickIMUV2.Acceleration value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.y / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AccelerationZGetter0(BrickIMUV2.Acceleration value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.z / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2MagneticFieldXGetter0(BrickIMUV2.MagneticField value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.x / 16000000.0, SmartHomeUnits.TESLA);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2MagneticFieldYGetter0(BrickIMUV2.MagneticField value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.y / 16000000.0, SmartHomeUnits.TESLA);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2MagneticFieldZGetter0(BrickIMUV2.MagneticField value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.z / 16000000.0, SmartHomeUnits.TESLA);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AngularVelocityXGetter0(BrickIMUV2.AngularVelocity value, BrickIMUV2Config cfg) {
        return new DecimalType(value.x / 16.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AngularVelocityYGetter0(BrickIMUV2.AngularVelocity value, BrickIMUV2Config cfg) {
        return new DecimalType(value.y / 16.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2AngularVelocityZGetter0(BrickIMUV2.AngularVelocity value, BrickIMUV2Config cfg) {
        return new DecimalType(value.z / 16.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2OrientationHeadingGetter0(BrickIMUV2.Orientation value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.heading / 16.0, SmartHomeUnits.DEGREE_ANGLE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2OrientationRollGetter0(BrickIMUV2.Orientation value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.roll / 16.0, SmartHomeUnits.DEGREE_ANGLE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2OrientationPitchGetter0(BrickIMUV2.Orientation value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.pitch / 16.0, SmartHomeUnits.DEGREE_ANGLE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2QuaternionWGetter0(BrickIMUV2.Quaternion value, BrickIMUV2Config cfg) {
        return new DecimalType(value.w / 16383.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2QuaternionXGetter0(BrickIMUV2.Quaternion value, BrickIMUV2Config cfg) {
        return new DecimalType(value.x / 16383.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2QuaternionYGetter0(BrickIMUV2.Quaternion value, BrickIMUV2Config cfg) {
        return new DecimalType(value.y / 16383.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2QuaternionZGetter0(BrickIMUV2.Quaternion value, BrickIMUV2Config cfg) {
        return new DecimalType(value.z / 16383.0);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2LinearAccelerationXGetter0(BrickIMUV2.LinearAcceleration value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.x / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2LinearAccelerationYGetter0(BrickIMUV2.LinearAcceleration value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.y / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2LinearAccelerationZGetter0(BrickIMUV2.LinearAcceleration value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.z / 100.0, SmartHomeUnits.METRE_PER_SQUARE_SECOND);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2GravityVectorXGetter0(BrickIMUV2.GravityVector value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.x / 980.665, SmartHomeUnits.STANDARD_GRAVITY);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2GravityVectorYGetter0(BrickIMUV2.GravityVector value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.y / 980.665, SmartHomeUnits.STANDARD_GRAVITY);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2GravityVectorZGetter0(BrickIMUV2.GravityVector value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value.z / 980.665, SmartHomeUnits.STANDARD_GRAVITY);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2TemperatureGetter0(byte value, BrickIMUV2Config cfg) {
        return new QuantityType<>(value, SIUnits.CELSIUS);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickIMUV2EnableLEDsGetter0(boolean value, BrickIMUV2Config cfg) {
        return value? OnOffType.ON : OnOffType.OFF;
    }

}