Implemented Many-to-Many behaviour for Switches and Dimmers
This commit is contained in:
parent
1fe31c0d46
commit
7cbacd7406
14 changed files with 88 additions and 111 deletions
|
@ -75,20 +75,6 @@ public class ButtonDimmerController
|
|||
return buttonDimmer.getOutputs();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/lights")
|
||||
public Set<? extends OutputDevice> addLight(
|
||||
@PathVariable("id") long inputId, @RequestBody List<Long> lightId)
|
||||
throws NotFoundException {
|
||||
return addOutput(inputId, lightId);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}/lights")
|
||||
public Set<? extends OutputDevice> removeLight(
|
||||
@PathVariable("id") long inputId, @RequestBody List<Long> lightId)
|
||||
throws NotFoundException {
|
||||
return removeOutput(inputId, lightId);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public void delete(@PathVariable("id") long id) {
|
||||
buttonDimmerRepository.deleteById(id);
|
||||
|
|
|
@ -2,10 +2,18 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
|
|||
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
|
||||
import com.google.gson.Gson;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static ch.usi.inf.sa4.sanmarinoes.smarthut.utils.Utils.toList;
|
||||
|
||||
/**
|
||||
* An abstract controller for an input device that has output connected to it. Aids to create the
|
||||
* output add and output remove route
|
||||
|
@ -103,4 +111,18 @@ public abstract class InputDeviceConnectionController<
|
|||
outputReposiory.saveAll(pair.output);
|
||||
return pair.input.getOutputs();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/lights")
|
||||
public List<OutputDevice> addLight(
|
||||
@PathVariable("id") long inputId, @RequestBody List<Long> lightId)
|
||||
throws NotFoundException {
|
||||
return toList(addOutput(inputId, lightId));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}/lights")
|
||||
public List<OutputDevice> removeLight(
|
||||
@PathVariable("id") long inputId, @RequestBody List<Long> lightId)
|
||||
throws NotFoundException {
|
||||
return toList(removeOutput(inputId, lightId));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,20 +68,6 @@ public class KnobDimmerController
|
|||
return dimmer.getOutputs();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/lights")
|
||||
public Set<? extends OutputDevice> addLight(
|
||||
@PathVariable("id") long inputId, @RequestBody List<Long> lightId)
|
||||
throws NotFoundException {
|
||||
return addOutput(inputId, lightId);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}/lights")
|
||||
public Set<? extends OutputDevice> removeLight(
|
||||
@PathVariable("id") long inputId, @RequestBody List<Long> lightId)
|
||||
throws NotFoundException {
|
||||
return removeOutput(inputId, lightId);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public void delete(@PathVariable("id") long id) {
|
||||
knobDimmerRepository.deleteById(id);
|
||||
|
|
|
@ -9,6 +9,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
|
|||
import java.security.Principal;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.validation.Valid;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.*;
|
||||
|
@ -81,20 +82,6 @@ public class SwitchController extends InputDeviceConnectionController<Switch, Sw
|
|||
return s.getOutputs();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/lights")
|
||||
public Set<? extends OutputDevice> addSwitchable(
|
||||
@PathVariable("id") long inputId, @RequestBody List<Long> switchableId)
|
||||
throws NotFoundException {
|
||||
return addOutput(inputId, switchableId);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}/lights")
|
||||
public Set<? extends OutputDevice> removeSwitchable(
|
||||
@PathVariable("id") long inputId, @RequestBody List<Long> switchableId)
|
||||
throws NotFoundException {
|
||||
return removeOutput(inputId, switchableId);
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public void deleteById(@PathVariable("id") long id) {
|
||||
switchRepository.deleteById(id);
|
||||
|
|
|
@ -23,25 +23,25 @@ public interface Connector<I extends InputDevice, O extends OutputDevice> {
|
|||
void connect(I input, O output, boolean connect);
|
||||
|
||||
/**
|
||||
* Produces a basic implementation of a connector, assuming there is a OneToMany relationship
|
||||
* Produces a basic implementation of a connector, assuming there is a ManyToMany relationship
|
||||
* between J and K
|
||||
*
|
||||
* @param outputsGetter the getter method of the set of outputs on the input class
|
||||
* @param inputSetter the setter method for the input id on the output class
|
||||
* @param inputsGetter the getter method of the set of outputs on the input class
|
||||
* @param <J> the input device type
|
||||
* @param <K> the output device type
|
||||
* @return a Connector implementation for the pair of types J and K
|
||||
*/
|
||||
static <J extends InputDevice, K extends OutputDevice> Connector<J, K> basic(
|
||||
Function<J, Set<? super K>> outputsGetter, BiConsumer<K, Long> inputSetter) {
|
||||
Function<J, Set<? super K>> outputsGetter, Function<K, Set<? super J>> inputsGetter) {
|
||||
return (i, o, connect) -> {
|
||||
if (connect) {
|
||||
outputsGetter.apply(i).add(o);
|
||||
inputsGetter.apply(o).add(i);
|
||||
} else {
|
||||
outputsGetter.apply(i).remove(o);
|
||||
inputsGetter.apply(o).remove(i);
|
||||
}
|
||||
|
||||
inputSetter.accept(o, connect ? i.getId() : null);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import javax.validation.constraints.NotNull;
|
|||
|
||||
/** Generic abstraction for a smart home device */
|
||||
@Entity
|
||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
public abstract class Device {
|
||||
|
||||
/** Ways a device can behave in the automation flow. For now only input/output */
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
||||
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Set;
|
||||
|
||||
/** Represent a dimmable light */
|
||||
@Entity
|
||||
|
@ -15,22 +15,18 @@ public class DimmableLight extends Switchable {
|
|||
|
||||
public static final Connector<ButtonDimmer, DimmableLight>
|
||||
BUTTON_DIMMER_DIMMABLE_LIGHT_CONNECTOR =
|
||||
Connector.basic(ButtonDimmer::getOutputs, DimmableLight::setDimmerId);
|
||||
Connector.basic(ButtonDimmer::getOutputs, DimmableLight::getDimmers);
|
||||
|
||||
public static final Connector<KnobDimmer, DimmableLight> KNOB_DIMMER_DIMMABLE_LIGHT_CONNECTOR =
|
||||
Connector.basic(KnobDimmer::getOutputs, DimmableLight::setDimmerId);
|
||||
Connector.basic(KnobDimmer::getOutputs, DimmableLight::getDimmers);
|
||||
|
||||
public DimmableLight() {
|
||||
super("dimmableLight");
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
@ManyToMany(mappedBy = "dimmables", cascade = CascadeType.DETACH)
|
||||
@GsonExclude
|
||||
@JoinColumn(name = "dimmer_id", updatable = false, insertable = false)
|
||||
private Dimmer dimmer;
|
||||
|
||||
@Column(name = "dimmer_id")
|
||||
private Long dimmerId;
|
||||
private Set<Dimmer> dimmers;
|
||||
|
||||
/** The light intensity value. Goes from 0 (off) to 100 (on) */
|
||||
@NotNull
|
||||
|
@ -76,14 +72,15 @@ public class DimmableLight extends Switchable {
|
|||
intensity = on ? oldIntensity : 0;
|
||||
}
|
||||
|
||||
public void setDimmerId(Long dimmerId) {
|
||||
this.dimmerId = dimmerId;
|
||||
super.setSwitchId(null);
|
||||
public Set<Dimmer> getDimmers() {
|
||||
return this.dimmers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSwitchId(Long switchId) {
|
||||
super.setSwitchId(switchId);
|
||||
this.dimmerId = null;
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this)
|
||||
.add("intensity", intensity)
|
||||
.add("oldIntensity", oldIntensity)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
||||
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Inheritance;
|
||||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.PreRemove;
|
||||
import javax.persistence.*;
|
||||
|
||||
/** Represents a generic dimmer input device */
|
||||
@Entity
|
||||
|
@ -16,8 +14,14 @@ public abstract class Dimmer extends InputDevice {
|
|||
super(kind);
|
||||
}
|
||||
|
||||
@OneToMany(mappedBy = "dimmer")
|
||||
private Set<DimmableLight> lights = new HashSet<>();
|
||||
@ManyToMany(cascade = CascadeType.DETACH)
|
||||
@GsonExclude
|
||||
@JoinTable(
|
||||
name = "dimmer_dimmable",
|
||||
joinColumns = @JoinColumn(name = "dimmer_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "dimmable_id")
|
||||
)
|
||||
private Set<DimmableLight> dimmables = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Get the lights connected to this dimmer
|
||||
|
@ -26,18 +30,11 @@ public abstract class Dimmer extends InputDevice {
|
|||
*/
|
||||
@Override
|
||||
public Set<DimmableLight> getOutputs() {
|
||||
return this.lights;
|
||||
return this.dimmables;
|
||||
}
|
||||
|
||||
/** Add a light to be controller by this dimmer */
|
||||
public void addDimmableLight(DimmableLight dimmableLight) {
|
||||
lights.add(dimmableLight);
|
||||
}
|
||||
|
||||
@PreRemove
|
||||
private void removeLightsFromDimmer() {
|
||||
for (DimmableLight dl : getOutputs()) {
|
||||
dl.setDimmerId(null);
|
||||
}
|
||||
dimmables.add(dimmableLight);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import javax.persistence.InheritanceType;
|
|||
* environment (sensor) or the user (switch / dimmer).
|
||||
*/
|
||||
@Entity
|
||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
public abstract class InputDevice extends Device {
|
||||
public InputDevice(String kind) {
|
||||
super(kind, FlowType.INPUT);
|
||||
|
|
|
@ -7,7 +7,7 @@ import javax.persistence.*;
|
|||
* ...).
|
||||
*/
|
||||
@Entity
|
||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
public abstract class OutputDevice extends Device {
|
||||
public OutputDevice(String kind) {
|
||||
super(kind, FlowType.OUTPUT);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
|
@ -44,4 +46,12 @@ public class SmartPlug extends Switchable {
|
|||
public SmartPlug() {
|
||||
super("smartPlug");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this)
|
||||
.add("totalConsumption", totalConsumption)
|
||||
.add("on", on)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
||||
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.PreRemove;
|
||||
import javax.persistence.*;
|
||||
|
||||
/** A switch input device */
|
||||
@Entity
|
||||
public class Switch extends InputDevice {
|
||||
|
||||
@OneToMany(mappedBy = "switchDevice")
|
||||
@ManyToMany(cascade = CascadeType.DETACH)
|
||||
@GsonExclude
|
||||
@JoinTable(
|
||||
name = "switch_switchable",
|
||||
joinColumns = @JoinColumn(name = "switch_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "switchable_id")
|
||||
)
|
||||
private Set<Switchable> switchables = new HashSet<>();
|
||||
|
||||
/** The state of this switch */
|
||||
|
@ -52,11 +57,4 @@ public class Switch extends InputDevice {
|
|||
public Set<Switchable> getOutputs() {
|
||||
return switchables;
|
||||
}
|
||||
|
||||
@PreRemove
|
||||
public void removeSwitchable() {
|
||||
for (Switchable s : getOutputs()) {
|
||||
s.setSwitchId(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,22 +2,20 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
|
|||
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude;
|
||||
import javax.persistence.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/** A device that can be turned either on or off */
|
||||
@Entity
|
||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
public abstract class Switchable extends OutputDevice {
|
||||
|
||||
public static final Connector<Switch, Switchable> SWITCH_SWITCHABLE_CONNECTOR =
|
||||
Connector.basic(Switch::getOutputs, Switchable::setSwitchId);
|
||||
Connector.basic(Switch::getOutputs, Switchable::getSwitches);
|
||||
|
||||
@ManyToOne
|
||||
@ManyToMany(mappedBy = "switchables", cascade = CascadeType.DETACH)
|
||||
@GsonExclude
|
||||
@JoinColumn(name = "switch_id", updatable = false, insertable = false)
|
||||
private Switch switchDevice;
|
||||
|
||||
@Column(name = "switch_id")
|
||||
private Long switchId;
|
||||
private Set<Switch> inputs = new HashSet<>();
|
||||
|
||||
protected Switchable(String kind) {
|
||||
super(kind);
|
||||
|
@ -37,11 +35,7 @@ public abstract class Switchable extends OutputDevice {
|
|||
*/
|
||||
public abstract void setOn(boolean on);
|
||||
|
||||
public Long getSwitchId() {
|
||||
return switchId;
|
||||
}
|
||||
|
||||
public void setSwitchId(Long switchId) {
|
||||
this.switchId = switchId;
|
||||
public Set<Switch> getSwitches() {
|
||||
return inputs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ public final class Utils {
|
|||
void apply(T input) throws Throwable;
|
||||
}
|
||||
|
||||
public static <T> List<T> toList(Iterable<T> iterable) {
|
||||
public static <T> List<T> toList(Iterable<? extends T> iterable) {
|
||||
return StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue