package org.eclipse.leshan.client.demo;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.eclipse.leshan.client.resource.BaseInstanceEnabler;
import org.eclipse.leshan.core.response.ExecuteResponse;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.util.NamedThreadFactory;
public class RandomTemperatureSensor extends BaseInstanceEnabler {
private static final String UNIT_CELSIUS = "cel";
private static final int SENSOR_VALUE = 5700;
private static final int UNITS = 5701;
private static final int MAX_MEASURED_VALUE = 5602;
private static final int MIN_MEASURED_VALUE = 5601;
private static final int RESET_MIN_MAX_MEASURED_VALUES = 5605;
private final ScheduledExecutorService scheduler;
private final Random rng = new Random();
private double currentTemp = 20d;
private double minMeasuredValue = currentTemp;
private double maxMeasuredValue = currentTemp;
public RandomTemperatureSensor() {
this.scheduler = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("Temperature Sensor"));
scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
adjustTemperature();
}
}, 2, 2, TimeUnit.SECONDS);
}
@Override
public synchronized ReadResponse read(int resourceId) {
switch (resourceId) {
case MIN_MEASURED_VALUE:
return ReadResponse.success(resourceId, getTwoDigitValue(minMeasuredValue));
case MAX_MEASURED_VALUE:
return ReadResponse.success(resourceId, getTwoDigitValue(maxMeasuredValue));
case SENSOR_VALUE:
return ReadResponse.success(resourceId, getTwoDigitValue(currentTemp));
case UNITS:
return ReadResponse.success(resourceId, UNIT_CELSIUS);
default:
return super.read(resourceId);
}
}
@Override
public synchronized ExecuteResponse execute(int resourceId, String params) {
switch (resourceId) {
case RESET_MIN_MAX_MEASURED_VALUES:
resetMinMaxMeasuredValues();
return ExecuteResponse.success();
default:
return super.execute(resourceId, params);
}
}
private double getTwoDigitValue(double value) {
BigDecimal toBeTruncated = BigDecimal.valueOf(value);
return toBeTruncated.setScale(2, RoundingMode.HALF_UP).doubleValue();
}
private synchronized void adjustTemperature() {
float delta = (rng.nextInt(20) - 10) / 10f;
currentTemp += delta;
Integer changedResource = adjustMinMaxMeasuredValue(currentTemp);
if (changedResource != null) {
fireResourcesChange(SENSOR_VALUE, changedResource);
} else {
fireResourcesChange(SENSOR_VALUE);
}
}
private Integer adjustMinMaxMeasuredValue(double newTemperature) {
if (newTemperature > maxMeasuredValue) {
maxMeasuredValue = newTemperature;
return MAX_MEASURED_VALUE;
} else if (newTemperature < minMeasuredValue) {
minMeasuredValue = newTemperature;
return MIN_MEASURED_VALUE;
} else {
return null;
}
}
private void resetMinMaxMeasuredValues() {
minMeasuredValue = currentTemp;
maxMeasuredValue = currentTemp;
}
}