other minor fixes^2
This commit is contained in:
parent
4a963115bb
commit
69d1b38ff2
7 changed files with 44 additions and 28 deletions
|
@ -71,14 +71,18 @@ public abstract class Device {
|
|||
@SocketGsonExclude
|
||||
private Set<State<?>> states = new HashSet<>();
|
||||
|
||||
@Transient @GsonExclude private boolean fromHost = false;
|
||||
@Transient @GsonExclude private Long fromHostId = null;
|
||||
|
||||
@Transient @GsonExclude private boolean fromGuest = false;
|
||||
|
||||
@Transient @GsonExclude private boolean deleted = false;
|
||||
|
||||
public boolean isFromHost() {
|
||||
return fromHost;
|
||||
public Long getFromHostId() {
|
||||
return fromHostId;
|
||||
}
|
||||
|
||||
public void setFromHostId(Long fromHostId) {
|
||||
this.fromHostId = fromHostId;
|
||||
}
|
||||
|
||||
public boolean isDeleted() {
|
||||
|
@ -97,10 +101,6 @@ public abstract class Device {
|
|||
this.fromGuest = fromGuest;
|
||||
}
|
||||
|
||||
public void setFromHost(boolean fromHost) {
|
||||
this.fromHost = fromHost;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ public class UpdateTasks {
|
|||
c.forEach(
|
||||
s ->
|
||||
sensorSocketEndpoint.queueDeviceUpdate(
|
||||
s, sensorRepository.findUser(s.getId())));
|
||||
s, sensorRepository.findUser(s.getId()), false, null, false));
|
||||
}
|
||||
|
||||
/** Sends device updates through sensor socket in batch every one second */
|
||||
|
|
|
@ -125,21 +125,17 @@ public class DeviceService {
|
|||
|
||||
// We're telling the host that a guest has modified a device. Therefore, fromGuest becomes
|
||||
// true.
|
||||
device.setFromHost(false);
|
||||
device.setFromGuest(true);
|
||||
// broadcast device update to host
|
||||
endpoint.queueDeviceUpdate(device, host);
|
||||
endpoint.queueDeviceUpdate(device, host, true, null, false);
|
||||
|
||||
// We're telling all guests that a higher entity has issued a device update. Therefore,
|
||||
// fromHost becomes true.
|
||||
device.setFromHost(true);
|
||||
device.setFromGuest(false);
|
||||
for (final User guest : guests) {
|
||||
if (guest.equals(currentUser)) {
|
||||
continue;
|
||||
}
|
||||
// enqueue all device updates for all other guests
|
||||
endpoint.queueDeviceUpdate(device, guest);
|
||||
endpoint.queueDeviceUpdate(device, guest, false, host.getId(), false);
|
||||
}
|
||||
|
||||
return device;
|
||||
|
@ -157,15 +153,13 @@ public class DeviceService {
|
|||
final User user = userRepository.findByUsername(username);
|
||||
final Set<User> guests = user.getGuests();
|
||||
// make sure we're broadcasting from host
|
||||
device.setFromHost(true);
|
||||
device.setFromGuest(false);
|
||||
for (final User guest : guests) {
|
||||
// broadcast to endpoint the object device, with receiving user set to guest
|
||||
endpoint.queueDeviceUpdate(device, guest);
|
||||
endpoint.queueDeviceUpdate(device, guest, false, user.getId(), false);
|
||||
}
|
||||
|
||||
if (causedByTrigger) {
|
||||
endpoint.queueDeviceUpdate(device, user);
|
||||
endpoint.queueDeviceUpdate(device, user, false, user.getId(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ public class MotionSensorService {
|
|||
@Autowired private MotionSensorRepository motionSensorRepository;
|
||||
|
||||
/**
|
||||
* Updates detection status of given motion sensor and propagates update throgh socket
|
||||
* Updates detection status of given motion sensor and propagates update through socket
|
||||
*
|
||||
* @param sensor the motion sensor to update
|
||||
* @param detected the new detection status
|
||||
|
@ -26,7 +26,7 @@ public class MotionSensorService {
|
|||
final MotionSensor toReturn = deviceService.saveAsOwner(sensor, username);
|
||||
|
||||
sensorSocketEndpoint.queueDeviceUpdate(
|
||||
sensor, motionSensorRepository.findUser(sensor.getId()));
|
||||
sensor, motionSensorRepository.findUser(sensor.getId()), false, null, false);
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,8 @@ public class SensorService {
|
|||
sensor =
|
||||
deviceService.saveAsOwner(
|
||||
sensor, sensorRepository.findUser(sensor.getId()).getUsername());
|
||||
endpoint.queueDeviceUpdate(sensor, sensorRepository.findUser(sensor.getId()));
|
||||
endpoint.queueDeviceUpdate(
|
||||
sensor, sensorRepository.findUser(sensor.getId()), false, null, false);
|
||||
return sensor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class ThermostatService {
|
|||
this.computeState(t);
|
||||
|
||||
deviceService.saveAsOwner(t, thermostatRepository.findUser(t.getId()).getUsername());
|
||||
endpoint.queueDeviceUpdate(t, thermostatRepository.findUser(t.getId()));
|
||||
endpoint.queueDeviceUpdate(t, thermostatRepository.findUser(t.getId()), false, null, false);
|
||||
}
|
||||
|
||||
public void updateStates() {
|
||||
|
|
|
@ -5,6 +5,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.config.JWTTokenUtils;
|
|||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Device;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.User;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.UserRepository;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.service.DeviceService;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
|
@ -21,6 +22,8 @@ public class SensorSocketEndpoint extends Endpoint {
|
|||
|
||||
private Gson gson = GsonConfig.socketGson();
|
||||
|
||||
@Autowired private DeviceService deviceService;
|
||||
|
||||
private UserRepository userRepository;
|
||||
|
||||
private JWTTokenUtils jwtTokenUtils;
|
||||
|
@ -28,7 +31,10 @@ public class SensorSocketEndpoint extends Endpoint {
|
|||
private Multimap<User, Session> authorizedClients =
|
||||
Multimaps.synchronizedMultimap(HashMultimap.create());
|
||||
|
||||
private final Map<User, Map<Long, Device>> messages = new HashMap<>();
|
||||
// messages are now stored as strings as a "hack" to capture and clone the state of the device,
|
||||
// since
|
||||
// fromHost and fromGuest are just mutable properties and hibernate caches the object.
|
||||
private final Map<User, Map<Long, String>> messages = new HashMap<>();
|
||||
|
||||
@Autowired
|
||||
public SensorSocketEndpoint(UserRepository userRepository, JWTTokenUtils jwtTokenUtils) {
|
||||
|
@ -41,18 +47,33 @@ public class SensorSocketEndpoint extends Endpoint {
|
|||
*
|
||||
* @param device the device update to be sent
|
||||
* @param u the user the device belongs
|
||||
* @param fromGuest value for device.fromGuest. This will be put in the device passed.
|
||||
* @param fromHostId value for device.fromHostId. This will be put in the device passed.
|
||||
* @param deleted value for device.deleted. This will be put in the device passed.
|
||||
*/
|
||||
public void queueDeviceUpdate(Device device, User u) {
|
||||
public void queueDeviceUpdate(
|
||||
Device device, User u, boolean fromGuest, Long fromHostId, boolean deleted) {
|
||||
synchronized (messages) {
|
||||
device.setFromGuest(fromGuest);
|
||||
device.setFromHostId(fromHostId);
|
||||
device.setDeleted(deleted);
|
||||
|
||||
// sort of an hack: force the population of thermostat measureTemperature and other
|
||||
// possible
|
||||
// computed fields in the future. This should already be done by the callers of this
|
||||
// method but for
|
||||
// whatever reason they don't do it.
|
||||
deviceService.populateComputedFields(List.of(device));
|
||||
|
||||
messages.putIfAbsent(u, new HashMap<>());
|
||||
messages.get(u).put(device.getId(), device);
|
||||
messages.get(u).put(device.getId(), gson.toJson(device));
|
||||
}
|
||||
}
|
||||
|
||||
/** Sends all device updates queued to be sent in a unique WebSocket message */
|
||||
public void flushDeviceUpdates() {
|
||||
synchronized (messages) {
|
||||
for (Map.Entry<User, Map<Long, Device>> batchForUser : messages.entrySet()) {
|
||||
for (Map.Entry<User, Map<Long, String>> batchForUser : messages.entrySet()) {
|
||||
broadcast(batchForUser.getKey(), batchForUser.getValue().values());
|
||||
batchForUser.getValue().clear();
|
||||
}
|
||||
|
@ -66,13 +87,13 @@ public class SensorSocketEndpoint extends Endpoint {
|
|||
* @param messages the message batch to send
|
||||
* @param u the user to which to send the message
|
||||
*/
|
||||
private void broadcast(User u, Collection<?> messages) {
|
||||
private void broadcast(User u, Collection<String> messages) {
|
||||
if (messages.isEmpty()) return;
|
||||
final HashSet<Session> sessions = new HashSet<>(authorizedClients.get(u));
|
||||
for (Session s : sessions) {
|
||||
try {
|
||||
if (s.isOpen()) {
|
||||
s.getBasicRemote().sendText(gson.toJson(messages));
|
||||
s.getBasicRemote().sendText("[" + String.join(",", messages) + "]");
|
||||
} else {
|
||||
authorizedClients.remove(u, s);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue