private List<MetricsBulletChartNVD3> getMetricsBulletChart(
      List<Integer> variableIds, Long timestampFrom, Long timestampTo) {
    ArrayList<MetricsBulletChartNVD3> bulletCharts = new ArrayList<MetricsBulletChartNVD3>();
    List<SensorVariable> sensorVariables = DaoUtils.getSensorVariableDao().getAll(variableIds);
    // Update from/to time
    MetricsDoubleTypeDevice queryInput =
        MetricsDoubleTypeDevice.builder()
            .timestampFrom(timestampFrom)
            .timestampTo(timestampTo)
            .build();
    for (SensorVariable sensorVariable : sensorVariables) {
      // Update sensor variable
      queryInput.setSensorVariable(sensorVariable);
      MetricsDoubleTypeDevice metric =
          DaoUtils.getMetricsDoubleTypeDeviceDao().getMinMaxAvg(queryInput);

      String unit = sensorVariable.getUnit() != "" ? " (" + sensorVariable.getUnit() + ")" : "";

      // If current value not available, do not allow any value
      if (sensorVariable.getValue() == null || metric.getMin() == null) {
        bulletCharts.add(
            MetricsBulletChartNVD3.builder()
                .id(sensorVariable.getId())
                .resourceName(
                    new ResourceModel(RESOURCE_TYPE.SENSOR_VARIABLE, sensorVariable)
                            .getResourceLessDetails()
                        + unit)
                .displayName(
                    sensorVariable.getSensor().getName()
                        + " >> "
                        + sensorVariable.getVariableType().getText()
                        + unit)
                .build());
      } else {
        bulletCharts.add(
            MetricsBulletChartNVD3.builder()
                .id(sensorVariable.getId())
                // .title(sensorVariable.getVariableType().getText())
                // .subtitle(sensorVariable.getUnit())
                .ranges(new Object[] {metric.getMin(), metric.getAvg(), metric.getMax()})
                .measures(new Object[] {sensorVariable.getValue()})
                .markers(new Object[] {sensorVariable.getPreviousValue()})
                .resourceName(
                    new ResourceModel(RESOURCE_TYPE.SENSOR_VARIABLE, sensorVariable)
                            .getResourceLessDetails()
                        + unit)
                .displayName(
                    sensorVariable.getSensor().getName()
                        + " >> "
                        + sensorVariable.getVariableType().getText()
                        + unit)
                .build());
      }
    }
    return bulletCharts;
  }
 private void checkHearbeat() {
   List<Node> nodes = DaoUtils.getNodeDao().getAll();
   long aliveCheckInterval =
       ObjectFactory.getAppProperties().getControllerSettings().getAliveCheckInterval();
   if (aliveCheckInterval < MycUtils.MINUTE) {
     aliveCheckInterval = MycUtils.MINUTE;
   }
   for (Node node : nodes) {
     if (node.getLastSeen() == null
         || node.getLastSeen() <= (System.currentTimeMillis() - aliveCheckInterval)) {
       node.setState(STATE.DOWN);
       DaoUtils.getNodeDao().update(node);
       _logger.debug("Node is in not reachable state, Node:[{}]", node);
     }
   }
 }
  private ArrayList<MetricsChartDataKeyValuesJson> getAllAfter(
      AGGREGATION_TYPE aggregationType, int sensorId) {
    MetricsAggregationBase metricsAggregationBase = new MetricsAggregationBase();
    Sensor sensor =
        DaoUtils.getSensorDao()
            .get(sensorId); // Here sensorId means 'id'(db reference) not actual sensorId

    ArrayList<MetricsChartDataKeyValuesJson> finalData =
        new ArrayList<MetricsChartDataKeyValuesJson>();

    if (sensor.getMetricType() == null) {
      // Sensor pay load type not up to date
      _logger.debug("Payload type not updated in sensor.");
      return null;
    } else if (sensor.getMetricType() == MyMessages.PAYLOAD_TYPE.PL_DOUBLE.ordinal()) {
      _logger.debug("Payload type: {}", MyMessages.PAYLOAD_TYPE.PL_DOUBLE.toString());
      List<MetricsDoubleTypeDevice> metrics =
          metricsAggregationBase.getMetricsDoubleTypeAllAfter(aggregationType, sensor);
      if (metrics == null) {
        // throw new ApiError("No data available");
        return null;
      }

      MetricsChartDataKeyValuesJson minChartData = new MetricsChartDataKeyValuesJson("Minimum");
      MetricsChartDataKeyValuesJson avgChartData = new MetricsChartDataKeyValuesJson("Average");
      MetricsChartDataKeyValuesJson maxChartData = new MetricsChartDataKeyValuesJson("Maximum");

      for (MetricsDoubleTypeDevice metric : metrics) {
        minChartData.add(new Object[] {metric.getTimestamp(), metric.getMin()});
        avgChartData.add(new Object[] {metric.getTimestamp(), metric.getAvg()});
        maxChartData.add(new Object[] {metric.getTimestamp(), metric.getMax()});
      }

      finalData.add(minChartData);
      finalData.add(avgChartData);
      finalData.add(maxChartData);
    } else if (sensor.getMetricType() == MyMessages.PAYLOAD_TYPE.PL_BOOLEAN.ordinal()) {
      _logger.debug("Payload type: {}", MyMessages.PAYLOAD_TYPE.PL_BOOLEAN.toString());
      List<MetricsOnOffTypeDevice> metrics =
          metricsAggregationBase.getMetricsBooleanTypeAllAfter(aggregationType, sensor);
      if (metrics == null) {
        // throw new ApiError("No data available");
        return null;
      }

      String name = sensor.getName() != null ? sensor.getName() : "State";
      MetricsChartDataKeyValuesJson minChartData = new MetricsChartDataKeyValuesJson(name);

      for (MetricsOnOffTypeDevice metric : metrics) {
        minChartData.add(new Object[] {metric.getTimestamp(), metric.getState() ? 1 : 0});
      }

      finalData.add(minChartData);
    }

    return finalData;
  }
 @Override
 public Principal authenticate(String aUsername, String aPassword) throws SecurityException {
   _logger.debug("User:{},Password:{}", aUsername, aPassword);
   User user = DaoUtils.getUserDao().get(aUsername);
   if (user != null) {
     _logger.debug("User Found...User:{}", user);
     if (user.getPassword().equals(aPassword)) {
       user.setPassword(null);
       return user;
     }
   }
   throw new SecurityException("Access denied to user " + aUsername);
 }
 private void sendHearbeat() {
   List<Node> nodes = DaoUtils.getNodeDao().getAll();
   for (Node node : nodes) {
     switch (node.getGateway().getNetworkType()) {
       case MY_SENSORS:
         ObjectFactory.getIActionEngine(NETWORK_TYPE.MY_SENSORS).sendAliveStatusRequest(node);
         break;
       default:
         // TODO: not supported
         return;
     }
   }
 }
 public static boolean login(String aUsername, String aPassword) {
   if (aUsername == null || aPassword == null) {
     return false;
   }
   _logger.debug("User:{},Password:{}", aUsername, aPassword);
   User user = DaoUtils.getUserDao().get(aUsername);
   if (user != null) {
     _logger.debug("User Found...User:{}", user);
     if (user.getPassword().equals(aPassword)) {
       return true;
     }
   }
   return false;
 }
 @GET
 @Path("/sensorVariableTypesBySenRef/{sensorRefId}")
 public Response getSensorVariableTypesBySensorRefId(@PathParam("sensorRefId") int sensorRefId) {
   Sensor sensor = DaoUtils.getSensorDao().get(sensorRefId);
   if (sensor != null && sensor.getType() != null) {
     return RestUtils.getResponse(
         Status.OK,
         TypesUtils.getSensorVariableTypes(sensor.getType(), sensor.getVariableTypes()));
   }
   return RestUtils.getResponse(
       Status.BAD_REQUEST,
       new ApiError(
           "Requested Sensor["
               + sensor.getName()
               + "] type not available or Sensor not available"));
 }
 private void unloadLoadSunRiseSetJobs() {
   List<Timer> timers = DaoUtils.getTimerDao().getAllEnabled();
   // reload all jobs
   for (Timer timer : timers) {
     switch (TYPE.get(timer.getType())) {
       case BEFORE_SUNRISE:
       case AFTER_SUNRISE:
       case BEFORE_SUNSET:
       case AFTER_SUNSET:
         SchedulerUtils.reloadTimerJob(timer);
         break;
       default:
         break;
     }
   }
 }
  @GET
  @Path("/")
  public Response getAll(
      @QueryParam(Timer.KEY_NAME) List<String> name,
      @QueryParam(Timer.KEY_RESOURCE_TYPE) String resourceType,
      @QueryParam(Timer.KEY_RESOURCE_ID) Integer resourceId,
      @QueryParam(Timer.KEY_TIMER_TYPE) String timerType,
      @QueryParam(Timer.KEY_FREQUENCY) String frequency,
      @QueryParam(Timer.KEY_ENABLED) Boolean enabled,
      @QueryParam(Query.PAGE_LIMIT) Long pageLimit,
      @QueryParam(Query.PAGE) Long page,
      @QueryParam(Query.ORDER_BY) String orderBy,
      @QueryParam(Query.ORDER) String order) {
    HashMap<String, Object> filters = new HashMap<String, Object>();

    filters.put(Timer.KEY_NAME, name);
    filters.put(Timer.KEY_RESOURCE_TYPE, RESOURCE_TYPE.fromString(resourceType));
    filters.put(Timer.KEY_RESOURCE_ID, resourceId);
    filters.put(Timer.KEY_TIMER_TYPE, TIMER_TYPE.fromString(timerType));
    filters.put(Timer.KEY_FREQUENCY, FREQUENCY_TYPE.fromString(frequency));
    filters.put(Timer.KEY_ENABLED, enabled);

    // Add allowed resources filter if he is non-admin
    if (!AuthUtils.isSuperAdmin(securityContext)) {
      filters.put(
          AllowedResources.KEY_ALLOWED_RESOURCES,
          AuthUtils.getUser(securityContext).getAllowedResources());
    }

    QueryResponse queryResponse =
        DaoUtils.getTimerDao()
            .getAll(
                Query.builder()
                    .order(order != null ? order : Query.ORDER_ASC)
                    .orderBy(orderBy != null ? orderBy : Timer.KEY_ID)
                    .filters(filters)
                    .pageLimit(pageLimit != null ? pageLimit : Query.MAX_ITEMS_PER_PAGE)
                    .page(page != null ? page : 1l)
                    .build());
    return RestUtils.getResponse(Status.OK, queryResponse);
  }
 private String getFileName(SensorVariable sensorVariable, AGGREGATION_TYPE aggrType) {
   Sensor sensor = DaoUtils.getSensorDao().getById(sensorVariable.getSensor().getId());
   StringBuilder builder = new StringBuilder();
   builder
       .append(sensor.getNode().getName())
       .append("_")
       .append(sensor.getName())
       .append("_Nid-")
       .append(sensor.getNode().getEui())
       .append("_Sid-")
       .append(sensor.getSensorId())
       .append("_")
       .append(sensorVariable.getVariableType().getText());
   if (sensorVariable.getMetricType() == METRIC_TYPE.DOUBLE) {
     builder.append("_").append("SampleType_").append(aggrType);
   }
   builder
       .append("_")
       .append(new SimpleDateFormat("yyyy-MMM-dd_hh-mm-ss").format(new Date()))
       .append(".csv");
   return builder.toString().replaceAll(" ", "_");
 }
 @GET
 @Path("/{id}")
 public Response get(@PathParam("id") int id) {
   hasAccessTimer(id);
   return RestUtils.getResponse(Status.OK, DaoUtils.getTimerDao().getById(id));
 }
  private ArrayList<MetricsChartDataGroupNVD3> getMetricsDataJsonNVD3(
      List<Integer> variableIds,
      Integer sensorId,
      Long timestampFrom,
      Long timestampTo,
      Boolean withMinMax,
      String chartType) {

    // if chartType not null, call this
    if (chartType != null) {
      return getMetricsDataJsonNVD3WithChartType(
          variableIds, timestampFrom, timestampTo, chartType);
    }

    // Get sensor variables
    List<SensorVariable> sensorVariables = null;
    if (!variableIds.isEmpty()) {
      sensorVariables = DaoUtils.getSensorVariableDao().getAll(variableIds);
    } else {
      sensorVariables = DaoUtils.getSensorVariableDao().getAllBySensorId(sensorId);
    }
    // Return if no data available
    if (sensorVariables == null) {
      return new ArrayList<MetricsChartDataGroupNVD3>();
    }

    MetricsGraphSettings metricsGraphSettings =
        ObjectFactory.getAppProperties().getMetricsGraphSettings();
    ArrayList<MetricsChartDataGroupNVD3> finalData = new ArrayList<MetricsChartDataGroupNVD3>();

    for (SensorVariable sensorVariable : sensorVariables) {
      MetricsGraph metrics =
          metricsGraphSettings.getMetric(sensorVariable.getVariableType().getText());
      switch (sensorVariable.getMetricType()) {
        case DOUBLE:
          ArrayList<MetricsChartDataNVD3> preDoubleData = new ArrayList<MetricsChartDataNVD3>();

          MetricsDoubleTypeDevice metricQueryDouble =
              MetricsDoubleTypeDevice.builder()
                  .timestampFrom(timestampFrom)
                  .timestampTo(timestampTo)
                  .sensorVariable(sensorVariable)
                  .build();
          List<MetricsDoubleTypeDevice> doubleMetrics =
              DaoUtils.getMetricsDoubleTypeDeviceDao().getAll(metricQueryDouble);
          ArrayList<Object> avgMetricDoubleValues = new ArrayList<Object>();
          ArrayList<Object> minMetricDoubleValues = new ArrayList<Object>();
          ArrayList<Object> maxMetricDoubleValues = new ArrayList<Object>();
          for (MetricsDoubleTypeDevice metric : doubleMetrics) {
            avgMetricDoubleValues.add(new Object[] {metric.getTimestamp(), metric.getAvg()});
            if (withMinMax) {
              minMetricDoubleValues.add(new Object[] {metric.getTimestamp(), metric.getMin()});
              maxMetricDoubleValues.add(new Object[] {metric.getTimestamp(), metric.getMax()});
            }
          }
          preDoubleData.add(
              MetricsChartDataNVD3.builder()
                  .key(ObjectFactory.getMcLocale().getString(MC_LOCALE.AVERAGE))
                  .values(avgMetricDoubleValues)
                  .color(metrics.getColor())
                  .type(metrics.getSubType())
                  .build()
                  .updateSubType(metrics.getType()));
          if (withMinMax) {
            preDoubleData.add(
                MetricsChartDataNVD3.builder()
                    .key(ObjectFactory.getMcLocale().getString(MC_LOCALE.MINUMUM))
                    .values(minMetricDoubleValues)
                    .color(COLOR_MINIMUM)
                    .type(metrics.getSubType())
                    .build()
                    .updateSubType(metrics.getType()));
            preDoubleData.add(
                MetricsChartDataNVD3.builder()
                    .key(ObjectFactory.getMcLocale().getString(MC_LOCALE.MAXIMUM))
                    .values(maxMetricDoubleValues)
                    .color(COLOR_MAXIMUM)
                    .type(metrics.getSubType())
                    .build()
                    .updateSubType(metrics.getType()));
          }
          finalData.add(
              MetricsChartDataGroupNVD3.builder()
                  .metricsChartDataNVD3(preDoubleData)
                  .id(sensorVariable.getId())
                  .unit(sensorVariable.getUnit())
                  .timeFormat(getTimeFormat(timestampFrom))
                  .variableType(
                      ObjectFactory.getMcLocale()
                          .getString(sensorVariable.getVariableType().name()))
                  .dataType(sensorVariable.getMetricType().getText())
                  .resourceName(
                      new ResourceModel(RESOURCE_TYPE.SENSOR_VARIABLE, sensorVariable)
                          .getResourceLessDetails())
                  .chartType(metrics.getType())
                  .chartInterpolate(metrics.getInterpolate())
                  .build());

          break;
        case BINARY:
          ArrayList<MetricsChartDataNVD3> preBinaryData = new ArrayList<MetricsChartDataNVD3>();
          MetricsBinaryTypeDevice metricQueryBinary =
              MetricsBinaryTypeDevice.builder()
                  .timestampFrom(timestampFrom)
                  .timestampTo(timestampTo)
                  .sensorVariable(sensorVariable)
                  .build();
          List<MetricsBinaryTypeDevice> binaryMetrics =
              DaoUtils.getMetricsBinaryTypeDeviceDao().getAll(metricQueryBinary);
          ArrayList<Object> metricBinaryValues = new ArrayList<Object>();
          for (MetricsBinaryTypeDevice metric : binaryMetrics) {
            metricBinaryValues.add(new Object[] {metric.getTimestamp(), metric.getState() ? 1 : 0});
          }
          preBinaryData.add(
              MetricsChartDataNVD3.builder()
                  .key(sensorVariable.getVariableType().getText())
                  .values(metricBinaryValues)
                  .color(metrics.getColor())
                  .type(metrics.getSubType())
                  .build()
                  .updateSubType(metrics.getType()));
          finalData.add(
              MetricsChartDataGroupNVD3.builder()
                  .metricsChartDataNVD3(preBinaryData)
                  .id(sensorVariable.getId())
                  .unit(sensorVariable.getUnit())
                  .timeFormat(getTimeFormat(timestampFrom))
                  .variableType(
                      ObjectFactory.getMcLocale()
                          .getString(sensorVariable.getVariableType().name()))
                  .dataType(sensorVariable.getMetricType().getText())
                  .resourceName(
                      new ResourceModel(RESOURCE_TYPE.SENSOR_VARIABLE, sensorVariable)
                          .getResourceLessDetails())
                  .chartType(metrics.getType())
                  .chartInterpolate(metrics.getInterpolate())
                  .build());
          break;
        default:
          // no need to do anything here
          break;
      }
    }

    return finalData;
  }
  private ArrayList<MetricsChartDataGroupNVD3> getMetricsDataJsonNVD3WithChartType(
      List<Integer> variableIds, Long timestampFrom, Long timestampTo, String chartType) {

    // Get sensor variables
    List<SensorVariable> sensorVariables = null;
    if (!variableIds.isEmpty()) {
      sensorVariables = DaoUtils.getSensorVariableDao().getAll(variableIds);
    }

    // Return if no data available
    if (sensorVariables == null) {
      return new ArrayList<MetricsChartDataGroupNVD3>();
    }

    MetricsGraphSettings metricsGraphSettings =
        ObjectFactory.getAppProperties().getMetricsGraphSettings();
    ArrayList<MetricsChartDataGroupNVD3> finalData = new ArrayList<MetricsChartDataGroupNVD3>();

    SensorVariable yaxis1Variable = null;
    boolean initialLoadDone = false;
    String chartTypeInternal = null;

    ArrayList<MetricsChartDataNVD3> metricDataValues = new ArrayList<MetricsChartDataNVD3>();

    String unit = null;
    String unit2 = null;
    String chartInterpolate = null;
    boolean isMultiChart = false;

    for (SensorVariable sensorVariable : sensorVariables) {
      MetricsGraph metrics =
          metricsGraphSettings.getMetric(sensorVariable.getVariableType().getText());
      // Load initial settings
      if (!initialLoadDone) {
        if (CHART_TYPE.MULTI_CHART == CHART_TYPE.fromString(chartType)) {
          isMultiChart = true;
          yaxis1Variable = sensorVariable;
          chartTypeInternal = chartType;
        } else if (CHART_TYPE.LINE_CHART == CHART_TYPE.fromString(chartType)) {
          chartTypeInternal = chartType;
          chartInterpolate = metrics.getInterpolate();
        }
        initialLoadDone = true;
      }

      Integer yAxis = null;
      if (yaxis1Variable != null) {
        if (yaxis1Variable.getVariableType() == sensorVariable.getVariableType()) {
          yAxis = 1;
          unit = sensorVariable.getUnit();
        } else {
          yAxis = 2;
          unit2 = sensorVariable.getUnit();
        }
      } else {
        unit = sensorVariable.getUnit();
      }

      if (chartTypeInternal == null) {
        chartTypeInternal = metrics.getType();
      }

      String seriesName = null;
      if (isMultiChart) {
        seriesName =
            sensorVariable.getSensor().getName() + "-" + sensorVariable.getVariableType().getText();
      } else {
        seriesName = sensorVariable.getSensor().getName();
      }
      switch (sensorVariable.getMetricType()) {
        case DOUBLE:
          MetricsDoubleTypeDevice metricQueryDouble =
              MetricsDoubleTypeDevice.builder()
                  .timestampFrom(timestampFrom)
                  .timestampTo(timestampTo)
                  .sensorVariable(sensorVariable)
                  .build();
          List<MetricsDoubleTypeDevice> doubleMetrics =
              DaoUtils.getMetricsDoubleTypeDeviceDao().getAll(metricQueryDouble);
          ArrayList<Object> avgMetricDoubleValues = new ArrayList<Object>();
          for (MetricsDoubleTypeDevice metric : doubleMetrics) {
            if (isMultiChart) {
              avgMetricDoubleValues.add(
                  MetricsChartDataXY.builder().x(metric.getTimestamp()).y(metric.getAvg()).build());
            } else {
              avgMetricDoubleValues.add(new Object[] {metric.getTimestamp(), metric.getAvg()});
            }
          }
          if (!doubleMetrics.isEmpty()) {
            metricDataValues.add(
                MetricsChartDataNVD3.builder()
                    .key(seriesName)
                    .values(avgMetricDoubleValues)
                    .type(metrics.getSubType())
                    // .interpolate(metrics.getInterpolate())
                    .yAxis(yAxis)
                    .build()
                    .updateSubType(chartTypeInternal));
          }

          break;
        case BINARY:
          MetricsBinaryTypeDevice metricQueryBinary =
              MetricsBinaryTypeDevice.builder()
                  .timestampFrom(timestampFrom)
                  .timestampTo(timestampTo)
                  .sensorVariable(sensorVariable)
                  .build();
          List<MetricsBinaryTypeDevice> binaryMetrics =
              DaoUtils.getMetricsBinaryTypeDeviceDao().getAll(metricQueryBinary);
          ArrayList<Object> metricBinaryValues = new ArrayList<Object>();
          for (MetricsBinaryTypeDevice metric : binaryMetrics) {
            if (isMultiChart) {
              metricBinaryValues.add(
                  MetricsChartDataXY.builder()
                      .x(metric.getTimestamp())
                      .y(metric.getState() ? 1 : 0)
                      .build());
            } else {
              metricBinaryValues.add(
                  new Object[] {metric.getTimestamp(), metric.getState() ? 1 : 0});
            }
          }
          if (!binaryMetrics.isEmpty()) {
            metricDataValues.add(
                MetricsChartDataNVD3.builder()
                    .key(seriesName)
                    .values(metricBinaryValues)
                    .type(metrics.getSubType())
                    // .interpolate(metrics.getInterpolate())
                    .yAxis(yAxis)
                    .id(sensorVariable.getId())
                    .resourceName(
                        new ResourceModel(RESOURCE_TYPE.SENSOR_VARIABLE, sensorVariable)
                            .getResourceLessDetails())
                    .build()
                    .updateSubType(chartTypeInternal));
          }

          break;
        default:
          // no need to do anything here
          break;
      }
    }

    finalData.add(
        MetricsChartDataGroupNVD3.builder()
            .metricsChartDataNVD3(metricDataValues)
            .unit(unit)
            .unit2(unit2)
            .timeFormat(getTimeFormat(timestampFrom))
            .chartType(chartType)
            .chartInterpolate(chartInterpolate)
            .build());

    return finalData;
  }
  private MetricsChartDataGroupNVD3 getMetricsBatteryJsonNVD3(
      Integer nodeId, Long timestampFrom, Long timestampTo, Boolean withMinMax) {
    ArrayList<MetricsChartDataNVD3> preDoubleData = new ArrayList<MetricsChartDataNVD3>();

    MetricsBatteryUsage metricQueryBattery =
        MetricsBatteryUsage.builder()
            .timestampFrom(timestampFrom)
            .timestampTo(timestampTo)
            .node(Node.builder().id(nodeId).build())
            .build();
    List<MetricsBatteryUsage> batteryMetrics =
        DaoUtils.getMetricsBatteryUsageDao().getAll(metricQueryBattery);
    ArrayList<Object> avgMetricValues = new ArrayList<Object>();
    ArrayList<Object> minMetricValues = new ArrayList<Object>();
    ArrayList<Object> maxMetricValues = new ArrayList<Object>();
    for (MetricsBatteryUsage metric : batteryMetrics) {
      avgMetricValues.add(new Object[] {metric.getTimestamp(), metric.getAvg()});
      if (withMinMax) {
        minMetricValues.add(new Object[] {metric.getTimestamp(), metric.getMin()});
        maxMetricValues.add(new Object[] {metric.getTimestamp(), metric.getMax()});
      }
    }
    MetricsGraph metricBattery =
        ObjectFactory.getAppProperties().getMetricsGraphSettings().getBattery();
    preDoubleData.add(
        MetricsChartDataNVD3.builder()
            .key(ObjectFactory.getMcLocale().getString(MC_LOCALE.AVERAGE))
            .values(avgMetricValues)
            .color(metricBattery.getColor())
            .type(metricBattery.getSubType())
            .build()
            .updateSubType(metricBattery.getType()));
    if (withMinMax) {
      preDoubleData.add(
          MetricsChartDataNVD3.builder()
              .key(ObjectFactory.getMcLocale().getString(MC_LOCALE.MINUMUM))
              .values(minMetricValues)
              .color(COLOR_MINIMUM)
              .type(metricBattery.getSubType())
              .build()
              .updateSubType(metricBattery.getType()));
      preDoubleData.add(
          MetricsChartDataNVD3.builder()
              .key(ObjectFactory.getMcLocale().getString(MC_LOCALE.MAXIMUM))
              .values(maxMetricValues)
              .color(COLOR_MAXIMUM)
              .type(metricBattery.getSubType())
              .build()
              .updateSubType(metricBattery.getType()));
    }

    return MetricsChartDataGroupNVD3.builder()
        .metricsChartDataNVD3(preDoubleData)
        .unit("%")
        .timeFormat(getTimeFormat(timestampFrom))
        .id(nodeId)
        .resourceName(new ResourceModel(RESOURCE_TYPE.NODE, nodeId).getResourceLessDetails())
        .chartType(metricBattery.getType())
        .chartInterpolate(metricBattery.getInterpolate())
        .build();
  }
 @GET
 @Path("/sensorData/{id}")
 public Response getSensorDetails(@PathParam("id") int id) {
   Sensor sensor = DaoUtils.getSensorDao().get(id);
   return RestUtils.getResponse(Status.OK, sensor);
 }
 public MetricsCsvDownload getMetricsCSV(int sensorValueId, int aggregationTypeId) {
   SensorVariable sensorVariable = DaoUtils.getSensorVariableDao().get(sensorValueId);
   AGGREGATION_TYPE aggrType = AGGREGATION_TYPE.get(aggregationTypeId);
   return new MetricsCsvDownload(
       getFileName(sensorVariable, aggrType), getData(sensorVariable, aggrType));
 }