Skip to content

Commit

Permalink
#90 Add cube
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreKoepke committed Jan 4, 2023
1 parent 993e39e commit 0654483
Show file tree
Hide file tree
Showing 14 changed files with 171 additions and 25 deletions.
7 changes: 2 additions & 5 deletions src/main/java/ch/akop/homesystem/deconz/DeconzConnector.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
import ch.akop.homesystem.models.devices.Device;
import ch.akop.homesystem.models.devices.actor.*;
import ch.akop.homesystem.models.devices.other.Scene;
import ch.akop.homesystem.models.devices.sensor.Button;
import ch.akop.homesystem.models.devices.sensor.CloseContact;
import ch.akop.homesystem.models.devices.sensor.MotionSensor;
import ch.akop.homesystem.models.devices.sensor.PowerMeter;
import ch.akop.homesystem.models.devices.sensor.*;
import ch.akop.homesystem.persistence.model.config.DeconzConfig;
import ch.akop.homesystem.persistence.repository.config.DeconzConfigRepository;
import ch.akop.homesystem.services.AutomationService;
Expand Down Expand Up @@ -144,7 +141,7 @@ private void registerSensor(String id, Sensor sensor) {
private Device<?> determineSensor(Sensor sensor) {
return switch (sensor.getType()) {
case "ZHAOpenClose" -> new CloseContact();
case "ZHASwitch" -> new Button();
case "ZHASwitch" -> sensor.getModelid().equals("lumi.sensor_cube.aqgl01") ? new AqaraCube() : new Button();
case "ZHAPresence" -> new MotionSensor();
case "ZHAPower" -> new PowerMeter();
default -> null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ch.akop.homesystem.models.devices.sensor;

import ch.akop.homesystem.deconz.rest.State;
import io.reactivex.rxjava3.subjects.PublishSubject;
import io.reactivex.rxjava3.subjects.ReplaySubject;
import io.reactivex.rxjava3.subjects.Subject;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Data
@EqualsAndHashCode(callSuper = true)
public class AqaraCube extends Sensor<AqaraCube> {

@Getter
private final Subject<Integer> activeSide$ = ReplaySubject.createWithSize(1);

private final Subject<EMPTY> shacked$ = PublishSubject.create();

public enum EMPTY {INSTANCE}

@Override
public Sensor<AqaraCube> consumeUpdate(State update) {
if (update.getButtonevent() != null) {
if (update.getButtonevent() < 7000) {
var firstNumber = update.getButtonevent() / 1000;
activeSide$.onNext(firstNumber);
} else if (update.getButtonevent() == 7007) {
shacked$.onNext(EMPTY.INSTANCE);
}
}
return this;
}

}
9 changes: 9 additions & 0 deletions src/main/java/ch/akop/homesystem/models/events/CubeEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ch.akop.homesystem.models.events;

import lombok.Data;

@Data
public class CubeEvent {
private final String cubeName;
private final CubeEventType eventType;
}
11 changes: 11 additions & 0 deletions src/main/java/ch/akop/homesystem/models/events/CubeEventType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package ch.akop.homesystem.models.events;

public enum CubeEventType {
FLIPPED_TO_SIDE_1,
FLIPPED_TO_SIDE_2,
FLIPPED_TO_SIDE_3,
FLIPPED_TO_SIDE_4,
FLIPPED_TO_SIDE_5,
FLIPPED_TO_SIDE_6,
SHAKED
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package ch.akop.homesystem.persistence.model.config;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;

@Entity
@Table(name = "config_cube")
@Getter
@Setter
public class CubeConfig {

@Id
private String name;

private String sceneNameOnSide_1;
private String sceneNameOnSide_2;
private String sceneNameOnSide_3;
private String sceneNameOnSide_4;
private String sceneNameOnSide_5;
private String sceneNameOnSide_6;
private String sceneNameOnShake;

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
package ch.akop.homesystem.persistence.model.config;

import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
Expand All @@ -25,7 +19,7 @@ public class MotionSensorConfig {
private String name;

@NonNull
@ElementCollection
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "config_motion_sensor_lights")
@MapKeyColumn(columnDefinition = "TEXT")
@Column(columnDefinition = "TEXT")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ch.akop.homesystem.persistence.repository.config;

import ch.akop.homesystem.persistence.model.config.CubeConfig;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CubeConfigRepository extends JpaRepository<CubeConfig, String> {
}
2 changes: 2 additions & 0 deletions src/main/java/ch/akop/homesystem/services/DeviceService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ public interface DeviceService {

boolean isAnyLightOn();

void activeSceneForAllGroups(String sceneName);

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package ch.akop.homesystem.services.impl;

import ch.akop.homesystem.models.devices.Device;
import ch.akop.homesystem.models.devices.sensor.AqaraCube;
import ch.akop.homesystem.models.devices.sensor.Button;
import ch.akop.homesystem.models.devices.sensor.CloseContact;
import ch.akop.homesystem.models.devices.sensor.CloseContactState;
import ch.akop.homesystem.models.events.ButtonPressEvent;
import ch.akop.homesystem.models.events.ButtonPressInternalEvent;
import ch.akop.homesystem.models.events.Event;
import ch.akop.homesystem.models.events.*;
import ch.akop.homesystem.persistence.repository.config.BasicConfigRepository;
import ch.akop.homesystem.persistence.repository.config.OffButtonConfigRepository;
import ch.akop.homesystem.services.AutomationService;
Expand Down Expand Up @@ -78,6 +77,26 @@ private void addDevice(Device<?> device) {
button.getEvents$()
.subscribe(integer -> eventPublisher.publishEvent(new ButtonPressInternalEvent(button.getName(), integer)));
}

if (device instanceof AqaraCube cube) {
cube.getActiveSide$()
.skip(1)
.subscribe(activeSide -> eventPublisher.publishEvent(new CubeEvent(cube.getName(), determineFlippedSide(activeSide))));
cube.getShacked$()
.subscribe(empty -> eventPublisher.publishEvent(new CubeEvent(cube.getName(), CubeEventType.SHAKED)));
}
}

private CubeEventType determineFlippedSide(int side) {
return switch (side) {
case 1 -> CubeEventType.FLIPPED_TO_SIDE_1;
case 2 -> CubeEventType.FLIPPED_TO_SIDE_2;
case 3 -> CubeEventType.FLIPPED_TO_SIDE_3;
case 4 -> CubeEventType.FLIPPED_TO_SIDE_4;
case 5 -> CubeEventType.FLIPPED_TO_SIDE_5;
case 6 -> CubeEventType.FLIPPED_TO_SIDE_6;
default -> throw new IllegalArgumentException("Cube-Side %d not existing".formatted(side));
};
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import ch.akop.homesystem.models.devices.Device;
import ch.akop.homesystem.models.devices.actor.DimmableLight;
import ch.akop.homesystem.models.devices.actor.SimpleLight;
import ch.akop.homesystem.models.devices.other.Group;
import ch.akop.homesystem.models.devices.other.Scene;
import ch.akop.homesystem.persistence.repository.config.BasicConfigRepository;
import ch.akop.homesystem.services.DeviceService;
import ch.akop.homesystem.util.SleepUtil;
Expand Down Expand Up @@ -95,4 +97,13 @@ public boolean isAnyLightOn() {
.getNotLights().contains(light.getName()))
.anyMatch(SimpleLight::isCurrentStateIsOn);
}

@Override
public void activeSceneForAllGroups(String sceneName) {
getDevicesOfType(Group.class)
.stream()
.flatMap(group -> group.getScenes().stream())
.filter(scene -> scene.getName().equals(sceneName))
.forEach(Scene::activate);
}
}
25 changes: 24 additions & 1 deletion src/main/java/ch/akop/homesystem/states/NormalState.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package ch.akop.homesystem.states;

import ch.akop.homesystem.models.events.CubeEvent;
import ch.akop.homesystem.models.events.Event;
import ch.akop.homesystem.persistence.repository.config.BasicConfigRepository;
import ch.akop.homesystem.persistence.repository.config.CubeConfigRepository;
import ch.akop.homesystem.services.DeviceService;
import ch.akop.homesystem.services.MessageService;
import ch.akop.homesystem.services.UserService;
Expand All @@ -21,6 +23,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.Duration;
Expand Down Expand Up @@ -49,7 +52,7 @@ public class NormalState extends Activatable implements State {
private final RainDetectorService rainDetectorService;
private final UserService userService;
private final BasicConfigRepository basicConfigRepository;

private final CubeConfigRepository cubeConfigRepository;
private Map<String, Boolean> lastPresenceMap;


Expand Down Expand Up @@ -141,6 +144,26 @@ public void event(Event event) {
}
}

@EventListener
public void event(CubeEvent cubeEvent) {
cubeConfigRepository.findById(cubeEvent.getCubeName())
.ifPresent(cubeConfig -> {
var sceneName = switch (cubeEvent.getEventType()) {
case FLIPPED_TO_SIDE_1 -> cubeConfig.getSceneNameOnSide_1();
case FLIPPED_TO_SIDE_2 -> cubeConfig.getSceneNameOnSide_2();
case FLIPPED_TO_SIDE_3 -> cubeConfig.getSceneNameOnSide_3();
case FLIPPED_TO_SIDE_4 -> cubeConfig.getSceneNameOnSide_4();
case FLIPPED_TO_SIDE_5 -> cubeConfig.getSceneNameOnSide_5();
case FLIPPED_TO_SIDE_6 -> cubeConfig.getSceneNameOnSide_6();
case SHAKED -> cubeConfig.getSceneNameOnShake();
};

if (StringUtils.hasText(sceneName)) {
deviceService.activeSceneForAllGroups(sceneName);
}
});
}

@SneakyThrows
private void doCentralOff() {
canStartMainDoorAnimation.blockFor(DEFAULT_DURATION_ANIMATION_BLOCKER);
Expand Down
10 changes: 3 additions & 7 deletions src/main/java/ch/akop/homesystem/states/SleepState.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,9 @@ private ZonedDateTime getWakeUpDateTime() {


public void turnLightsOff() {
deviceService.getDevicesOfType(Group.class)
.stream()
.flatMap(group -> group.getScenes().stream())
.filter(scene -> scene.getName().equals(basicConfigRepository.findFirstByOrderByModifiedDesc()
.orElseThrow()
.getNightSceneName()))
.forEach(Scene::activate);
deviceService.activeSceneForAllGroups(basicConfigRepository.findFirstByOrderByModifiedDesc()
.orElseThrow()
.getNightSceneName());
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
application.yaml
application.y*ml
12 changes: 12 additions & 0 deletions src/main/resources/db/migration/V1__initializeDatabase.sql
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,15 @@ create table if not exists public.rain_stats
raining boolean not null
);

create table if not exists public.config_cube
(
name text primary key,
scene_name_on_side_1 text null,
scene_name_on_side_2 text null,
scene_name_on_side_3 text null,
scene_name_on_side_4 text null,
scene_name_on_side_5 text null,
scene_name_on_side_6 text null,
scene_name_on_shake text null
);

0 comments on commit 0654483

Please sign in to comment.