/**
 * 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.StringType;
import org.eclipse.smarthome.core.library.types.PointType;
import org.eclipse.smarthome.core.library.types.DateTimeType;
import org.eclipse.smarthome.core.library.types.OpenClosedType;
import java.time.ZoneId;

import com.tinkerforge.BrickletGPS;
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 GPS Bricklet.
 * @author Erik Fleckstein - Initial contribution
 */
@NonNullByDefault
public class BrickletGPSWrapper extends BrickletGPS implements StandardFlashable, DeviceWrapper {
    public static final DeviceInfo DEVICE_INFO = new DeviceInfo(BrickletGPS.DEVICE_DISPLAY_NAME, "brickletgps", BrickletGPS.DEVICE_IDENTIFIER, BrickletGPSWrapper.class, BrickletGPSActions.class, "2.0.0", false);

    public BrickletGPSWrapper(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(BrickletGPSWrapper.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);
        BrickletGPSConfig cfg = (BrickletGPSConfig) config.as(BrickletGPSConfig.class);
        this.addCoordinatesListener(this.reg((latitude, ns, longitude, ew, pdop, hdop, vdop, epe) -> {if(true) {updateStateFn.accept("BrickletGPSLocation", transformBrickletGPSLocationCallback0(latitude, ns, longitude, ew, pdop, hdop, vdop, epe, cfg));}}, this::removeCoordinatesListener));
		this.addStatusListener(this.reg((fix, satellitesView, satellitesUsed) -> {if(true) {updateStateFn.accept("BrickletGPSFix", transformBrickletGPSFixCallback0(fix, satellitesView, satellitesUsed, cfg));}}, this::removeStatusListener));
		this.addStatusListener(this.reg((fix, satellitesView, satellitesUsed) -> {if(true) {updateStateFn.accept("BrickletGPSSatellitesInView", transformBrickletGPSSatellitesInViewCallback0(fix, satellitesView, satellitesUsed, cfg));}}, this::removeStatusListener));
		this.addStatusListener(this.reg((fix, satellitesView, satellitesUsed) -> {if(true) {updateStateFn.accept("BrickletGPSSatellitesUsed", transformBrickletGPSSatellitesUsedCallback0(fix, satellitesView, satellitesUsed, cfg));}}, this::removeStatusListener));
		this.addAltitudeListener(this.reg((altitude, geoidalSeparation) -> {if(true) {updateStateFn.accept("BrickletGPSAltitude", transformBrickletGPSAltitudeCallback0(altitude, geoidalSeparation, cfg));}}, this::removeAltitudeListener));
		this.addAltitudeListener(this.reg((altitude, geoidalSeparation) -> {if(true) {updateStateFn.accept("BrickletGPSGeoidalSeparation", transformBrickletGPSGeoidalSeparationCallback0(altitude, geoidalSeparation, cfg));}}, this::removeAltitudeListener));
		this.addMotionListener(this.reg((course, speed) -> {if(true) {updateStateFn.accept("BrickletGPSCourse", transformBrickletGPSCourseCallback0(course, speed, cfg));}}, this::removeMotionListener));
		this.addMotionListener(this.reg((course, speed) -> {if(true) {updateStateFn.accept("BrickletGPSSpeed", transformBrickletGPSSpeedCallback0(course, speed, cfg));}}, this::removeMotionListener));
		this.addDateTimeListener(this.reg((date, time) -> {if(true) {updateStateFn.accept("BrickletGPSDateTime", transformBrickletGPSDateTimeCallback0(date, time, cfg));}}, this::removeDateTimeListener));
        this.setStatusCallbackPeriod(cfg.statusUpdateInterval);
		        this.setAltitudeCallbackPeriod(cfg.altitudeUpdateInterval);
		        this.setMotionCallbackPeriod(cfg.motionUpdateInterval);
		{
		BrickletGPSCoordinatesConfig channelCfg = getChannelConfigFn.apply("BrickletGPSLocation").as(BrickletGPSCoordinatesConfig.class);
		this.setCoordinatesCallbackPeriod(channelCfg.updateInterval);
		}
		{
		BrickletGPSDateTimeConfig channelCfg = getChannelConfigFn.apply("BrickletGPSDateTime").as(BrickletGPSDateTimeConfig.class);
		this.setDateTimeCallbackPeriod(channelCfg.updateInterval);
		}
    }

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

        
        this.setCoordinatesCallbackPeriod(0);
		this.setDateTimeCallbackPeriod(0);
		this.setStatusCallbackPeriod(0);
		        this.setAltitudeCallbackPeriod(0);
		        this.setMotionCallbackPeriod(0);
    }

    @Override
    public List<String> getEnabledChannels(org.eclipse.smarthome.config.core.Configuration config) throws TinkerforgeException{
        List<String> result = new ArrayList<String>();
        result.add("BrickletGPSLocation");
		result.add("BrickletGPSFix");
		result.add("BrickletGPSSatellitesInView");
		result.add("BrickletGPSSatellitesUsed");
		result.add("BrickletGPSAltitude");
		result.add("BrickletGPSGeoidalSeparation");
		result.add("BrickletGPSCourse");
		result.add("BrickletGPSSpeed");
		result.add("BrickletGPSDateTime");
		result.add("BrickletGPSRestart");
        return result;
    }

    public static @Nullable ChannelType getChannelType(ChannelTypeUID channelTypeUID) {
        switch(channelTypeUID.getId()) {
            case "BrickletGPSCoordinates":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletGPSCoordinates"), "Location", "Location").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletGPSCoordinates")).withDescription("The location as determined by the bricklet.").build();
            case "BrickletGPSFix":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletGPSFix"), "Fix", "Contact").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletGPSFix")).withDescription("The current fix status").build();
            case "BrickletGPSSatellitesInView":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletGPSSatellitesInView"), "Satellites In View", "Number:Dimensionless").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletGPSSatellitesInView")).withDescription("The number of satellites that are in view.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%d").withReadOnly(true).build().toStateDescription()).build();
            case "BrickletGPSSatellitesUsed":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletGPSSatellitesUsed"), "Satellites Used", "Number:Dimensionless").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletGPSSatellitesUsed")).withDescription("The number of satellites that are currently used.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%d").withReadOnly(true).build().toStateDescription()).build();
            case "BrickletGPSAltitude":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletGPSAltitude"), "Altitude", "Number:Length").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletGPSAltitude")).withDescription("The measured altitude")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%.2f %unit%").withReadOnly(true).build().toStateDescription()).build();
            case "BrickletGPSGeoidalSeparation":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletGPSGeoidalSeparation"), "Geoidal Separation", "Number:Length").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletGPSGeoidalSeparation")).withDescription("The geoidal separation corresponding to the current altitude")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%.2f %unit%").withReadOnly(true).build().toStateDescription()).build();
            case "BrickletGPSCourse":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletGPSCourse"), "Course", "Number:Angle").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletGPSCourse")).withDescription("The current course. A course of 0° means the Bricklet is traveling north bound and 90° means it is traveling east bound. Please note that this only returns useful values if an actual movement is present.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(360)).withStep(BigDecimal.valueOf(0.01)).withPattern("%.2f %unit%").withReadOnly(true).build().toStateDescription()).build();
            case "BrickletGPSSpeed":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletGPSSpeed"), "Speed", "Number:Speed").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletGPSSpeed")).withDescription("The current speed. Please note that this only returns useful values if an actual movement is present.")
