/** Starts a verticle for the device with the unique device ID \c uid. */
  @Override
  public void start() throws Exception {

    apiVersion[0] = 2;
    apiVersion[1] = 0;
    apiVersion[2] = 0;

    logger = LoggerFactory.getLogger(getClass());

    logger.info("Verticle started: " + BrickletVoltage.class);
    uidString = config().getString("uid");
    uidBytes = Utils.uid2long(uidString);

    vertx
        .eventBus()
        .consumer(
            uidString,
            message -> {
              Buffer msgBuffer = (Buffer) message.body();
              Packet packet = new Packet(msgBuffer);
              logger.trace("got request: {}", packet.toString());
              Set<Object> handlerids = vertx.sharedData().getLocalMap(Brickd.HANDLERIDMAP).keySet();
              for (Object handlerid : handlerids) {
                Buffer buffer = callFunction(packet);
                // TODO add logging
                if (packet.getResponseExpected()) {
                  if (buffer != null) {
                    logger.trace("sending answer: {}", new Packet(buffer).toString());
                    vertx.eventBus().publish((String) handlerid, buffer);
                  } else {
                    logger.trace("buffer is null");
                  }
                }
              }
            });

    // broadcast queue for enumeration requests
    vertx
        .eventBus()
        .consumer(
            CommonServices.BROADCAST_UID,
            message -> {
              Set<Object> handlerids = vertx.sharedData().getLocalMap(Brickd.HANDLERIDMAP).keySet();
              if (handlerids != null) {
                logger.debug("sending enumerate answer");
                for (Object handlerid : handlerids) {
                  vertx
                      .eventBus()
                      .publish(
                          (String) handlerid,
                          Utils.getEnumerateResponse(uidString, uidBytes, DEVICE_IDENTIFIER));
                }
              } else {
                logger.error("no handlerids found");
              }
            });
  }
 private Buffer setVoltageCallbackThreshold(Packet packet) {
   logger.debug("function setVoltageCallbackThreshold");
   if (packet.getResponseExpected()) {
     byte length = (byte) 8 + 0;
     byte functionId = FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD;
     byte flags = (byte) 0;
     Buffer header = Utils.createHeader(uidBytes, length, functionId, packet.getOptions(), flags);
     Buffer buffer = Buffer.buffer();
     buffer.appendBuffer(header);
     // TODO response expected bei settern
     return buffer;
   }
   this.voltageCallbackThreshold = packet.getPayload();
   return null;
 }
  private Buffer getIdentity(Packet packet) {
    logger.debug("function getIdentity");
    if (packet.getResponseExpected()) {
      byte length = (byte) 8 + 25;
      byte functionId = FUNCTION_GET_IDENTITY;
      byte flags = (byte) 0;
      Buffer header = Utils.createHeader(uidBytes, length, functionId, packet.getOptions(), flags);
      Buffer buffer = Buffer.buffer();
      buffer.appendBuffer(header);
      buffer.appendBuffer(Utils.getIdentityPayload(uidString, uidBytes, DEVICE_IDENTIFIER));
      return buffer;
    }

    return null;
  }
 private Buffer setAnalogValueCallbackPeriod(Packet packet) {
   logger.debug("function setAnalogValueCallbackPeriod");
   if (packet.getResponseExpected()) {
     byte length = (byte) 8 + 0;
     byte functionId = FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD;
     byte flags = (byte) 0;
     Buffer header = Utils.createHeader(uidBytes, length, functionId, packet.getOptions(), flags);
     Buffer buffer = Buffer.buffer();
     buffer.appendBuffer(header);
     // TODO response expected bei settern
     return buffer;
   }
   this.analogValueCallbackPeriod = packet.getPayload();
   return null;
 }
  private Buffer getAnalogValueCallbackThreshold(Packet packet) {
    logger.debug("function getAnalogValueCallbackThreshold");
    if (packet.getResponseExpected()) {
      byte length = (byte) 8 + 5;
      byte functionId = FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD;
      byte flags = (byte) 0;
      Buffer header = Utils.createHeader(uidBytes, length, functionId, packet.getOptions(), flags);
      Buffer buffer = Buffer.buffer();
      buffer.appendBuffer(header);
      buffer.appendBuffer(this.analogValueCallbackThreshold);
      return buffer;
    }

    return null;
  }
  private Buffer getVoltageCallbackPeriod(Packet packet) {
    logger.debug("function getVoltageCallbackPeriod");
    if (packet.getResponseExpected()) {
      byte length = (byte) 8 + 4;
      byte functionId = FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD;
      byte flags = (byte) 0;
      Buffer header = Utils.createHeader(uidBytes, length, functionId, packet.getOptions(), flags);
      Buffer buffer = Buffer.buffer();
      buffer.appendBuffer(header);
      buffer.appendBuffer(this.voltageCallbackPeriod);
      return buffer;
    }

    return null;
  }
  private Buffer getVoltage(Packet packet) {
    logger.debug("function getVoltage");
    if (packet.getResponseExpected()) {
      byte length = (byte) 8 + 2;
      byte functionId = FUNCTION_GET_VOLTAGE;
      byte flags = (byte) 0;
      Buffer header = Utils.createHeader(uidBytes, length, functionId, packet.getOptions(), flags);
      Buffer buffer = Buffer.buffer();
      buffer.appendBuffer(header);
      buffer.appendBytes(Utils.get2ByteURandomValue(1));

      return buffer;
    }

    return null;
  }
 private Buffer callFunction(Packet packet) {
   Buffer buffer = null;
   byte functionId = packet.getFunctionId();
   if (functionId == 0) {
     // TODO raise Exception or log error
   } else if (functionId == FUNCTION_GET_VOLTAGE) {
     buffer = getVoltage(packet);
   } else if (functionId == FUNCTION_GET_ANALOG_VALUE) {
     buffer = getAnalogValue(packet);
   } else if (functionId == FUNCTION_SET_VOLTAGE_CALLBACK_PERIOD) {
     buffer = setVoltageCallbackPeriod(packet);
   } else if (functionId == FUNCTION_GET_VOLTAGE_CALLBACK_PERIOD) {
     buffer = getVoltageCallbackPeriod(packet);
   } else if (functionId == FUNCTION_SET_ANALOG_VALUE_CALLBACK_PERIOD) {
     buffer = setAnalogValueCallbackPeriod(packet);
   } else if (functionId == FUNCTION_GET_ANALOG_VALUE_CALLBACK_PERIOD) {
     buffer = getAnalogValueCallbackPeriod(packet);
   } else if (functionId == FUNCTION_SET_VOLTAGE_CALLBACK_THRESHOLD) {
     buffer = setVoltageCallbackThreshold(packet);
   } else if (functionId == FUNCTION_GET_VOLTAGE_CALLBACK_THRESHOLD) {
     buffer = getVoltageCallbackThreshold(packet);
   } else if (functionId == FUNCTION_SET_ANALOG_VALUE_CALLBACK_THRESHOLD) {
     buffer = setAnalogValueCallbackThreshold(packet);
   } else if (functionId == FUNCTION_GET_ANALOG_VALUE_CALLBACK_THRESHOLD) {
     buffer = getAnalogValueCallbackThreshold(packet);
   } else if (functionId == FUNCTION_SET_DEBOUNCE_PERIOD) {
     buffer = setDebouncePeriod(packet);
   } else if (functionId == FUNCTION_GET_DEBOUNCE_PERIOD) {
     buffer = getDebouncePeriod(packet);
   } else if (functionId == FUNCTION_GET_IDENTITY) {
     buffer = getIdentity(packet);
   } else {
     // TODO: raise Exception or log error
   }
   return buffer;
 }