/**
 * 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 org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jdt.annotation.NonNull;
import org.openhab.binding.tinkerforge.internal.handler.DeviceHandler;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.binding.ThingActions;
import org.eclipse.smarthome.core.thing.binding.ThingActionsScope;
import org.eclipse.smarthome.core.thing.binding.ThingHandler;
import org.eclipse.smarthome.core.types.RefreshType;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.openhab.core.automation.annotation.ActionInput;
import org.openhab.core.automation.annotation.ActionOutput;
import org.openhab.core.automation.annotation.RuleAction;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import java.util.Map;
import java.util.HashMap;

import com.tinkerforge.TinkerforgeException;
import com.tinkerforge.BrickRED;

/**
 * Passes through actions of the RED Brick.
 * @author Erik Fleckstein - Initial contribution
 */
@ThingActionsScope(name = "tinkerforge")
@NonNullByDefault
public class BrickREDActions implements ThingActions, IBrickREDActions {

    private @Nullable DeviceHandler handler;

    @Override
    public void setThingHandler(@Nullable ThingHandler handler) { this.handler = (DeviceHandler) handler; }

    @Override
    public @Nullable ThingHandler getThingHandler() { return handler; }

    private static IBrickREDActions invokeMethodOf(@Nullable ThingActions actions) {
        if (actions == null) {
            throw new IllegalArgumentException("actions cannot be null");
        }
        if (actions.getClass().getName().equals(BrickREDActions.class.getName())) {
            if (actions instanceof IBrickREDActions) {
                return (IBrickREDActions) actions;
            } else {
                return (IBrickREDActions) Proxy.newProxyInstance(IBrickREDActions.class.getClassLoader(),
                        new Class[] { IBrickREDActions.class }, (Object proxy, Method method, Object[] args) -> {
                            Method m = actions.getClass().getDeclaredMethod(method.getName(),
                                    method.getParameterTypes());
                            return m.invoke(actions, args);
                        });
            }
        }
        throw new IllegalArgumentException("Actions is not an instance of BrickREDActions");
    }

    
    @Override
    @RuleAction(label = "Create Session")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "sessionId", type="int")
           Map<String, Object> brickREDCreateSession(
            @ActionInput(name = "lifetime") long lifetime) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.CreateSession value = dev.createSession(lifetime);
        
        result.put("errorCode", value.errorCode);
        result.put("sessionId", value.sessionId);
        return result;
    }

    public static Map<String, Object> brickREDCreateSession(@Nullable ThingActions actions, long lifetime) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDCreateSession(lifetime);
    }


    @Override
    @RuleAction(label = "Expire Session")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDExpireSession(
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.expireSession(sessionId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDExpireSession(@Nullable ThingActions actions, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDExpireSession(sessionId);
    }

    @Override
    @RuleAction(label = "Expire Session Unchecked")
    public void brickREDExpireSessionUnchecked(
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        DeviceHandler h = handler;
        if(h == null) {
            return;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return;
        }
        dev.expireSessionUnchecked(sessionId);
        
    }

    public static void brickREDExpireSessionUnchecked(@Nullable ThingActions actions, int sessionId) throws TinkerforgeException {
        invokeMethodOf(actions).brickREDExpireSessionUnchecked(sessionId);
    }


    @Override
    @RuleAction(label = "Keep Session Alive")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDKeepSessionAlive(
            @ActionInput(name = "sessionId") int sessionId,
            @ActionInput(name = "lifetime") long lifetime) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.keepSessionAlive(sessionId, lifetime);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDKeepSessionAlive(@Nullable ThingActions actions, int sessionId, long lifetime) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDKeepSessionAlive(sessionId, lifetime);
    }


    @Override
    @RuleAction(label = "Release Object")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDReleaseObject(
            @ActionInput(name = "objectId") int objectId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.releaseObject(objectId, sessionId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDReleaseObject(@Nullable ThingActions actions, int objectId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDReleaseObject(objectId, sessionId);
    }

    @Override
    @RuleAction(label = "Release Object Unchecked")
    public void brickREDReleaseObjectUnchecked(
            @ActionInput(name = "objectId") int objectId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        DeviceHandler h = handler;
        if(h == null) {
            return;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return;
        }
        dev.releaseObjectUnchecked(objectId, sessionId);
        
    }

    public static void brickREDReleaseObjectUnchecked(@Nullable ThingActions actions, int objectId, int sessionId) throws TinkerforgeException {
        invokeMethodOf(actions).brickREDReleaseObjectUnchecked(objectId, sessionId);
    }


    @Override
    @RuleAction(label = "Allocate String")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "stringId", type="int")
           Map<String, Object> brickREDAllocateString(
            @ActionInput(name = "lengthToReserve") long lengthToReserve,
            @ActionInput(name = "buffer") String buffer,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.AllocateString value = dev.allocateString(lengthToReserve, buffer, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("stringId", value.stringId);
        return result;
    }

    public static Map<String, Object> brickREDAllocateString(@Nullable ThingActions actions, long lengthToReserve, String buffer, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDAllocateString(lengthToReserve, buffer, sessionId);
    }


    @Override
    @RuleAction(label = "Truncate String")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDTruncateString(
            @ActionInput(name = "stringId") int stringId,
            @ActionInput(name = "length") long length) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.truncateString(stringId, length);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDTruncateString(@Nullable ThingActions actions, int stringId, long length) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDTruncateString(stringId, length);
    }


    @Override
    @RuleAction(label = "Get String Length")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "length", type="long")
           Map<String, Object> brickREDGetStringLength(
            @ActionInput(name = "stringId") int stringId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.StringLength value = dev.getStringLength(stringId);
        
        result.put("errorCode", value.errorCode);
        result.put("length", value.length);
        return result;
    }

    public static Map<String, Object> brickREDGetStringLength(@Nullable ThingActions actions, int stringId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetStringLength(stringId);
    }


    @Override
    @RuleAction(label = "Set String Chunk")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDSetStringChunk(
            @ActionInput(name = "stringId") int stringId,
            @ActionInput(name = "offset") long offset,
            @ActionInput(name = "buffer") String buffer) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.setStringChunk(stringId, offset, buffer);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDSetStringChunk(@Nullable ThingActions actions, int stringId, long offset, String buffer) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDSetStringChunk(stringId, offset, buffer);
    }


    @Override
    @RuleAction(label = "Get String Chunk")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "buffer", type="String")
           Map<String, Object> brickREDGetStringChunk(
            @ActionInput(name = "stringId") int stringId,
            @ActionInput(name = "offset") long offset) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.StringChunk value = dev.getStringChunk(stringId, offset);
        
        result.put("errorCode", value.errorCode);
        result.put("buffer", value.buffer);
        return result;
    }

    public static Map<String, Object> brickREDGetStringChunk(@Nullable ThingActions actions, int stringId, long offset) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetStringChunk(stringId, offset);
    }


    @Override
    @RuleAction(label = "Allocate List")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "listId", type="int")
           Map<String, Object> brickREDAllocateList(
            @ActionInput(name = "lengthToReserve") int lengthToReserve,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.AllocateList value = dev.allocateList(lengthToReserve, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("listId", value.listId);
        return result;
    }

    public static Map<String, Object> brickREDAllocateList(@Nullable ThingActions actions, int lengthToReserve, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDAllocateList(lengthToReserve, sessionId);
    }


    @Override
    @RuleAction(label = "Get List Length")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "length", type="int")
           Map<String, Object> brickREDGetListLength(
            @ActionInput(name = "listId") int listId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ListLength value = dev.getListLength(listId);
        
        result.put("errorCode", value.errorCode);
        result.put("length", value.length);
        return result;
    }

    public static Map<String, Object> brickREDGetListLength(@Nullable ThingActions actions, int listId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetListLength(listId);
    }


    @Override
    @RuleAction(label = "Get List Item")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "itemObjectId", type="int")
           @ActionOutput(name = "type", type="short")
           Map<String, Object> brickREDGetListItem(
            @ActionInput(name = "listId") int listId,
            @ActionInput(name = "index") int index,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ListItem value = dev.getListItem(listId, index, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("itemObjectId", value.itemObjectId);
        result.put("type", value.type);
        return result;
    }

    public static Map<String, Object> brickREDGetListItem(@Nullable ThingActions actions, int listId, int index, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetListItem(listId, index, sessionId);
    }


    @Override
    @RuleAction(label = "Append To List")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDAppendToList(
            @ActionInput(name = "listId") int listId,
            @ActionInput(name = "itemObjectId") int itemObjectId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.appendToList(listId, itemObjectId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDAppendToList(@Nullable ThingActions actions, int listId, int itemObjectId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDAppendToList(listId, itemObjectId);
    }


    @Override
    @RuleAction(label = "Remove From List")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDRemoveFromList(
            @ActionInput(name = "listId") int listId,
            @ActionInput(name = "index") int index) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.removeFromList(listId, index);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDRemoveFromList(@Nullable ThingActions actions, int listId, int index) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDRemoveFromList(listId, index);
    }


    @Override
    @RuleAction(label = "Open File")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "fileId", type="int")
           Map<String, Object> brickREDOpenFile(
            @ActionInput(name = "nameStringId") int nameStringId,
            @ActionInput(name = "flags") long flags,
            @ActionInput(name = "permissions") int permissions,
            @ActionInput(name = "uid") long uid,
            @ActionInput(name = "gid") long gid,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.OpenFile value = dev.openFile(nameStringId, flags, permissions, uid, gid, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("fileId", value.fileId);
        return result;
    }

    public static Map<String, Object> brickREDOpenFile(@Nullable ThingActions actions, int nameStringId, long flags, int permissions, long uid, long gid, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDOpenFile(nameStringId, flags, permissions, uid, gid, sessionId);
    }


    @Override
    @RuleAction(label = "Create Pipe")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "fileId", type="int")
           Map<String, Object> brickREDCreatePipe(
            @ActionInput(name = "flags") long flags,
            @ActionInput(name = "length") long length,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.CreatePipe value = dev.createPipe(flags, length, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("fileId", value.fileId);
        return result;
    }

    public static Map<String, Object> brickREDCreatePipe(@Nullable ThingActions actions, long flags, long length, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDCreatePipe(flags, length, sessionId);
    }


    @Override
    @RuleAction(label = "Get File Info")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "type", type="short")
           @ActionOutput(name = "nameStringId", type="int")
           @ActionOutput(name = "flags", type="long")
           @ActionOutput(name = "permissions", type="int")
           @ActionOutput(name = "uid", type="long")
           @ActionOutput(name = "gid", type="long")
           @ActionOutput(name = "length", type="long")
           @ActionOutput(name = "accessTimestamp", type="long")
           @ActionOutput(name = "modificationTimestamp", type="long")
           @ActionOutput(name = "statusChangeTimestamp", type="long")
           Map<String, Object> brickREDGetFileInfo(
            @ActionInput(name = "fileId") int fileId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.FileInfo value = dev.getFileInfo(fileId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("type", value.type);
        result.put("nameStringId", value.nameStringId);
        result.put("flags", value.flags);
        result.put("permissions", value.permissions);
        result.put("uid", value.uid);
        result.put("gid", value.gid);
        result.put("length", value.length);
        result.put("accessTimestamp", value.accessTimestamp);
        result.put("modificationTimestamp", value.modificationTimestamp);
        result.put("statusChangeTimestamp", value.statusChangeTimestamp);
        return result;
    }

    public static Map<String, Object> brickREDGetFileInfo(@Nullable ThingActions actions, int fileId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetFileInfo(fileId, sessionId);
    }


    @Override
    @RuleAction(label = "Read File")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "buffer", type="short[]")
           @ActionOutput(name = "lengthRead", type="short")
           Map<String, Object> brickREDReadFile(
            @ActionInput(name = "fileId") int fileId,
            @ActionInput(name = "lengthToRead") short lengthToRead) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ReadFile value = dev.readFile(fileId, lengthToRead);
        
        result.put("errorCode", value.errorCode);
        result.put("buffer", value.buffer);
        result.put("lengthRead", value.lengthRead);
        return result;
    }

    public static Map<String, Object> brickREDReadFile(@Nullable ThingActions actions, int fileId, short lengthToRead) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDReadFile(fileId, lengthToRead);
    }


    @Override
    @RuleAction(label = "Write File")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "lengthWritten", type="short")
           Map<String, Object> brickREDWriteFile(
            @ActionInput(name = "fileId") int fileId,
            @ActionInput(name = "buffer") short[] buffer,
            @ActionInput(name = "lengthToWrite") short lengthToWrite) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.WriteFile value = dev.writeFile(fileId, buffer, lengthToWrite);
        
        result.put("errorCode", value.errorCode);
        result.put("lengthWritten", value.lengthWritten);
        return result;
    }

    public static Map<String, Object> brickREDWriteFile(@Nullable ThingActions actions, int fileId, short[] buffer, short lengthToWrite) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDWriteFile(fileId, buffer, lengthToWrite);
    }

    @Override
    @RuleAction(label = "Write File Unchecked")
    public void brickREDWriteFileUnchecked(
            @ActionInput(name = "fileId") int fileId,
            @ActionInput(name = "buffer") short[] buffer,
            @ActionInput(name = "lengthToWrite") short lengthToWrite) throws TinkerforgeException {
        DeviceHandler h = handler;
        if(h == null) {
            return;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return;
        }
        dev.writeFileUnchecked(fileId, buffer, lengthToWrite);
        
    }

    public static void brickREDWriteFileUnchecked(@Nullable ThingActions actions, int fileId, short[] buffer, short lengthToWrite) throws TinkerforgeException {
        invokeMethodOf(actions).brickREDWriteFileUnchecked(fileId, buffer, lengthToWrite);
    }


    @Override
    @RuleAction(label = "Set File Position")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "position", type="long")
           Map<String, Object> brickREDSetFilePosition(
            @ActionInput(name = "fileId") int fileId,
            @ActionInput(name = "offset") long offset,
            @ActionInput(name = "origin") short origin) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.SetFilePosition value = dev.setFilePosition(fileId, offset, origin);
        
        result.put("errorCode", value.errorCode);
        result.put("position", value.position);
        return result;
    }

    public static Map<String, Object> brickREDSetFilePosition(@Nullable ThingActions actions, int fileId, long offset, short origin) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDSetFilePosition(fileId, offset, origin);
    }


    @Override
    @RuleAction(label = "Get File Position")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "position", type="long")
           Map<String, Object> brickREDGetFilePosition(
            @ActionInput(name = "fileId") int fileId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.FilePosition value = dev.getFilePosition(fileId);
        
        result.put("errorCode", value.errorCode);
        result.put("position", value.position);
        return result;
    }

    public static Map<String, Object> brickREDGetFilePosition(@Nullable ThingActions actions, int fileId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetFilePosition(fileId);
    }


    @Override
    @RuleAction(label = "Set File Events")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDSetFileEvents(
            @ActionInput(name = "fileId") int fileId,
            @ActionInput(name = "events") int events) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.setFileEvents(fileId, events);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDSetFileEvents(@Nullable ThingActions actions, int fileId, int events) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDSetFileEvents(fileId, events);
    }


    @Override
    @RuleAction(label = "Get File Events")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "events", type="int")
           Map<String, Object> brickREDGetFileEvents(
            @ActionInput(name = "fileId") int fileId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.FileEvents value = dev.getFileEvents(fileId);
        
        result.put("errorCode", value.errorCode);
        result.put("events", value.events);
        return result;
    }

    public static Map<String, Object> brickREDGetFileEvents(@Nullable ThingActions actions, int fileId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetFileEvents(fileId);
    }


    @Override
    @RuleAction(label = "Open Directory")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "directoryId", type="int")
           Map<String, Object> brickREDOpenDirectory(
            @ActionInput(name = "nameStringId") int nameStringId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.OpenDirectory value = dev.openDirectory(nameStringId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("directoryId", value.directoryId);
        return result;
    }

    public static Map<String, Object> brickREDOpenDirectory(@Nullable ThingActions actions, int nameStringId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDOpenDirectory(nameStringId, sessionId);
    }


    @Override
    @RuleAction(label = "Get Directory Name")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "nameStringId", type="int")
           Map<String, Object> brickREDGetDirectoryName(
            @ActionInput(name = "directoryId") int directoryId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.DirectoryName value = dev.getDirectoryName(directoryId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("nameStringId", value.nameStringId);
        return result;
    }

    public static Map<String, Object> brickREDGetDirectoryName(@Nullable ThingActions actions, int directoryId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetDirectoryName(directoryId, sessionId);
    }


    @Override
    @RuleAction(label = "Get Next Directory Entry")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "nameStringId", type="int")
           @ActionOutput(name = "type", type="short")
           Map<String, Object> brickREDGetNextDirectoryEntry(
            @ActionInput(name = "directoryId") int directoryId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.NextDirectoryEntry value = dev.getNextDirectoryEntry(directoryId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("nameStringId", value.nameStringId);
        result.put("type", value.type);
        return result;
    }

    public static Map<String, Object> brickREDGetNextDirectoryEntry(@Nullable ThingActions actions, int directoryId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetNextDirectoryEntry(directoryId, sessionId);
    }


    @Override
    @RuleAction(label = "Rewind Directory")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDRewindDirectory(
            @ActionInput(name = "directoryId") int directoryId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.rewindDirectory(directoryId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDRewindDirectory(@Nullable ThingActions actions, int directoryId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDRewindDirectory(directoryId);
    }


    @Override
    @RuleAction(label = "Create Directory")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDCreateDirectory(
            @ActionInput(name = "nameStringId") int nameStringId,
            @ActionInput(name = "flags") long flags,
            @ActionInput(name = "permissions") int permissions,
            @ActionInput(name = "uid") long uid,
            @ActionInput(name = "gid") long gid) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.createDirectory(nameStringId, flags, permissions, uid, gid);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDCreateDirectory(@Nullable ThingActions actions, int nameStringId, long flags, int permissions, long uid, long gid) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDCreateDirectory(nameStringId, flags, permissions, uid, gid);
    }


    @Override
    @RuleAction(label = "Get Processes")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "processesListId", type="int")
           Map<String, Object> brickREDGetProcesses(
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.Processes value = dev.getProcesses(sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("processesListId", value.processesListId);
        return result;
    }

    public static Map<String, Object> brickREDGetProcesses(@Nullable ThingActions actions, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProcesses(sessionId);
    }


    @Override
    @RuleAction(label = "Spawn Process")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "processId", type="int")
           Map<String, Object> brickREDSpawnProcess(
            @ActionInput(name = "executableStringId") int executableStringId,
            @ActionInput(name = "argumentsListId") int argumentsListId,
            @ActionInput(name = "environmentListId") int environmentListId,
            @ActionInput(name = "workingDirectoryStringId") int workingDirectoryStringId,
            @ActionInput(name = "uid") long uid,
            @ActionInput(name = "gid") long gid,
            @ActionInput(name = "stdinFileId") int stdinFileId,
            @ActionInput(name = "stdoutFileId") int stdoutFileId,
            @ActionInput(name = "stderrFileId") int stderrFileId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.SpawnProcess value = dev.spawnProcess(executableStringId, argumentsListId, environmentListId, workingDirectoryStringId, uid, gid, stdinFileId, stdoutFileId, stderrFileId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("processId", value.processId);
        return result;
    }

    public static Map<String, Object> brickREDSpawnProcess(@Nullable ThingActions actions, int executableStringId, int argumentsListId, int environmentListId, int workingDirectoryStringId, long uid, long gid, int stdinFileId, int stdoutFileId, int stderrFileId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDSpawnProcess(executableStringId, argumentsListId, environmentListId, workingDirectoryStringId, uid, gid, stdinFileId, stdoutFileId, stderrFileId, sessionId);
    }


    @Override
    @RuleAction(label = "Kill Process")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDKillProcess(
            @ActionInput(name = "processId") int processId,
            @ActionInput(name = "signal") short signal) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.killProcess(processId, signal);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDKillProcess(@Nullable ThingActions actions, int processId, short signal) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDKillProcess(processId, signal);
    }


    @Override
    @RuleAction(label = "Get Process Command")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "executableStringId", type="int")
           @ActionOutput(name = "argumentsListId", type="int")
           @ActionOutput(name = "environmentListId", type="int")
           @ActionOutput(name = "workingDirectoryStringId", type="int")
           Map<String, Object> brickREDGetProcessCommand(
            @ActionInput(name = "processId") int processId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ProcessCommand value = dev.getProcessCommand(processId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("executableStringId", value.executableStringId);
        result.put("argumentsListId", value.argumentsListId);
        result.put("environmentListId", value.environmentListId);
        result.put("workingDirectoryStringId", value.workingDirectoryStringId);
        return result;
    }

    public static Map<String, Object> brickREDGetProcessCommand(@Nullable ThingActions actions, int processId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProcessCommand(processId, sessionId);
    }


    @Override
    @RuleAction(label = "Get Process Identity")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "pid", type="long")
           @ActionOutput(name = "uid", type="long")
           @ActionOutput(name = "gid", type="long")
           Map<String, Object> brickREDGetProcessIdentity(
            @ActionInput(name = "processId") int processId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ProcessIdentity value = dev.getProcessIdentity(processId);
        
        result.put("errorCode", value.errorCode);
        result.put("pid", value.pid);
        result.put("uid", value.uid);
        result.put("gid", value.gid);
        return result;
    }

    public static Map<String, Object> brickREDGetProcessIdentity(@Nullable ThingActions actions, int processId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProcessIdentity(processId);
    }


    @Override
    @RuleAction(label = "Get Process Stdio")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "stdinFileId", type="int")
           @ActionOutput(name = "stdoutFileId", type="int")
           @ActionOutput(name = "stderrFileId", type="int")
           Map<String, Object> brickREDGetProcessStdio(
            @ActionInput(name = "processId") int processId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ProcessStdio value = dev.getProcessStdio(processId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("stdinFileId", value.stdinFileId);
        result.put("stdoutFileId", value.stdoutFileId);
        result.put("stderrFileId", value.stderrFileId);
        return result;
    }

    public static Map<String, Object> brickREDGetProcessStdio(@Nullable ThingActions actions, int processId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProcessStdio(processId, sessionId);
    }


    @Override
    @RuleAction(label = "Get Process State")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "state", type="short")
           @ActionOutput(name = "timestamp", type="long")
           @ActionOutput(name = "exitCode", type="short")
           Map<String, Object> brickREDGetProcessState(
            @ActionInput(name = "processId") int processId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ProcessState value = dev.getProcessState(processId);
        
        result.put("errorCode", value.errorCode);
        result.put("state", value.state);
        result.put("timestamp", value.timestamp);
        result.put("exitCode", value.exitCode);
        return result;
    }

    public static Map<String, Object> brickREDGetProcessState(@Nullable ThingActions actions, int processId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProcessState(processId);
    }


    @Override
    @RuleAction(label = "Get Programs")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "programsListId", type="int")
           Map<String, Object> brickREDGetPrograms(
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.Programs value = dev.getPrograms(sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("programsListId", value.programsListId);
        return result;
    }

    public static Map<String, Object> brickREDGetPrograms(@Nullable ThingActions actions, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetPrograms(sessionId);
    }


    @Override
    @RuleAction(label = "Define Program")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "programId", type="int")
           Map<String, Object> brickREDDefineProgram(
            @ActionInput(name = "identifierStringId") int identifierStringId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.DefineProgram value = dev.defineProgram(identifierStringId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("programId", value.programId);
        return result;
    }

    public static Map<String, Object> brickREDDefineProgram(@Nullable ThingActions actions, int identifierStringId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDDefineProgram(identifierStringId, sessionId);
    }


    @Override
    @RuleAction(label = "Purge Program")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDPurgeProgram(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "cookie") long cookie) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.purgeProgram(programId, cookie);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDPurgeProgram(@Nullable ThingActions actions, int programId, long cookie) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDPurgeProgram(programId, cookie);
    }


    @Override
    @RuleAction(label = "Get Program Identifier")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "identifierStringId", type="int")
           Map<String, Object> brickREDGetProgramIdentifier(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ProgramIdentifier value = dev.getProgramIdentifier(programId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("identifierStringId", value.identifierStringId);
        return result;
    }

    public static Map<String, Object> brickREDGetProgramIdentifier(@Nullable ThingActions actions, int programId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProgramIdentifier(programId, sessionId);
    }


    @Override
    @RuleAction(label = "Get Program Root Directory")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "rootDirectoryStringId", type="int")
           Map<String, Object> brickREDGetProgramRootDirectory(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ProgramRootDirectory value = dev.getProgramRootDirectory(programId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("rootDirectoryStringId", value.rootDirectoryStringId);
        return result;
    }

    public static Map<String, Object> brickREDGetProgramRootDirectory(@Nullable ThingActions actions, int programId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProgramRootDirectory(programId, sessionId);
    }


    @Override
    @RuleAction(label = "Set Program Command")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDSetProgramCommand(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "executableStringId") int executableStringId,
            @ActionInput(name = "argumentsListId") int argumentsListId,
            @ActionInput(name = "environmentListId") int environmentListId,
            @ActionInput(name = "workingDirectoryStringId") int workingDirectoryStringId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.setProgramCommand(programId, executableStringId, argumentsListId, environmentListId, workingDirectoryStringId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDSetProgramCommand(@Nullable ThingActions actions, int programId, int executableStringId, int argumentsListId, int environmentListId, int workingDirectoryStringId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDSetProgramCommand(programId, executableStringId, argumentsListId, environmentListId, workingDirectoryStringId);
    }


    @Override
    @RuleAction(label = "Get Program Command")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "executableStringId", type="int")
           @ActionOutput(name = "argumentsListId", type="int")
           @ActionOutput(name = "environmentListId", type="int")
           @ActionOutput(name = "workingDirectoryStringId", type="int")
           Map<String, Object> brickREDGetProgramCommand(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ProgramCommand value = dev.getProgramCommand(programId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("executableStringId", value.executableStringId);
        result.put("argumentsListId", value.argumentsListId);
        result.put("environmentListId", value.environmentListId);
        result.put("workingDirectoryStringId", value.workingDirectoryStringId);
        return result;
    }

    public static Map<String, Object> brickREDGetProgramCommand(@Nullable ThingActions actions, int programId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProgramCommand(programId, sessionId);
    }


    @Override
    @RuleAction(label = "Set Program Stdio Redirection")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDSetProgramStdioRedirection(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "stdinRedirection") short stdinRedirection,
            @ActionInput(name = "stdinFileNameStringId") int stdinFileNameStringId,
            @ActionInput(name = "stdoutRedirection") short stdoutRedirection,
            @ActionInput(name = "stdoutFileNameStringId") int stdoutFileNameStringId,
            @ActionInput(name = "stderrRedirection") short stderrRedirection,
            @ActionInput(name = "stderrFileNameStringId") int stderrFileNameStringId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.setProgramStdioRedirection(programId, stdinRedirection, stdinFileNameStringId, stdoutRedirection, stdoutFileNameStringId, stderrRedirection, stderrFileNameStringId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDSetProgramStdioRedirection(@Nullable ThingActions actions, int programId, short stdinRedirection, int stdinFileNameStringId, short stdoutRedirection, int stdoutFileNameStringId, short stderrRedirection, int stderrFileNameStringId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDSetProgramStdioRedirection(programId, stdinRedirection, stdinFileNameStringId, stdoutRedirection, stdoutFileNameStringId, stderrRedirection, stderrFileNameStringId);
    }


    @Override
    @RuleAction(label = "Get Program Stdio Redirection")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "stdinRedirection", type="short")
           @ActionOutput(name = "stdinFileNameStringId", type="int")
           @ActionOutput(name = "stdoutRedirection", type="short")
           @ActionOutput(name = "stdoutFileNameStringId", type="int")
           @ActionOutput(name = "stderrRedirection", type="short")
           @ActionOutput(name = "stderrFileNameStringId", type="int")
           Map<String, Object> brickREDGetProgramStdioRedirection(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ProgramStdioRedirection value = dev.getProgramStdioRedirection(programId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("stdinRedirection", value.stdinRedirection);
        result.put("stdinFileNameStringId", value.stdinFileNameStringId);
        result.put("stdoutRedirection", value.stdoutRedirection);
        result.put("stdoutFileNameStringId", value.stdoutFileNameStringId);
        result.put("stderrRedirection", value.stderrRedirection);
        result.put("stderrFileNameStringId", value.stderrFileNameStringId);
        return result;
    }

    public static Map<String, Object> brickREDGetProgramStdioRedirection(@Nullable ThingActions actions, int programId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProgramStdioRedirection(programId, sessionId);
    }


    @Override
    @RuleAction(label = "Set Program Schedule")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDSetProgramSchedule(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "startMode") short startMode,
            @ActionInput(name = "continueAfterError") boolean continueAfterError,
            @ActionInput(name = "startInterval") long startInterval,
            @ActionInput(name = "startFieldsStringId") int startFieldsStringId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.setProgramSchedule(programId, startMode, continueAfterError, startInterval, startFieldsStringId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDSetProgramSchedule(@Nullable ThingActions actions, int programId, short startMode, boolean continueAfterError, long startInterval, int startFieldsStringId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDSetProgramSchedule(programId, startMode, continueAfterError, startInterval, startFieldsStringId);
    }


    @Override
    @RuleAction(label = "Get Program Schedule")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "startMode", type="short")
           @ActionOutput(name = "continueAfterError", type="boolean")
           @ActionOutput(name = "startInterval", type="long")
           @ActionOutput(name = "startFieldsStringId", type="int")
           Map<String, Object> brickREDGetProgramSchedule(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ProgramSchedule value = dev.getProgramSchedule(programId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("startMode", value.startMode);
        result.put("continueAfterError", value.continueAfterError);
        result.put("startInterval", value.startInterval);
        result.put("startFieldsStringId", value.startFieldsStringId);
        return result;
    }

    public static Map<String, Object> brickREDGetProgramSchedule(@Nullable ThingActions actions, int programId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProgramSchedule(programId, sessionId);
    }


    @Override
    @RuleAction(label = "Get Program Scheduler State")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "state", type="short")
           @ActionOutput(name = "timestamp", type="long")
           @ActionOutput(name = "messageStringId", type="int")
           Map<String, Object> brickREDGetProgramSchedulerState(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.ProgramSchedulerState value = dev.getProgramSchedulerState(programId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("state", value.state);
        result.put("timestamp", value.timestamp);
        result.put("messageStringId", value.messageStringId);
        return result;
    }

    public static Map<String, Object> brickREDGetProgramSchedulerState(@Nullable ThingActions actions, int programId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetProgramSchedulerState(programId, sessionId);
    }


    @Override
    @RuleAction(label = "Continue Program Schedule")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDContinueProgramSchedule(
            @ActionInput(name = "programId") int programId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.continueProgramSchedule(programId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDContinueProgramSchedule(@Nullable ThingActions actions, int programId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDContinueProgramSchedule(programId);
    }


    @Override
    @RuleAction(label = "Start Program")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDStartProgram(
            @ActionInput(name = "programId") int programId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.startProgram(programId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDStartProgram(@Nullable ThingActions actions, int programId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDStartProgram(programId);
    }


    @Override
    @RuleAction(label = "Get Last Spawned Program Process")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "processId", type="int")
           @ActionOutput(name = "timestamp", type="long")
           Map<String, Object> brickREDGetLastSpawnedProgramProcess(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.LastSpawnedProgramProcess value = dev.getLastSpawnedProgramProcess(programId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("processId", value.processId);
        result.put("timestamp", value.timestamp);
        return result;
    }

    public static Map<String, Object> brickREDGetLastSpawnedProgramProcess(@Nullable ThingActions actions, int programId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetLastSpawnedProgramProcess(programId, sessionId);
    }


    @Override
    @RuleAction(label = "Get Custom Program Option Names")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "namesListId", type="int")
           Map<String, Object> brickREDGetCustomProgramOptionNames(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.CustomProgramOptionNames value = dev.getCustomProgramOptionNames(programId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("namesListId", value.namesListId);
        return result;
    }

    public static Map<String, Object> brickREDGetCustomProgramOptionNames(@Nullable ThingActions actions, int programId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetCustomProgramOptionNames(programId, sessionId);
    }


    @Override
    @RuleAction(label = "Set Custom Program Option Value")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDSetCustomProgramOptionValue(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "nameStringId") int nameStringId,
            @ActionInput(name = "valueStringId") int valueStringId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.setCustomProgramOptionValue(programId, nameStringId, valueStringId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDSetCustomProgramOptionValue(@Nullable ThingActions actions, int programId, int nameStringId, int valueStringId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDSetCustomProgramOptionValue(programId, nameStringId, valueStringId);
    }


    @Override
    @RuleAction(label = "Get Custom Program Option Value")
    public @ActionOutput(name = "errorCode", type="short")
           @ActionOutput(name = "valueStringId", type="int")
           Map<String, Object> brickREDGetCustomProgramOptionValue(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "nameStringId") int nameStringId,
            @ActionInput(name = "sessionId") int sessionId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.CustomProgramOptionValue value = dev.getCustomProgramOptionValue(programId, nameStringId, sessionId);
        
        result.put("errorCode", value.errorCode);
        result.put("valueStringId", value.valueStringId);
        return result;
    }

    public static Map<String, Object> brickREDGetCustomProgramOptionValue(@Nullable ThingActions actions, int programId, int nameStringId, int sessionId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetCustomProgramOptionValue(programId, nameStringId, sessionId);
    }


    @Override
    @RuleAction(label = "Remove Custom Program Option")
    public @ActionOutput(name = "errorCode", type="short")
           Map<String, Object> brickREDRemoveCustomProgramOption(
            @ActionInput(name = "programId") int programId,
            @ActionInput(name = "nameStringId") int nameStringId) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        short value = dev.removeCustomProgramOption(programId, nameStringId);
        
        result.put("errorCode", value);
        return result;
    }

    public static Map<String, Object> brickREDRemoveCustomProgramOption(@Nullable ThingActions actions, int programId, int nameStringId) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDRemoveCustomProgramOption(programId, nameStringId);
    }


    @Override
    @RuleAction(label = "Get Identity")
    public @ActionOutput(name = "uid", type="String")
           @ActionOutput(name = "connectedUid", type="String")
           @ActionOutput(name = "position", type="char")
           @ActionOutput(name = "hardwareVersion", type="short[]")
           @ActionOutput(name = "firmwareVersion", type="short[]")
           @ActionOutput(name = "deviceIdentifier", type="int")
           Map<String, Object> brickREDGetIdentity(
            ) throws TinkerforgeException {
        Map<String, Object> result = new HashMap<>();
        DeviceHandler h = handler;
        if(h == null) {
            return result;
        }
        
        @Nullable BrickREDWrapper dev = ((@Nullable BrickREDWrapper)h.getDevice());
        if(dev == null) {
            return result;
        }

        BrickRED.Identity value = dev.getIdentity();
        
        result.put("uid", value.uid);
        result.put("connectedUid", value.connectedUid);
        result.put("position", value.position);
        result.put("hardwareVersion", value.hardwareVersion);
        result.put("firmwareVersion", value.firmwareVersion);
        result.put("deviceIdentifier", value.deviceIdentifier);
        return result;
    }

    public static Map<String, Object> brickREDGetIdentity(@Nullable ThingActions actions) throws TinkerforgeException {
        return invokeMethodOf(actions).brickREDGetIdentity();
    }
}
