Merge branch 'fix4867594w867593428574ew' into 'dev'
fix See merge request sa4-2020/the-sanmarinoes/backend!96
This commit is contained in:
commit
3df6812b1f
12 changed files with 197 additions and 22 deletions
|
@ -1,5 +1,6 @@
|
||||||
package ch.usi.inf.sa4.sanmarinoes.smarthut.config;
|
package ch.usi.inf.sa4.sanmarinoes.smarthut.config;
|
||||||
|
|
||||||
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.AutomationFastUpdateRequest;
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableState;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableState;
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.State;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.State;
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.SwitchableState;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.SwitchableState;
|
||||||
|
@ -30,7 +31,18 @@ public class GsonConfig {
|
||||||
RuntimeTypeAdapterFactory.of(State.class, "kind")
|
RuntimeTypeAdapterFactory.of(State.class, "kind")
|
||||||
.registerSubtype(SwitchableState.class, "switchableState")
|
.registerSubtype(SwitchableState.class, "switchableState")
|
||||||
.registerSubtype(DimmableState.class, "dimmableState");
|
.registerSubtype(DimmableState.class, "dimmableState");
|
||||||
|
RuntimeTypeAdapterFactory<AutomationFastUpdateRequest.TriggerDTO>
|
||||||
|
runtimeTypeAdapterFactoryII =
|
||||||
|
RuntimeTypeAdapterFactory.of(
|
||||||
|
AutomationFastUpdateRequest.TriggerDTO.class, "kind")
|
||||||
|
.registerSubtype(
|
||||||
|
AutomationFastUpdateRequest.BooleanTriggerDTO.class,
|
||||||
|
"booleanTrigger")
|
||||||
|
.registerSubtype(
|
||||||
|
AutomationFastUpdateRequest.RangeTriggerDTO.class,
|
||||||
|
"rangeTrigger");
|
||||||
builder.registerTypeAdapterFactory(runtimeTypeAdapterFactory);
|
builder.registerTypeAdapterFactory(runtimeTypeAdapterFactory);
|
||||||
|
builder.registerTypeAdapterFactory(runtimeTypeAdapterFactoryII);
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ public class SpringFoxConfig {
|
||||||
.or(PathSelectors.regex("/motionSensor.*")::apply)
|
.or(PathSelectors.regex("/motionSensor.*")::apply)
|
||||||
.or(PathSelectors.regex("/curtains.*")::apply)
|
.or(PathSelectors.regex("/curtains.*")::apply)
|
||||||
.or(PathSelectors.regex("/user.*")::apply)
|
.or(PathSelectors.regex("/user.*")::apply)
|
||||||
|
.or(PathSelectors.regex("/automation.*")::apply)
|
||||||
.or(PathSelectors.regex("/auth/profile.*")::apply);
|
.or(PathSelectors.regex("/auth/profile.*")::apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
|
package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
|
||||||
|
|
||||||
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.AutomationFastUpdateRequest;
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.AutomationSaveRequest;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.AutomationSaveRequest;
|
||||||
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.Automation;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.AutomationRepository;
|
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ScenePriorityRepository;
|
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.SceneRepository;
|
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.UserRepository;
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
@ -28,8 +26,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||||
public class AutomationController {
|
public class AutomationController {
|
||||||
|
|
||||||
@Autowired private AutomationRepository automationRepository;
|
@Autowired private AutomationRepository automationRepository;
|
||||||
@Autowired private SceneRepository sceneRepository;
|
@Autowired private ScenePriorityRepository sceneRepository;
|
||||||
@Autowired private ScenePriorityRepository scenePriorityRepository;
|
@Autowired private TriggerRepository<Trigger<?>> triggerRepository;
|
||||||
@Autowired private UserRepository userService;
|
@Autowired private UserRepository userService;
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
|
@ -73,6 +71,46 @@ public class AutomationController {
|
||||||
principal);
|
principal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PutMapping("/fast")
|
||||||
|
public Automation fastUpdate(
|
||||||
|
@Valid @RequestBody AutomationFastUpdateRequest req, Principal principal)
|
||||||
|
throws NotFoundException {
|
||||||
|
final Automation a =
|
||||||
|
automationRepository
|
||||||
|
.findByIdAndUserId(
|
||||||
|
req.getId(),
|
||||||
|
userService.findByUsername(principal.getName()).getId())
|
||||||
|
.orElseThrow(NotFoundException::new);
|
||||||
|
|
||||||
|
a.setName(req.getName());
|
||||||
|
automationRepository.save(a);
|
||||||
|
|
||||||
|
triggerRepository.deleteAllByAutomationId(a.getId());
|
||||||
|
sceneRepository.deleteAllByAutomationId(a.getId());
|
||||||
|
|
||||||
|
Iterable<Trigger<?>> tt =
|
||||||
|
triggerRepository.saveAll(
|
||||||
|
req.getTriggers()
|
||||||
|
.stream()
|
||||||
|
.map(AutomationFastUpdateRequest.TriggerDTO::toModel)
|
||||||
|
.map(t -> t.setAutomationId(a.getId()))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
Iterable<ScenePriority> ss =
|
||||||
|
sceneRepository.saveAll(
|
||||||
|
req.getScenes()
|
||||||
|
.stream()
|
||||||
|
.map(AutomationFastUpdateRequest.ScenePriorityDTO::toModel)
|
||||||
|
.map(t -> t.setAutomationId(a.getId()))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
|
a.getScenes().clear();
|
||||||
|
a.getTriggers().clear();
|
||||||
|
ss.forEach(t -> a.getScenes().add(t));
|
||||||
|
tt.forEach(t -> a.getTriggers().add(t));
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
@DeleteMapping("/{id}")
|
@DeleteMapping("/{id}")
|
||||||
public void delete(@PathVariable long id) {
|
public void delete(@PathVariable long id) {
|
||||||
automationRepository.deleteById(id);
|
automationRepository.deleteById(id);
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
package ch.usi.inf.sa4.sanmarinoes.smarthut.dto;
|
||||||
|
|
||||||
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.BooleanTrigger;
|
||||||
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.RangeTrigger;
|
||||||
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ScenePriority;
|
||||||
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Trigger;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
public class AutomationFastUpdateRequest {
|
||||||
|
public abstract static class TriggerDTO {
|
||||||
|
@NotNull public long deviceId;
|
||||||
|
|
||||||
|
public abstract Trigger<?> toModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BooleanTriggerDTO extends TriggerDTO {
|
||||||
|
@NotNull public boolean on;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Trigger<?> toModel() {
|
||||||
|
BooleanTrigger<?> t = new BooleanTrigger<>();
|
||||||
|
t.setDeviceId(this.deviceId);
|
||||||
|
t.setOn(this.on);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RangeTriggerDTO extends TriggerDTO {
|
||||||
|
@NotNull RangeTrigger.Operator operator;
|
||||||
|
@NotNull double range;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Trigger<?> toModel() {
|
||||||
|
RangeTrigger<?> t = new RangeTrigger<>();
|
||||||
|
t.setDeviceId(this.deviceId);
|
||||||
|
t.setOperator(this.operator);
|
||||||
|
t.setRange(this.range);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ScenePriorityDTO {
|
||||||
|
@NotNull public long sceneId;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Min(0)
|
||||||
|
public Integer priority;
|
||||||
|
|
||||||
|
public ScenePriority toModel() {
|
||||||
|
ScenePriority s = new ScenePriority();
|
||||||
|
s.setSceneId(sceneId);
|
||||||
|
s.setPriority(priority);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull private List<ScenePriorityDTO> scenes;
|
||||||
|
@NotNull private List<TriggerDTO> triggers;
|
||||||
|
@NotNull private long id;
|
||||||
|
|
||||||
|
@NotNull @NotEmpty private String name;
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ScenePriorityDTO> getScenes() {
|
||||||
|
return scenes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScenes(List<ScenePriorityDTO> scenes) {
|
||||||
|
this.scenes = scenes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TriggerDTO> getTriggers() {
|
||||||
|
return triggers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTriggers(List<TriggerDTO> triggers) {
|
||||||
|
this.triggers = triggers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,11 +28,9 @@ public class Automation {
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "automation", orphanRemoval = true)
|
@OneToMany(mappedBy = "automation", orphanRemoval = true)
|
||||||
@GsonExclude
|
|
||||||
private Set<Trigger<?>> triggers = new HashSet<>();
|
private Set<Trigger<?>> triggers = new HashSet<>();
|
||||||
|
|
||||||
@OneToMany(mappedBy = "automation", cascade = CascadeType.REMOVE)
|
@OneToMany(mappedBy = "automation", cascade = CascadeType.REMOVE)
|
||||||
@GsonExclude
|
|
||||||
private Set<ScenePriority> scenes = new HashSet<>();
|
private Set<ScenePriority> scenes = new HashSet<>();
|
||||||
|
|
||||||
@NotNull @NotEmpty private String name;
|
@NotNull @NotEmpty private String name;
|
||||||
|
@ -53,6 +51,10 @@ public class Automation {
|
||||||
return scenes;
|
return scenes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Trigger<?>> getTriggers() {
|
||||||
|
return triggers;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.springframework.data.jpa.repository.EntityGraph;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
public interface AutomationRepository extends CrudRepository<Automation, Long> {
|
public interface AutomationRepository extends CrudRepository<Automation, Long> {
|
||||||
|
@EntityGraph(attributePaths = {"scenes", "triggers"})
|
||||||
List<Automation> findAllByUserId(@Param("userId") long userId);
|
List<Automation> findAllByUserId(@Param("userId") long userId);
|
||||||
|
|
||||||
|
@EntityGraph(attributePaths = {"scenes", "triggers"})
|
||||||
|
Optional<Automation> findByIdAndUserId(@Param("id") long id, @Param("userId") long userId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@ public class BooleanTrigger<D extends Device & BooleanTriggerable> extends Trigg
|
||||||
@Column(name = "switchable_on")
|
@Column(name = "switchable_on")
|
||||||
private boolean on;
|
private boolean on;
|
||||||
|
|
||||||
|
public BooleanTrigger() {
|
||||||
|
super("booleanTrigger");
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isOn() {
|
public boolean isOn() {
|
||||||
return on;
|
return on;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@ import javax.validation.constraints.NotNull;
|
||||||
@Entity
|
@Entity
|
||||||
public class RangeTrigger<D extends Device & RangeTriggerable> extends Trigger<D> {
|
public class RangeTrigger<D extends Device & RangeTriggerable> extends Trigger<D> {
|
||||||
|
|
||||||
|
public RangeTrigger() {
|
||||||
|
super("rangeTrigger");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean triggered() {
|
public boolean triggered() {
|
||||||
double value = getDevice().readTriggerState();
|
double value = getDevice().readTriggerState();
|
||||||
|
|
|
@ -65,8 +65,9 @@ public class ScenePriority {
|
||||||
return automationId;
|
return automationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAutomationId(Long automationId) {
|
public ScenePriority setAutomationId(Long automationId) {
|
||||||
this.automationId = automationId;
|
this.automationId = automationId;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scene getScene() {
|
public Scene getScene() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
|
@ -8,7 +9,11 @@ public interface ScenePriorityRepository extends CrudRepository<ScenePriority, L
|
||||||
|
|
||||||
List<ScenePriority> findAllBySceneId(@Param("sceneId") long sceneId);
|
List<ScenePriority> findAllBySceneId(@Param("sceneId") long sceneId);
|
||||||
|
|
||||||
|
@Transactional
|
||||||
void deleteBySceneId(@Param("sceneId") long sceneId);
|
void deleteBySceneId(@Param("sceneId") long sceneId);
|
||||||
|
|
||||||
List<ScenePriority> findAllByAutomationId(@Param("automationId") long automationId);
|
List<ScenePriority> findAllByAutomationId(@Param("automationId") long automationId);
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
void deleteAllByAutomationId(Long automationId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,22 +2,23 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
||||||
|
|
||||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude;
|
import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.*;
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.GenerationType;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Inheritance;
|
|
||||||
import javax.persistence.InheritanceType;
|
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.persistence.PreRemove;
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
||||||
public abstract class Trigger<D extends Device> {
|
public abstract class Trigger<D extends Device> {
|
||||||
|
|
||||||
|
@Transient private String kind;
|
||||||
|
|
||||||
|
protected Trigger(String kind) {
|
||||||
|
this.kind = kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKind() {
|
||||||
|
return kind;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract boolean triggered();
|
public abstract boolean triggered();
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
|
@ -84,8 +85,9 @@ public abstract class Trigger<D extends Device> {
|
||||||
return automationId;
|
return automationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAutomationId(Long automationId) {
|
public Trigger<D> setAutomationId(Long automationId) {
|
||||||
this.automationId = automationId;
|
this.automationId = automationId;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreRemove
|
@PreRemove
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
public interface TriggerRepository<T extends Trigger<?>> extends CrudRepository<T, Long> {
|
public interface TriggerRepository<T extends Trigger<?>> extends CrudRepository<T, Long> {
|
||||||
|
|
||||||
List<T> findAllByDeviceId(@Param("deviceId") long deviceId);
|
List<T> findAllByDeviceId(@Param("deviceId") long deviceId);
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
void deleteAllByAutomationId(Long automationId);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue