Code review for Thermostat

This commit is contained in:
Claudio Maggioni 2020-04-15 17:55:04 +02:00
parent 0e924c088b
commit 646672e3db
8 changed files with 68 additions and 50 deletions

View file

@ -29,8 +29,10 @@ connection.onopen = function(evt) {
connection.onmessage = function(evt) { connection.onmessage = function(evt) {
console.log("***ONMESSAGE", evt); console.log("***ONMESSAGE", evt);
let data = JSON.parse(evt.data); let data = JSON.parse(evt.data);
let a = document.getElementById("giovanni");
if (a) a.remove();
malusa.innerHTML += "<p><pre>" + JSON.stringify(JSON.parse(evt.data), null, 2) + "</pre></p>"; malusa.innerHTML += "<pre id=\"giovanni\">" + JSON.stringify(JSON.parse(evt.data), null, 2) + "</pre>";
}; };
connection.onerror = function(evt) { connection.onerror = function(evt) {

View file

@ -68,6 +68,7 @@ public class SpringFoxConfig {
.or(PathSelectors.regex("/room.*")::apply) .or(PathSelectors.regex("/room.*")::apply)
.or(PathSelectors.regex("/device.*")::apply) .or(PathSelectors.regex("/device.*")::apply)
.or(PathSelectors.regex("/buttonDimmer.*")::apply) .or(PathSelectors.regex("/buttonDimmer.*")::apply)
.or(PathSelectors.regex("/thermostat.*")::apply)
.or(PathSelectors.regex("/dimmableLight.*")::apply) .or(PathSelectors.regex("/dimmableLight.*")::apply)
.or(PathSelectors.regex("/knobDimmer.*")::apply) .or(PathSelectors.regex("/knobDimmer.*")::apply)
.or(PathSelectors.regex("/regularLight.*")::apply) .or(PathSelectors.regex("/regularLight.*")::apply)

View file

@ -1,6 +1,5 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.ThermostatSaveRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.ThermostatSaveRequest;
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
@ -40,12 +39,13 @@ public class ThermostatController {
newT.setId(t.getId()); newT.setId(t.getId());
newT.setName(t.getName()); newT.setName(t.getName());
newT.setRoomId(t.getRoomId()); newT.setRoomId(t.getRoomId());
newT.setUseExternalSensors(t.isUseExternalSensors());
if (newT.getState() == Thermostat.ThermostatState.OFF if (t.isTurnOn()) {
&& t.getState() != Thermostat.ThermostatState.OFF) { newT.setState(Thermostat.ThermostatState.IDLE);
thermostatService.computeState(newT); thermostatService.computeState(newT);
} else { } else {
newT.setState(t.getState()); newT.setState(Thermostat.ThermostatState.OFF);
} }
newT = thermostatRepository.save(newT); newT = thermostatRepository.save(newT);

View file

@ -1,19 +1,10 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.dto; package ch.usi.inf.sa4.sanmarinoes.smarthut.dto;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Sensor;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Thermostat;
import java.math.BigDecimal; import java.math.BigDecimal;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
public class ThermostatSaveRequest { public class ThermostatSaveRequest {
public enum ThermostatState {
OFF,
IDLE,
COOLING,
HEATING
}
/** Device identifier */ /** Device identifier */
private long id; private long id;
@ -32,14 +23,14 @@ public class ThermostatSaveRequest {
@NotNull private boolean useExternalSensors; @NotNull private boolean useExternalSensors;
/** State of this thermostat */ /** State of this thermostat */
@NotNull private Thermostat.ThermostatState state; @NotNull private boolean turnOn;
public void setState(Thermostat.ThermostatState state) { public boolean isTurnOn() {
this.state = state; return turnOn;
} }
public Thermostat.ThermostatState getState() { public void setTurnOn(boolean turnOn) {
return this.state; this.turnOn = turnOn;
} }
public boolean isUseExternalSensors() { public boolean isUseExternalSensors() {

View file

@ -27,14 +27,15 @@ public class Thermostat extends OutputDevice {
/** The temperature detected by the embedded sensor */ /** The temperature detected by the embedded sensor */
@Column(nullable = false, precision = 4, scale = 1) @Column(nullable = false, precision = 4, scale = 1)
private BigDecimal internalSensorTemperature; private BigDecimal internalSensorTemperature =
Sensor.TYPICAL_VALUES.get(Sensor.SensorType.TEMPERATURE);
/** State of this thermostat */ /** State of this thermostat */
@Column @NotNull private ThermostatState state; @Column @NotNull private ThermostatState state;
@Transient private BigDecimal measuredTemperature; @Transient private BigDecimal measuredTemperature;
@Column boolean useExternalSensors = false; @Column private boolean useExternalSensors = false;
/** Creates a thermostat with a temperature sensor and its initial OFF state */ /** Creates a thermostat with a temperature sensor and its initial OFF state */
public Thermostat() { public Thermostat() {
@ -74,30 +75,11 @@ public class Thermostat extends OutputDevice {
this.targetTemperature = targetTemperature; this.targetTemperature = targetTemperature;
} }
/* public void setInternalSensorTemperature(BigDecimal internalSensorTemperature) {
* Sets the target temperature to be reached. Changes the thermostat state accordingly and waits this.internalSensorTemperature = internalSensorTemperature;
* until such temperature is reached by the embedded sensor to become idle again.
*
* @param targetTemperature - the temperature to be reached by the thermostat
*/
/*public void setTargetTemperature(BigDecimal targetTemperature) {
if (this.state == ThermostatState.OFF) {
this.setState(ThermostatState.IDLE);
} }
this.targetTemperature = targetTemperature; public void setUseExternalSensors(boolean useExternalSensors) {
BigDecimal actualTemperature = this.temperatureSensor.getValue(); this.useExternalSensors = useExternalSensors;
if (actualTemperature.compareTo(targetTemperature) == -1) {
this.setState(ThermostatState.HEATING);
} else {
this.setState(ThermostatState.COOLING);
} }
while (!(this.temperatureSensor.getValue().equals(this.targetTemperature))) {
// Do nothing, wait for the target temperature to be reached
}
this.setState(ThermostatState.IDLE);
}*/
} }

View file

@ -1,10 +1,23 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.models; package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
public interface ThermostatRepository extends DeviceRepository<Thermostat> { public interface ThermostatRepository extends DeviceRepository<Thermostat> {
/**
* Finds all devices belonging to a user
*
* @param username the User's username
* @return all devices of that user
*/
@Transactional
@Query("SELECT t FROM Thermostat t JOIN t.room r JOIN r.user u WHERE u.username = ?1")
List<Thermostat> findAllByUsername(String username);
/** /**
* Computes the average temperature of all temperature sensors in the room * Computes the average temperature of all temperature sensors in the room
* *

View file

@ -1,11 +1,10 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.scheduled; package ch.usi.inf.sa4.sanmarinoes.smarthut.scheduled;
import ch.usi.inf.sa4.sanmarinoes.smarthut.controller.MotionSensorController; import ch.usi.inf.sa4.sanmarinoes.smarthut.controller.MotionSensorController;
import ch.usi.inf.sa4.sanmarinoes.smarthut.controller.SensorController;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
import ch.usi.inf.sa4.sanmarinoes.smarthut.service.SensorService; import ch.usi.inf.sa4.sanmarinoes.smarthut.service.SensorService;
import ch.usi.inf.sa4.sanmarinoes.smarthut.service.ThermostatService;
import ch.usi.inf.sa4.sanmarinoes.smarthut.socket.SensorSocketEndpoint; import ch.usi.inf.sa4.sanmarinoes.smarthut.socket.SensorSocketEndpoint;
import java.math.BigDecimal;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -29,16 +28,24 @@ public class UpdateTasks {
@Autowired private SensorService sensorService; @Autowired private SensorService sensorService;
@Autowired private ThermostatService thermostatService;
@Autowired private MotionSensorController motionSensorController; @Autowired private MotionSensorController motionSensorController;
@Autowired private SensorSocketEndpoint sensorSocketEndpoint; @Autowired private SensorSocketEndpoint sensorSocketEndpoint;
/** Generates fake sensor updates every two seconds with a +/- 1.25% error */ /** Generates fake sensor updates every two seconds with a +/- 2.5% error */
@Scheduled(fixedRate = 2000) @Scheduled(fixedRate = 2000)
public void sensorFakeUpdate() { public void sensorFakeUpdate() {
sensorService.sensorFakeUpdate(); sensorService.sensorFakeUpdate();
} }
/** Generates fake sensor updates every two seconds with a +/- 2.5% error */
@Scheduled(fixedRate = 2000)
public void thermostatInteralSensorFakeUpdate() {
thermostatService.fakeUpdateAll();
}
/** /**
* Generate fake motion detections in all motion detectors every 20 seconds for 2 seconds at * Generate fake motion detections in all motion detectors every 20 seconds for 2 seconds at
* most * most
@ -64,7 +71,10 @@ public class UpdateTasks {
public void smartPlugConsumptionFakeUpdate() { public void smartPlugConsumptionFakeUpdate() {
smartPlugRepository.updateTotalConsumption(SmartPlug.AVERAGE_CONSUMPTION_KW); smartPlugRepository.updateTotalConsumption(SmartPlug.AVERAGE_CONSUMPTION_KW);
final Collection<SmartPlug> c = smartPlugRepository.findByOn(true); final Collection<SmartPlug> c = smartPlugRepository.findByOn(true);
c.forEach(s -> sensorSocketEndpoint.queueDeviceUpdate(s, sensorRepository.findUser(s.getId()))); c.forEach(
s ->
sensorSocketEndpoint.queueDeviceUpdate(
s, sensorRepository.findUser(s.getId())));
} }
/** Sends device updates through sensor socket in batch every one second */ /** Sends device updates through sensor socket in batch every one second */

View file

@ -1,5 +1,6 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.service; package ch.usi.inf.sa4.sanmarinoes.smarthut.service;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Sensor;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Thermostat; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Thermostat;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ThermostatRepository; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ThermostatRepository;
import ch.usi.inf.sa4.sanmarinoes.smarthut.socket.SensorSocketEndpoint; import ch.usi.inf.sa4.sanmarinoes.smarthut.socket.SensorSocketEndpoint;
@ -17,6 +18,24 @@ public class ThermostatService {
@Autowired private ThermostatRepository thermostatRepository; @Autowired private ThermostatRepository thermostatRepository;
private void randomJitter(Thermostat thermostat) {
updateValueForThermostat(
thermostat,
Sensor.TYPICAL_VALUES
.get(Sensor.SensorType.TEMPERATURE)
.multiply(BigDecimal.valueOf(0.975 + Math.random() / 20)));
}
private void updateValueForThermostat(Thermostat thermostat, BigDecimal value) {
thermostat.setInternalSensorTemperature(value);
thermostatRepository.save(thermostat);
}
public void fakeUpdateAll() {
thermostatRepository.findAll().forEach(this::randomJitter);
updateStates();
}
public List<Thermostat> findAll(String username) { public List<Thermostat> findAll(String username) {
Iterable<Thermostat> all = thermostatRepository.findAllByUsername(username); Iterable<Thermostat> all = thermostatRepository.findAllByUsername(username);
all.forEach(this::populateMeasuredTemperature); all.forEach(this::populateMeasuredTemperature);