.withStateDescription(StateDescriptionFragmentBuilder.create().withPattern("%.2f %unit%").withReadOnly(true).build().toStateDescription()).build();
            case "BrickletGPSDateTime":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletGPSDateTime"), "Date Time", "DateTime").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletGPSDateTime")).withDescription("The current date and time.").build();
            case "BrickletGPSRestart":
                return ChannelTypeBuilder.state(new ChannelTypeUID("tinkerforge", "BrickletGPSRestart"), "Restart", "String").withConfigDescriptionURI(URI.create("channel-type:tinkerforge:BrickletGPSRestart")).withDescription("Restarts the GPS Bricklet, the following restart types are available:<ul><li>Hot start (use all available data in the NV store)</li><li>Warm start (don't use ephemeris at restart)</li><li>Cold start (don't use time, position, almanacs and ephemeris at restart)</li><li>Factory reset (clear all system/user configurations at restart)</li></ul>")
.withCommandDescription(CommandDescriptionBuilder.create().withCommandOption(new CommandOption("0", "Hot Start")).withCommandOption(new CommandOption("1", "Warm Start")).withCommandOption(new CommandOption("2", "Cold Start")).withCommandOption(new CommandOption("3", "Factory reset")).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 GPS Bricklet").isListed(false).withSupportedBridgeTypeUIDs(Arrays.asList(TinkerforgeBindingConstants.THING_TYPE_BRICK_DAEMON.toString())).withConfigDescriptionURI(URI.create("thing-type:tinkerforge:" + thingTypeUID.getId())).withDescription("Determine position, velocity and altitude using GPS").withChannelDefinitions(Arrays.asList(new ChannelDefinitionBuilder("BrickletGPSLocation", new ChannelTypeUID("tinkerforge", "BrickletGPSCoordinates")).withLabel("Location").build(), new ChannelDefinitionBuilder("BrickletGPSFix", new ChannelTypeUID("tinkerforge", "BrickletGPSFix")).withLabel("Fix").build(), new ChannelDefinitionBuilder("BrickletGPSSatellitesInView", new ChannelTypeUID("tinkerforge", "BrickletGPSSatellitesInView")).withLabel("Satellites In View").build(), new ChannelDefinitionBuilder("BrickletGPSSatellitesUsed", new ChannelTypeUID("tinkerforge", "BrickletGPSSatellitesUsed")).withLabel("Satellites Used").build(), new ChannelDefinitionBuilder("BrickletGPSAltitude", new ChannelTypeUID("tinkerforge", "BrickletGPSAltitude")).withLabel("Altitude").build(), new ChannelDefinitionBuilder("BrickletGPSGeoidalSeparation", new ChannelTypeUID("tinkerforge", "BrickletGPSGeoidalSeparation")).withLabel("Geoidal Separation").build(), new ChannelDefinitionBuilder("BrickletGPSCourse", new ChannelTypeUID("tinkerforge", "BrickletGPSCourse")).withLabel("Course").build(), new ChannelDefinitionBuilder("BrickletGPSSpeed", new ChannelTypeUID("tinkerforge", "BrickletGPSSpeed")).withLabel("Speed").build(), new ChannelDefinitionBuilder("BrickletGPSDateTime", new ChannelTypeUID("tinkerforge", "BrickletGPSDateTime")).withLabel("Date Time").build(), new ChannelDefinitionBuilder("BrickletGPSRestart", new ChannelTypeUID("tinkerforge", "BrickletGPSRestart")).withLabel("Restart").build())).withProperties(props).build();
    }

    public static @Nullable ConfigDescription getConfigDescription(URI uri) {
        switch(uri.toASCIIString()) {
            case "thing-type:tinkerforge:brickletgps":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList(ConfigDescriptionParameterBuilder.create("statusUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the status in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Status Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("altitudeUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the altitude and geodial separation in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Altitude Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build(), ConfigDescriptionParameterBuilder.create("motionUpdateInterval", Type.INTEGER).withDefault("1000").withDescription("Specifies the update interval for the course and speed in milliseconds. A value of 0 disables automatic updates.").withGroupName("update_intervals").withLabel("Motion Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build())).withParameterGroups(Arrays.asList(new ConfigDescriptionParameterGroup("update_intervals", "null", true, "Update Intervals", "Update Intervals"))).build();
            case "channel-type:tinkerforge:BrickletGPSCoordinates":
                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.").withGroupName("update_intervals").withLabel("Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build())).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletGPSFix":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletGPSSatellitesInView":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletGPSSatellitesUsed":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletGPSAltitude":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletGPSGeoidalSeparation":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletGPSCourse":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletGPSSpeed":
                return ConfigDescriptionBuilder.create(uri).withParameters(Arrays.asList()).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletGPSDateTime":
                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.").withGroupName("update_intervals").withLabel("Update Interval").withUnit("ms").withMinimum(BigDecimal.valueOf(0)).withMaximum(BigDecimal.valueOf(4294967295L)).build())).withParameterGroups(Arrays.asList()).build();
            case "channel-type:tinkerforge:BrickletGPSRestart":
                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 {
        BrickletGPSConfig cfg = (BrickletGPSConfig) config.as(BrickletGPSConfig.class);
switch(channel) {
            case "BrickletGPSLocation":
               return;
            case "BrickletGPSFix":
                   {
            BrickletGPS.Status value = this.getStatus();
            if(true)
                updateStateFn.accept(channel, transformBrickletGPSFixGetter0(value, cfg));
        }
                   return;
            case "BrickletGPSSatellitesInView":
                   {
            BrickletGPS.Status value = this.getStatus();
            if(true)
                updateStateFn.accept(channel, transformBrickletGPSSatellitesInViewGetter0(value, cfg));
        }
                   return;
            case "BrickletGPSSatellitesUsed":
                   {
            BrickletGPS.Status value = this.getStatus();
            if(true)
                updateStateFn.accept(channel, transformBrickletGPSSatellitesUsedGetter0(value, cfg));
        }
                   return;
            case "BrickletGPSAltitude":
                   {
            BrickletGPS.Altitude value = this.getAltitude();
            if(true)
                updateStateFn.accept(channel, transformBrickletGPSAltitudeGetter0(value, cfg));
        }
                   return;
            case "BrickletGPSGeoidalSeparation":
                   {
            BrickletGPS.Altitude value = this.getAltitude();
            if(true)
                updateStateFn.accept(channel, transformBrickletGPSGeoidalSeparationGetter0(value, cfg));
        }
                   return;
            case "BrickletGPSCourse":
                   {
            BrickletGPS.Motion value = this.getMotion();
            if(true)
                updateStateFn.accept(channel, transformBrickletGPSCourseGetter0(value, cfg));
        }
                   return;
            case "BrickletGPSSpeed":
                   {
            BrickletGPS.Motion value = this.getMotion();
            if(true)
                updateStateFn.accept(channel, transformBrickletGPSSpeedGetter0(value, cfg));
        }
                   return;
            case "BrickletGPSDateTime":
                   {
            BrickletGPS.DateTime value = this.getDateTime();
            if(true)
                updateStateFn.accept(channel, transformBrickletGPSDateTimeGetter0(value, cfg));
        }
                   return;
            case "BrickletGPSRestart":
               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 "BrickletGPSRestart":
                if (command instanceof StringType) {
                    StringType cmd = (StringType) command;
this.restart(Short.valueOf(cmd.toString()));
                }
        
                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 transformBrickletGPSLocationCallback0(long latitude, char ns, long longitude, char ew, int pdop, int hdop, int vdop, int epe, BrickletGPSConfig cfg) {
        return new PointType(new DecimalType(latitude / 1000000.0 * (ns == 'N' ? 1 : -1)), new DecimalType(longitude / 1000000.0 * (ew == 'E' ? 1 : -1)));
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSFixCallback0(short fix, short satellitesView, short satellitesUsed, BrickletGPSConfig cfg) {
        return fix > 1 ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSSatellitesInViewCallback0(short fix, short satellitesView, short satellitesUsed, BrickletGPSConfig cfg) {
        return new DecimalType(satellitesView);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSSatellitesUsedCallback0(short fix, short satellitesView, short satellitesUsed, BrickletGPSConfig cfg) {
        return new DecimalType(satellitesUsed);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSAltitudeCallback0(int altitude, int geoidalSeparation, BrickletGPSConfig cfg) {
        return new QuantityType<>(altitude / 100.0, SIUnits.METRE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSGeoidalSeparationCallback0(int altitude, int geoidalSeparation, BrickletGPSConfig cfg) {
        return new QuantityType<>(geoidalSeparation / 100.0, SIUnits.METRE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSCourseCallback0(long course, long speed, BrickletGPSConfig cfg) {
        return new QuantityType<>(course / 100.0, SmartHomeUnits.DEGREE_ANGLE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSSpeedCallback0(long course, long speed, BrickletGPSConfig cfg) {
        return new QuantityType<>(speed / 100.0, SIUnits.KILOMETRE_PER_HOUR);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSDateTimeCallback0(long date, long time, BrickletGPSConfig cfg) {
        return new DateTimeType(Helper.parseGPSDateTime(date, time).withZoneSameInstant(ZoneId.systemDefault()));
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSFixGetter0(BrickletGPS.Status value, BrickletGPSConfig cfg) {
        return value.fix > 1 ? OpenClosedType.CLOSED : OpenClosedType.OPEN;
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSSatellitesInViewGetter0(BrickletGPS.Status value, BrickletGPSConfig cfg) {
        return new DecimalType(value.satellitesView);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSSatellitesUsedGetter0(BrickletGPS.Status value, BrickletGPSConfig cfg) {
        return new DecimalType(value.satellitesUsed);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSAltitudeGetter0(BrickletGPS.Altitude value, BrickletGPSConfig cfg) {
        return new QuantityType<>(value.altitude / 100.0, SIUnits.METRE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSGeoidalSeparationGetter0(BrickletGPS.Altitude value, BrickletGPSConfig cfg) {
        return new QuantityType<>(value.geoidalSeparation / 100.0, SIUnits.METRE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSCourseGetter0(BrickletGPS.Motion value, BrickletGPSConfig cfg) {
        return new QuantityType<>(value.course / 100.0, SmartHomeUnits.DEGREE_ANGLE);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSSpeedGetter0(BrickletGPS.Motion value, BrickletGPSConfig cfg) {
        return new QuantityType<>(value.speed / 100.0, SIUnits.KILOMETRE_PER_HOUR);
    }
	    private org.eclipse.smarthome.core.types.State transformBrickletGPSDateTimeGetter0(BrickletGPS.DateTime value, BrickletGPSConfig cfg) {
        return new DateTimeType(Helper.parseGPSDateTime(value.date, value.time).withZoneSameInstant(ZoneId.systemDefault()));
    }

}