DeviceStateScene + Search blur fix
This commit is contained in:
parent
5a74795569
commit
febb198c93
@ -1,4 +1,4 @@
|
|||||||
import {validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators";
|
import {validateListOrEmpty, validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators";
|
||||||
import {Property} from "../property/Property";
|
import {Property} from "../property/Property";
|
||||||
|
|
||||||
export abstract class Device {
|
export abstract class Device {
|
||||||
@ -21,6 +21,15 @@ export abstract class Device {
|
|||||||
type,
|
type,
|
||||||
Property.fromJsonAllowNull(json['stateProperty']),
|
Property.fromJsonAllowNull(json['stateProperty']),
|
||||||
);
|
);
|
||||||
|
case "DeviceStateScene":
|
||||||
|
return new DeviceStateScene(
|
||||||
|
validateNumberNotNull(json['id']),
|
||||||
|
validateStringNotEmptyNotNull(json['title']),
|
||||||
|
type,
|
||||||
|
Property.fromJsonAllowNull(json['stateProperty']),
|
||||||
|
Property.fromJsonAllowNull(json['sceneProperty']),
|
||||||
|
validateListOrEmpty(json['sceneNumbers'], parseInt),
|
||||||
|
);
|
||||||
case "DeviceShutter":
|
case "DeviceShutter":
|
||||||
return new DeviceShutter(
|
return new DeviceShutter(
|
||||||
validateNumberNotNull(json['id']),
|
validateNumberNotNull(json['id']),
|
||||||
@ -67,6 +76,28 @@ export class DeviceSwitch extends Device {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class DeviceStateScene extends DeviceSwitch {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: number,
|
||||||
|
title: string,
|
||||||
|
type: string,
|
||||||
|
stateProperty: Property | null,
|
||||||
|
public sceneProperty: Property | null,
|
||||||
|
public sceneNumbers: number[],
|
||||||
|
) {
|
||||||
|
super(id, title, type, stateProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateProperty(property: Property): void {
|
||||||
|
super.updateProperty(property);
|
||||||
|
if (this.sceneProperty?.id === property.id) {
|
||||||
|
this.sceneProperty = property;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export class DeviceShutter extends Device {
|
export class DeviceShutter extends Device {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {ApiService, NO_COMPARE, NO_OP} from "../api.service";
|
import {ApiService, NO_COMPARE, NO_OP} from "../api.service";
|
||||||
import {Device} from "./Device";
|
import {Device, DeviceShutter, DeviceStateScene, DeviceSwitch} from "./Device";
|
||||||
|
import {Update} from "../Update";
|
||||||
|
import {PropertyService} from "../property/property.service";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -9,10 +11,15 @@ export class DeviceService {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly api: ApiService,
|
readonly api: ApiService,
|
||||||
|
readonly propertyService: PropertyService,
|
||||||
) {
|
) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subscribe(next: (device: Update<Device>) => void): void {
|
||||||
|
this.api.subscribe("DeviceDto", Device.fromJson, next);
|
||||||
|
}
|
||||||
|
|
||||||
findAll(next: (list: Device[]) => void, compare: (a: Device, b: Device) => number = NO_COMPARE, error: (error: any) => void = NO_OP): void {
|
findAll(next: (list: Device[]) => void, compare: (a: Device, b: Device) => number = NO_COMPARE, error: (error: any) => void = NO_OP): void {
|
||||||
this.api.getList("device/findAll", Device.fromJson, compare, next, error);
|
this.api.getList("device/findAll", Device.fromJson, compare, next, error);
|
||||||
}
|
}
|
||||||
@ -21,14 +28,42 @@ export class DeviceService {
|
|||||||
this.api.postReturnItem("device/set/" + device.id + "/" + key, value, Device.fromJson, next, error);
|
this.api.postReturnItem("device/set/" + device.id + "/" + key, value, Device.fromJson, next, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
setDeviceSwitch(device: Device, key: string, value: any, next: (item: Device) => void, error: (error: any) => void = NO_OP): void {
|
setDeviceSwitch(device: Device, key: string, value: any, next: (item: Device) => void = NO_OP, error: (error: any) => void = NO_OP): void {
|
||||||
this.api.postReturnItem("device/set/" + device.id + "/DeviceSwitch/" + key, value, Device.fromJson, next, error);
|
this.api.postReturnItem("device/set/" + device.id + "/DeviceSwitch/" + key, value, Device.fromJson, next, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
setDeviceShutter(device: Device, key: string, value: any, next: (item: Device) => void, error: (error: any) => void = NO_OP): void {
|
setDeviceStateScene(device: Device, key: string, value: any, next: (item: Device) => void = NO_OP, error: (error: any) => void = NO_OP): void {
|
||||||
|
this.api.postReturnItem("device/set/" + device.id + "/DeviceStateScene/" + key, value, Device.fromJson, next, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
setDeviceShutter(device: Device, key: string, value: any, next: (item: Device) => void = NO_OP, error: (error: any) => void = NO_OP): void {
|
||||||
this.api.postReturnItem("device/set/" + device.id + "/DeviceShutter/" + key, value, Device.fromJson, next, error);
|
this.api.postReturnItem("device/set/" + device.id + "/DeviceShutter/" + key, value, Device.fromJson, next, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSwitchState(d: Device, value: boolean): void {
|
||||||
|
const device: DeviceSwitch = d as DeviceSwitch;
|
||||||
|
if (!device.stateProperty) {
|
||||||
|
throw new Error("Property 'stateProperty' not set for: " + device);
|
||||||
|
}
|
||||||
|
this.propertyService.set(device.stateProperty, "value", value ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
setStateScene(d: Device, value: number): void {
|
||||||
|
const device: DeviceStateScene = d as DeviceStateScene;
|
||||||
|
if (!device.sceneProperty) {
|
||||||
|
throw new Error("Property 'sceneProperty' not set for: " + device);
|
||||||
|
}
|
||||||
|
this.propertyService.set(device.sceneProperty, "value", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setShutterPosition(d: Device, value: number): void {
|
||||||
|
const device: DeviceShutter = d as DeviceShutter;
|
||||||
|
if (!device.positionProperty) {
|
||||||
|
throw new Error("Property 'positionProperty' not set for: " + device);
|
||||||
|
}
|
||||||
|
this.propertyService.set(device.positionProperty, "value", value);
|
||||||
|
}
|
||||||
|
|
||||||
getById(id: number, next: (item: Device) => void, error: (error: any) => void = NO_OP): void {
|
getById(id: number, next: (item: Device) => void, error: (error: any) => void = NO_OP): void {
|
||||||
this.api.getItem("device/getById/" + id, Device.fromJson, next, error);
|
this.api.getItem("device/getById/" + id, Device.fromJson, next, error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import {NO_COMPARE} from "./api.service";
|
||||||
|
|
||||||
export function validateBooleanNotNull(value: any): boolean {
|
export function validateBooleanNotNull(value: any): boolean {
|
||||||
if (value !== true && value !== false) {
|
if (value !== true && value !== false) {
|
||||||
throw new Error("Not a boolean: " + value);
|
throw new Error("Not a boolean: " + value);
|
||||||
@ -66,7 +68,7 @@ export function validateDateAllowNull(value: any): Date | null {
|
|||||||
return validateDateNotNull(value);
|
return validateDateNotNull(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateListOrEmpty<T>(json: any, fromJson: (json: any) => T, compare: (a: T, b: T) => number): T[] {
|
export function validateListOrEmpty<T>(json: any, fromJson: (json: any) => T, compare: (a: T, b: T) => number = NO_COMPARE): T[] {
|
||||||
if (!Array.isArray(json)) {
|
if (!Array.isArray(json)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,14 @@
|
|||||||
|
<div class="config">
|
||||||
|
<select [(ngModel)]="createType">
|
||||||
|
<option ngValue="DeviceSwitch">Schalter</option>
|
||||||
|
<option ngValue="DeviceShutter">Rollladen</option>
|
||||||
|
</select>
|
||||||
|
<button (click)="create()">+ Hinzufügen</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ng-container *ngFor="let device of devices.sort(Device.compareTypeThenTitle); trackBy: Device.trackBy">
|
<ng-container *ngFor="let device of devices.sort(Device.compareTypeThenTitle); trackBy: Device.trackBy">
|
||||||
<ng-container [ngSwitch]="device.type">
|
<ng-container [ngSwitch]="device.type">
|
||||||
|
|
||||||
<div class="device" *ngSwitchCase="'DeviceSwitch'" [ngClass]="getSwitchClassList(device)">
|
<div class="device" *ngSwitchCase="'DeviceSwitch'" [ngClass]="getSwitchClassList(device)">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{device.title}}
|
{{device.title}}
|
||||||
@ -8,10 +17,25 @@
|
|||||||
<fa-icon [icon]="faEdit"></fa-icon>
|
<fa-icon [icon]="faEdit"></fa-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<img alt="An" class="control" src="assets/switch-on.svg" (click)="setSwitchState(device, true)"/>
|
<img alt="An" class="control" src="assets/switch-on.svg" (click)="deviceService.setSwitchState(device, true)"/>
|
||||||
<img alt="Aus" class="control" src="assets/switch-off.svg" (click)="setSwitchState(device, false)"/>
|
<img alt="Aus" class="control" src="assets/switch-off.svg" (click)="deviceService.setSwitchState(device, false)"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="device" *ngSwitchCase="'DeviceStateScene'" [ngClass]="getStateSceneClassList(device)">
|
||||||
|
<div class="title">
|
||||||
|
{{device.title}}
|
||||||
|
</div>
|
||||||
|
<div class="edit" [routerLink]="['/Device', {id: device.id}]">
|
||||||
|
<fa-icon [icon]="faEdit"></fa-icon>
|
||||||
|
</div>
|
||||||
|
<div class="controls">
|
||||||
|
<div *ngFor="let scene of getStateScenes(device)" class="control button" (click)="deviceService.setStateScene(device, scene.number)">
|
||||||
|
<span class="center">{{scene.title}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="device" *ngSwitchCase="'DeviceShutter'" [ngClass]="getShutterClassList(device)">
|
<div class="device" *ngSwitchCase="'DeviceShutter'" [ngClass]="getShutterClassList(device)">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{device.title}}
|
{{device.title}}
|
||||||
@ -20,30 +44,23 @@
|
|||||||
<fa-icon [icon]="faEdit"></fa-icon>
|
<fa-icon [icon]="faEdit"></fa-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<div class="control button" (click)="setShutterPosition(device, 0)">
|
<div class="control button" (click)="deviceService.setShutterPosition(device, 0)">
|
||||||
<span class="center">Auf</span>
|
<span class="center">Auf</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="control button" (click)="setShutterPosition(device, 40)">
|
<div class="control button" (click)="deviceService.setShutterPosition(device, 40)">
|
||||||
<span class="center">50%</span>
|
<span class="center">50%</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="control button" (click)="setShutterPosition(device, 75)">
|
<div class="control button" (click)="deviceService.setShutterPosition(device, 75)">
|
||||||
<span class="center">90%</span>
|
<span class="center">90%</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="control button" (click)="setShutterPosition(device, 85)">
|
<div class="control button" (click)="deviceService.setShutterPosition(device, 85)">
|
||||||
<span class="center">Schlitze</span>
|
<span class="center">Schlitze</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="control button" (click)="setShutterPosition(device, 100)">
|
<div class="control button" (click)="deviceService.setShutterPosition(device, 100)">
|
||||||
<span class="center">Zu</span>
|
<span class="center">Zu</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<p>
|
|
||||||
<select [(ngModel)]="createType">
|
|
||||||
<option ngValue="DeviceSwitch">Schalter</option>
|
|
||||||
<option ngValue="DeviceShutter">Rollladen</option>
|
|
||||||
</select>
|
|
||||||
<button (click)="create()">+ Hinzufügen</button>
|
|
||||||
</p>
|
|
||||||
|
|||||||
@ -3,6 +3,12 @@
|
|||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
|
||||||
|
@media (min-width: 1000px) {
|
||||||
|
float: left;
|
||||||
|
width: 400px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
float: left;
|
float: left;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -71,3 +77,8 @@
|
|||||||
.shutterUnknown {
|
.shutterUnknown {
|
||||||
background-color: gray;
|
background-color: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.config {
|
||||||
|
clear: both;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
import {DeviceService} from "../../api/device/device.service";
|
import {DeviceService} from "../../api/device/device.service";
|
||||||
import {PropertyService} from "../../api/property/property.service";
|
import {PropertyService} from "../../api/property/property.service";
|
||||||
import {Device, DeviceShutter, DeviceSwitch} from "../../api/device/Device";
|
import {Device, DeviceShutter, DeviceStateScene, DeviceSwitch} from "../../api/device/Device";
|
||||||
import {faEdit} from '@fortawesome/free-regular-svg-icons';
|
import {faEdit} from '@fortawesome/free-regular-svg-icons';
|
||||||
|
import {Scene} from "../../api/scene/Scene";
|
||||||
|
import {SceneService} from "../../api/scene/scene.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-device-list',
|
selector: 'app-device-list',
|
||||||
@ -17,10 +19,13 @@ export class DeviceListComponent implements OnInit {
|
|||||||
|
|
||||||
devices: Device[] = [];
|
devices: Device[] = [];
|
||||||
|
|
||||||
|
scenes: Scene[] = [];
|
||||||
|
|
||||||
createType: string = "DeviceSwitch";
|
createType: string = "DeviceSwitch";
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly deviceService: DeviceService,
|
readonly deviceService: DeviceService,
|
||||||
|
readonly sceneService: SceneService,
|
||||||
readonly propertyService: PropertyService,
|
readonly propertyService: PropertyService,
|
||||||
) {
|
) {
|
||||||
// nothing
|
// nothing
|
||||||
@ -28,23 +33,12 @@ export class DeviceListComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.propertyService.subscribe(update => this.devices.forEach(d => d.updateProperty(update.payload)));
|
this.propertyService.subscribe(update => this.devices.forEach(d => d.updateProperty(update.payload)));
|
||||||
|
|
||||||
|
this.deviceService.subscribe(update => this.updateDevice(update.payload, update.existing));
|
||||||
this.deviceService.findAll(devices => this.devices = devices);
|
this.deviceService.findAll(devices => this.devices = devices);
|
||||||
}
|
|
||||||
|
|
||||||
setSwitchState(d: Device, value: boolean): void {
|
this.sceneService.subscribe(update => this.updateScene(update.payload, update.existing));
|
||||||
const device: DeviceSwitch = d as DeviceSwitch;
|
this.sceneService.findAll(scenes => this.scenes = scenes);
|
||||||
if (!device.stateProperty) {
|
|
||||||
throw new Error("Property 'stateProperty' not set for: " + device);
|
|
||||||
}
|
|
||||||
this.propertyService.set(device.stateProperty, "value", value ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
setShutterPosition(d: Device, value: number): void {
|
|
||||||
const device: DeviceShutter = d as DeviceShutter;
|
|
||||||
if (!device.positionProperty) {
|
|
||||||
throw new Error("Property 'positionProperty' not set for: " + device);
|
|
||||||
}
|
|
||||||
this.propertyService.set(device.positionProperty, "value", value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create(): void {
|
create(): void {
|
||||||
@ -66,6 +60,20 @@ export class DeviceListComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private updateScene(scene: Scene, existing: boolean): void {
|
||||||
|
const index: number = this.scenes.findIndex(p => p.id === scene.id);
|
||||||
|
if (index >= 0) {
|
||||||
|
if (existing) {
|
||||||
|
this.scenes[index] = scene;
|
||||||
|
} else {
|
||||||
|
this.scenes.slice(index, 1);
|
||||||
|
}
|
||||||
|
} else if (existing) {
|
||||||
|
this.scenes.push(scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getSwitchClassList(device: Device): object {
|
getSwitchClassList(device: Device): object {
|
||||||
const value: number | null | undefined = (device as DeviceSwitch).stateProperty?.value;
|
const value: number | null | undefined = (device as DeviceSwitch).stateProperty?.value;
|
||||||
return {
|
return {
|
||||||
@ -75,6 +83,10 @@ export class DeviceListComponent implements OnInit {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getStateSceneClassList(device: Device): object {
|
||||||
|
return this.getSwitchClassList(device);
|
||||||
|
}
|
||||||
|
|
||||||
getShutterClassList(device: Device): object {
|
getShutterClassList(device: Device): object {
|
||||||
const value: number | null | undefined = (device as DeviceShutter).positionProperty?.value;
|
const value: number | null | undefined = (device as DeviceShutter).positionProperty?.value;
|
||||||
return {
|
return {
|
||||||
@ -85,4 +97,9 @@ export class DeviceListComponent implements OnInit {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getStateScenes(d: Device): Scene[] {
|
||||||
|
const device: DeviceStateScene = d as DeviceStateScene;
|
||||||
|
return device.sceneNumbers.map(sceneNumber => this.scenes.find(scene => scene.number === sceneNumber)).filter(scene => scene !== undefined).map(s => s as Scene);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,30 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Eigenschaft</th>
|
<th>Eigenschaft</th>
|
||||||
<td>
|
<td>
|
||||||
<app-search [searchService]="propertyService" [initial]="deviceSwitch.stateProperty?.id" [showKey]="true" (valueChange)="setDeviceSwitch('stateProperty', $event)"></app-search>
|
<app-search [searchService]="propertyService" [initial]="deviceSwitch.stateProperty?.id" [showKey]="true" (valueChange)="deviceService.setDeviceSwitch(device,'stateProperty', $event)"></app-search>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="deviceStateScene">
|
||||||
|
<table class="vertical">
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<td>
|
||||||
|
<app-edit-field [initial]="deviceStateScene.title" (valueChange)="set('title', $event)"></app-edit-field>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Status-Eigenschaft</th>
|
||||||
|
<td>
|
||||||
|
<app-search [searchService]="propertyService" [initial]="deviceStateScene.stateProperty?.id" [showKey]="true" (valueChange)="deviceService.setDeviceStateScene(device,'stateProperty', $event)"></app-search>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Szene-Eigenschaft</th>
|
||||||
|
<td>
|
||||||
|
<app-search [searchService]="propertyService" [initial]="deviceStateScene.sceneProperty?.id" [showKey]="true" (valueChange)="deviceService.setDeviceStateScene(device,'sceneProperty', $event)"></app-search>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -30,7 +53,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Eigenschaft</th>
|
<th>Eigenschaft</th>
|
||||||
<td>
|
<td>
|
||||||
<app-search [searchService]="propertyService" [initial]="deviceShutter.positionProperty?.id" [showKey]="true" (valueChange)="setDeviceShutter('positionProperty', $event)"></app-search>
|
<app-search [searchService]="propertyService" [initial]="deviceShutter.positionProperty?.id" [showKey]="true" (valueChange)="deviceService.setDeviceShutter(device,'positionProperty', $event)"></app-search>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core';
|
|||||||
import {ActivatedRoute, Router} from "@angular/router";
|
import {ActivatedRoute, Router} from "@angular/router";
|
||||||
import {DataService} from "../../data.service";
|
import {DataService} from "../../data.service";
|
||||||
import {PropertyService} from "../../api/property/property.service";
|
import {PropertyService} from "../../api/property/property.service";
|
||||||
import {Device, DeviceShutter, DeviceSwitch} from "../../api/device/Device";
|
import {Device, DeviceShutter, DeviceStateScene, DeviceSwitch} from "../../api/device/Device";
|
||||||
import {DeviceService} from "../../api/device/device.service";
|
import {DeviceService} from "../../api/device/device.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -16,6 +16,8 @@ export class DeviceComponent implements OnInit {
|
|||||||
|
|
||||||
deviceSwitch: DeviceSwitch | undefined;
|
deviceSwitch: DeviceSwitch | undefined;
|
||||||
|
|
||||||
|
deviceStateScene: DeviceStateScene | undefined;
|
||||||
|
|
||||||
deviceShutter: DeviceShutter | undefined;
|
deviceShutter: DeviceShutter | undefined;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -39,6 +41,9 @@ export class DeviceComponent implements OnInit {
|
|||||||
case "DeviceSwitch":
|
case "DeviceSwitch":
|
||||||
this.deviceSwitch = device as DeviceSwitch;
|
this.deviceSwitch = device as DeviceSwitch;
|
||||||
break;
|
break;
|
||||||
|
case "DeviceStateScene":
|
||||||
|
this.deviceStateScene = device as DeviceStateScene;
|
||||||
|
break;
|
||||||
case "DeviceShutter":
|
case "DeviceShutter":
|
||||||
this.deviceShutter = device as DeviceShutter;
|
this.deviceShutter = device as DeviceShutter;
|
||||||
break;
|
break;
|
||||||
@ -50,14 +55,6 @@ export class DeviceComponent implements OnInit {
|
|||||||
this.deviceService.set(this.device, key, value, device => this.setDevice(device));
|
this.deviceService.set(this.device, key, value, device => this.setDevice(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
setDeviceSwitch(key: string, value: any): void {
|
|
||||||
this.deviceService.setDeviceSwitch(this.device, key, value, device => this.setDevice(device));
|
|
||||||
}
|
|
||||||
|
|
||||||
setDeviceShutter(key: string, value: any): void {
|
|
||||||
this.deviceService.setDeviceShutter(this.device, key, value, device => this.setDevice(device));
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(): void {
|
delete(): void {
|
||||||
if (confirm(this.getDeviceTypeTitle() + " \"" + this.device.title + "\" wirklich löschen?")) {
|
if (confirm(this.getDeviceTypeTitle() + " \"" + this.device.title + "\" wirklich löschen?")) {
|
||||||
this.deviceService.delete(this.device, () => this.router.navigate(["/DeviceList"]));
|
this.deviceService.delete(this.device, () => this.router.navigate(["/DeviceList"]));
|
||||||
|
|||||||
@ -8,14 +8,14 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr *ngFor="let property of properties.sort(Property.compareTypeThenTitle)">
|
<tr *ngFor="let property of properties.sort(Property.compareTypeThenTitle)">
|
||||||
<td>
|
<td>
|
||||||
<app-edit-field [initial]="property.title" (valueChange)="setProperty(property, 'title', $event)"></app-edit-field>
|
<app-edit-field [initial]="property.title" (valueChange)="edit(property, 'title', $event)"></app-edit-field>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<app-edit-field [initial]="property.name" (valueChange)="setProperty(property, 'name', $event)"></app-edit-field>
|
<app-edit-field [initial]="property.name" (valueChange)="edit(property, 'name', $event)"></app-edit-field>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select [(ngModel)]="property.type" (ngModelChange)="setProperty(property, 'type',property.type)">
|
<select [(ngModel)]="property.type" (ngModelChange)="edit(property, 'type', property.type)">
|
||||||
<option value="SWITCH">Schalter</option>
|
<option value="BOOLEAN">Schalter</option>
|
||||||
<option value="SHUTTER">Rollladen</option>
|
<option value="SHUTTER">Rollladen</option>
|
||||||
<option value="BRIGHTNESS_PERCENT">Helligkeit [%]</option>
|
<option value="BRIGHTNESS_PERCENT">Helligkeit [%]</option>
|
||||||
<option value="COLOR_TEMPERATURE">Farbtermperatur</option>
|
<option value="COLOR_TEMPERATURE">Farbtermperatur</option>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<ng-container *ngIf="property.value !== null">
|
<ng-container *ngIf="property.value !== null">
|
||||||
<td *ngIf="property.type === 'SWITCH'" class="boolean" [class.true]="property.value" [class.false]="!property.value" (click)="setProperty(property, 'value', property.value > 0 ? 0 : 1)">
|
<td *ngIf="property.type === 'BOOLEAN'" class="boolean" [class.true]="property.value" [class.false]="!property.value" (click)="edit(property, 'value', property.value > 0 ? 0 : 1)">
|
||||||
{{property.value ? "An" : "Aus"}}
|
{{property.value ? "An" : "Aus"}}
|
||||||
</td>
|
</td>
|
||||||
<td *ngIf="property.type === 'SHUTTER'" class="number" [class.true]="property.value === 0" [class.false]="property.value === 100" [class.tristate]="0 < property.value && property.value < 100">
|
<td *ngIf="property.type === 'SHUTTER'" class="number" [class.true]="property.value === 0" [class.false]="property.value === 100" [class.tristate]="0 < property.value && property.value < 100">
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
@ -32,12 +32,12 @@ export class PropertyListComponent implements OnInit {
|
|||||||
this.sceneService.subscribe(update => this.updateScene(update.payload, update.existing));
|
this.sceneService.subscribe(update => this.updateScene(update.payload, update.existing));
|
||||||
}
|
}
|
||||||
|
|
||||||
setProperty(property: Property, key: string, value: any): void {
|
edit(property: Property, key: string, value: any): void {
|
||||||
this.propertyService.set(property, key, value, property => this.updateProperty(property, true));
|
this.propertyService.set(property, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
setScene(scene: Scene, key: string, value: any): void {
|
setScene(scene: Scene, key: string, value: any): void {
|
||||||
this.sceneService.set(scene, key, value, scene => this.updateScene(scene, true));
|
this.sceneService.set(scene, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateProperty(property: Property, existing: boolean): void {
|
private updateProperty(property: Property, existing: boolean): void {
|
||||||
|
|||||||
@ -132,7 +132,7 @@
|
|||||||
<td class="empty last"></td>
|
<td class="empty last"></td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<td *ngIf="schedule.property?.type === 'SWITCH'" [class.true]="entry.value" [class.false]="!entry.value" (click)="set(entry, 'value', entry.value > 0 ? 0 : 1)">
|
<td *ngIf="schedule.property?.type === 'BOOLEAN'" [class.true]="entry.value" [class.false]="!entry.value" (click)="set(entry, 'value', entry.value > 0 ? 0 : 1)">
|
||||||
{{entry.value ? "An" : "Aus"}}
|
{{entry.value ? "An" : "Aus"}}
|
||||||
</td>
|
</td>
|
||||||
<td *ngIf="schedule.property?.type === 'SHUTTER'" [class.true]="entry.value === 0" [class.false]="entry.value === 100" [class.tristate]="0 < entry.value && entry.value < 100">
|
<td *ngIf="schedule.property?.type === 'SHUTTER'" [class.true]="entry.value === 0" [class.false]="entry.value === 100" [class.tristate]="0 < entry.value && entry.value < 100">
|
||||||
|
|||||||
@ -10,19 +10,19 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input #input type="text" *ngIf="searching" [(ngModel)]="term" (ngModelChange)="changed()" (keydown)="inputKeyPress($event)" (blur)="blur()">
|
<input #input type="text" *ngIf="searching" [(ngModel)]="term" (ngModelChange)="changed()" (keydown)="inputKeyPress($event)" (focus)="cancelOnBlur=true" (blur)="blur()">
|
||||||
|
|
||||||
<div #resultList *ngIf="searching" class="resultList">
|
<div #resultList *ngIf="searching" class="resultList">
|
||||||
<div *ngIf="allowEmpty" class="result" (click)="select(undefined)">
|
<div *ngIf="allowEmpty" class="result" (mousedown)="dontCancelOnBlur()" (click)="select(undefined)">
|
||||||
-
|
-
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="selected" class="result selected" (click)="select(selected)">
|
<div *ngIf="selected" class="result selected" (mousedown)="dontCancelOnBlur()" (click)="select(selected)">
|
||||||
{{selected.value}}
|
{{selected.value}}
|
||||||
<ng-container *ngIf="showKey">
|
<ng-container *ngIf="showKey">
|
||||||
[{{selected.key}}]
|
[{{selected.key}}]
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
<div *ngFor="let result of results" class="result" (click)="select(result)">
|
<div *ngFor="let result of results" class="result" (mousedown)="dontCancelOnBlur()" (click)="select(result)">
|
||||||
{{result.value}}
|
{{result.value}}
|
||||||
<ng-container *ngIf="showKey">
|
<ng-container *ngIf="showKey">
|
||||||
[{{result.key}}]
|
[{{result.key}}]
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {ISearchService} from "../../api/ISearchService";
|
|||||||
})
|
})
|
||||||
export class SearchComponent<T> implements OnInit {
|
export class SearchComponent<T> implements OnInit {
|
||||||
|
|
||||||
private timeout: number | undefined;
|
private changedTimeout: number | undefined;
|
||||||
|
|
||||||
@ViewChild('input')
|
@ViewChild('input')
|
||||||
input2?: ElementRef;
|
input2?: ElementRef;
|
||||||
@ -43,6 +43,8 @@ export class SearchComponent<T> implements OnInit {
|
|||||||
|
|
||||||
searching: boolean = false;
|
searching: boolean = false;
|
||||||
|
|
||||||
|
cancelOnBlur: boolean = true;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,14 +55,14 @@ export class SearchComponent<T> implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
changed(): void {
|
changed(): void {
|
||||||
this.clearTimeout();
|
this.clearChangedTimeout();
|
||||||
this.timeout = setTimeout(() => this.doSearch(), 400);
|
this.changedTimeout = setTimeout(() => this.doSearch(), 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
private clearTimeout(): void {
|
private clearChangedTimeout(): void {
|
||||||
if (this.timeout) {
|
if (this.changedTimeout) {
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.changedTimeout);
|
||||||
this.timeout = undefined;
|
this.changedTimeout = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,13 +82,13 @@ export class SearchComponent<T> implements OnInit {
|
|||||||
this.doSearch();
|
this.doSearch();
|
||||||
break;
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
this.cancel();
|
this.cancelSearch();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doSearch(): void {
|
doSearch(): void {
|
||||||
this.clearTimeout();
|
this.clearChangedTimeout();
|
||||||
if (!this.term) {
|
if (!this.term) {
|
||||||
this.results = [];
|
this.results = [];
|
||||||
} else {
|
} else {
|
||||||
@ -95,13 +97,19 @@ export class SearchComponent<T> implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
blur() {
|
blur() {
|
||||||
setTimeout(() => this.cancel(), 100);
|
if (this.cancelOnBlur) {
|
||||||
|
this.cancelSearch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel(): void {
|
cancelSearch(): void {
|
||||||
this.searching = false;
|
this.searching = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dontCancelOnBlur(): void {
|
||||||
|
this.cancelOnBlur = false;
|
||||||
|
}
|
||||||
|
|
||||||
select(result: KeyValuePair | undefined): void {
|
select(result: KeyValuePair | undefined): void {
|
||||||
this.searching = false;
|
this.searching = false;
|
||||||
this.selected = result;
|
this.selected = result;
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Angular</title>
|
<title>Angular</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=scene-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import de.ph87.homeautomation.knx.group.KnxGroupReadService;
|
|||||||
import de.ph87.homeautomation.property.Property;
|
import de.ph87.homeautomation.property.Property;
|
||||||
import de.ph87.homeautomation.property.PropertyRepository;
|
import de.ph87.homeautomation.property.PropertyRepository;
|
||||||
import de.ph87.homeautomation.property.PropertyType;
|
import de.ph87.homeautomation.property.PropertyType;
|
||||||
|
import de.ph87.homeautomation.scene.SceneDto;
|
||||||
import de.ph87.homeautomation.scene.SceneRepository;
|
import de.ph87.homeautomation.scene.SceneRepository;
|
||||||
import de.ph87.homeautomation.scene.SceneWriteService;
|
import de.ph87.homeautomation.scene.SceneWriteService;
|
||||||
import de.ph87.homeautomation.schedule.Schedule;
|
import de.ph87.homeautomation.schedule.Schedule;
|
||||||
@ -48,16 +49,21 @@ public class DemoDataService {
|
|||||||
private final SceneWriteService sceneWriteService;
|
private final SceneWriteService sceneWriteService;
|
||||||
|
|
||||||
public void insertDemoData() {
|
public void insertDemoData() {
|
||||||
final Property fernseher = createProperty("fernseher.eg", PropertyType.SWITCH, "Fernseher", knx(0, 0, 20), knx(0, 0, 4));
|
final Property eg = createProperty("eg.status", PropertyType.BOOLEAN, "Erdgeschoss", knx(0, 4, 2), null);
|
||||||
final Property verstaerker = createProperty("verstaerker", PropertyType.SWITCH, "Verstärker", knx(0, 3, 57), knx(0, 3, 56));
|
final Property eg_szene = createProperty("eg.szene", PropertyType.SCENE, "Erdgeschoss Szene", null, knx(0, 0, 1));
|
||||||
final Property garten_steckdosen = createProperty("garten.steckdosen", PropertyType.SWITCH, "Garten Steckdosen", knx(0, 4, 12), knx(0, 4, 11));
|
final Property og = createProperty("og.status", PropertyType.BOOLEAN, "Obergeschoss", knx(0, 6, 6), null);
|
||||||
final Property terrasse = createProperty("terrasse", PropertyType.SWITCH, "Terrasse Licht", knx(0, 4, 1), knx(0, 4, 0));
|
final Property og_szene = createProperty("og.szene", PropertyType.SCENE, "Obergeschoss Szene", null, knx(0, 3, 2));
|
||||||
|
|
||||||
final Property ambiente_eg = createProperty("ambiente.eg", PropertyType.SWITCH, "Ambiente EG", knx(0, 3, 81), knx(0, 3, 80));
|
final Property fernseher = createProperty("fernseher.eg", PropertyType.BOOLEAN, "Fernseher", knx(0, 0, 20), knx(0, 0, 4));
|
||||||
final Property ambiente_og = createProperty("ambiente.og", PropertyType.SWITCH, "Ambiente OG", knx(0, 6, 2), knx(0, 6, 3));
|
final Property verstaerker = createProperty("verstaerker", PropertyType.BOOLEAN, "Verstärker", knx(0, 3, 57), knx(0, 3, 56));
|
||||||
|
final Property garten_steckdosen = createProperty("garten.steckdosen", PropertyType.BOOLEAN, "Garten Steckdosen", knx(0, 4, 12), knx(0, 4, 11));
|
||||||
|
final Property terrasse = createProperty("terrasse", PropertyType.BOOLEAN, "Terrasse Licht", knx(0, 4, 1), knx(0, 4, 0));
|
||||||
|
|
||||||
final Property bad_licht = createProperty("bad.licht", PropertyType.SWITCH, "Bad Licht", knx(0, 5, 19), knx(0, 3, 73));
|
final Property ambiente_eg = createProperty("ambiente.eg", PropertyType.BOOLEAN, "Ambiente EG", knx(0, 3, 81), knx(0, 3, 80));
|
||||||
final Property flur_eg_licht = createProperty("flur.eg.licht", PropertyType.SWITCH, "Flur EG Licht", knx(0, 4, 8), knx(0, 5, 14));
|
final Property ambiente_og = createProperty("ambiente.og", PropertyType.BOOLEAN, "Ambiente OG", knx(0, 6, 2), knx(0, 6, 3));
|
||||||
|
|
||||||
|
final Property bad_licht = createProperty("bad.licht", PropertyType.BOOLEAN, "Bad Licht", knx(0, 5, 19), knx(0, 3, 73));
|
||||||
|
final Property flur_eg_licht = createProperty("flur.eg.licht", PropertyType.BOOLEAN, "Flur EG Licht", knx(0, 4, 8), knx(0, 5, 14));
|
||||||
|
|
||||||
final Property wohnzimmer_rollladen = createProperty("wohnzimmer.rollladen", PropertyType.SHUTTER, "Wohnzimmer Rollladen", null, knx(0, 4, 24));
|
final Property wohnzimmer_rollladen = createProperty("wohnzimmer.rollladen", PropertyType.SHUTTER, "Wohnzimmer Rollladen", null, knx(0, 4, 24));
|
||||||
final Property schlafzimmer_rollladen = createProperty("schlafzimmer_rollladen", PropertyType.SHUTTER, "Schlafzimmer Rollladen", null, knx(0, 3, 3));
|
final Property schlafzimmer_rollladen = createProperty("schlafzimmer_rollladen", PropertyType.SHUTTER, "Schlafzimmer Rollladen", null, knx(0, 3, 3));
|
||||||
@ -66,7 +72,16 @@ public class DemoDataService {
|
|||||||
final Property helligkeit = createProperty("helligkeit", PropertyType.LUX, "Helligkeit", knx(0, 5, 6), null);
|
final Property helligkeit = createProperty("helligkeit", PropertyType.LUX, "Helligkeit", knx(0, 5, 6), null);
|
||||||
final Property szene_haus = createProperty("szene_haus", PropertyType.SCENE, "Szene Haus ", null, knx(0, 0, 21));
|
final Property szene_haus = createProperty("szene_haus", PropertyType.SCENE, "Szene Haus ", null, knx(0, 0, 21));
|
||||||
|
|
||||||
|
if (sceneRepository.count() == 0) {
|
||||||
|
final SceneDto alles_aus = sceneWriteService.create(1, "Alles AUS");
|
||||||
|
final SceneDto nachtlicht = sceneWriteService.create(2, "Nachtlicht");
|
||||||
|
final SceneDto dekoration_aus = sceneWriteService.create(30, "Dekoration AUS");
|
||||||
|
final SceneDto dekoration_an = sceneWriteService.create(31, "Dekoration AN");
|
||||||
|
|
||||||
if (deviceRepository.count() == 0) {
|
if (deviceRepository.count() == 0) {
|
||||||
|
deviceWriteService.createDeviceStateScene(eg, eg_szene, alles_aus);
|
||||||
|
deviceWriteService.createDeviceStateScene(og, og_szene, alles_aus);
|
||||||
|
|
||||||
deviceWriteService.createDeviceSwitch(fernseher);
|
deviceWriteService.createDeviceSwitch(fernseher);
|
||||||
deviceWriteService.createDeviceSwitch(verstaerker);
|
deviceWriteService.createDeviceSwitch(verstaerker);
|
||||||
deviceWriteService.createDeviceSwitch(garten_steckdosen);
|
deviceWriteService.createDeviceSwitch(garten_steckdosen);
|
||||||
@ -82,12 +97,6 @@ public class DemoDataService {
|
|||||||
deviceWriteService.createDeviceShutter(schlafzimmer_rollladen);
|
deviceWriteService.createDeviceShutter(schlafzimmer_rollladen);
|
||||||
deviceWriteService.createDeviceShutter(flur_og_rollladen);
|
deviceWriteService.createDeviceShutter(flur_og_rollladen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sceneRepository.count() == 0) {
|
|
||||||
sceneWriteService.create(1, "Alles AUS");
|
|
||||||
sceneWriteService.create(2, "Nachtlicht");
|
|
||||||
sceneWriteService.create(30, "Dekoration AUS");
|
|
||||||
sceneWriteService.create(31, "Dekoration AN");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scheduleRepository.count() == 0) {
|
if (scheduleRepository.count() == 0) {
|
||||||
|
|||||||
@ -56,6 +56,16 @@ public class DeviceController {
|
|||||||
return deviceWriteService.setDeviceSwitch(id, (device, v) -> device.setStateProperty(mapIfNotNull(v, propertyReadService::getByName)), name);
|
return deviceWriteService.setDeviceSwitch(id, (device, v) -> device.setStateProperty(mapIfNotNull(v, propertyReadService::getByName)), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("set/{id}/DeviceStateScene/stateProperty")
|
||||||
|
public DeviceDto setDeviceStateSceneStateProperty(@PathVariable final long id, @RequestBody(required = false) final String name) {
|
||||||
|
return deviceWriteService.setDeviceStateScene(id, (device, v) -> device.setStateProperty(mapIfNotNull(v, propertyReadService::getByName)), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("set/{id}/DeviceStateScene/sceneProperty")
|
||||||
|
public DeviceDto setDeviceStateSceneSceneProperty(@PathVariable final long id, @RequestBody(required = false) final String name) {
|
||||||
|
return deviceWriteService.setDeviceStateScene(id, (device, v) -> device.setSceneProperty(mapIfNotNull(v, propertyReadService::getByName)), name);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("set/{id}/DeviceShutter/positionProperty")
|
@PostMapping("set/{id}/DeviceShutter/positionProperty")
|
||||||
public DeviceDto setDeviceShutterPositionProperty(@PathVariable final long id, @RequestBody(required = false) final String name) {
|
public DeviceDto setDeviceShutterPositionProperty(@PathVariable final long id, @RequestBody(required = false) final String name) {
|
||||||
return deviceWriteService.setDeviceShutter(id, (device, v) -> device.setPositionProperty(mapIfNotNull(v, propertyReadService::getByName)), name);
|
return deviceWriteService.setDeviceShutter(id, (device, v) -> device.setPositionProperty(mapIfNotNull(v, propertyReadService::getByName)), name);
|
||||||
|
|||||||
@ -31,6 +31,9 @@ public class DeviceReadService {
|
|||||||
if (device instanceof DeviceSwitch) {
|
if (device instanceof DeviceSwitch) {
|
||||||
final DeviceSwitch deviceSwitch = (DeviceSwitch) device;
|
final DeviceSwitch deviceSwitch = (DeviceSwitch) device;
|
||||||
return new DeviceSwitchDto(deviceSwitch, mapIfNotNull(deviceSwitch.getStateProperty(), propertyMapper::toDto));
|
return new DeviceSwitchDto(deviceSwitch, mapIfNotNull(deviceSwitch.getStateProperty(), propertyMapper::toDto));
|
||||||
|
} else if (device instanceof DeviceStateScene) {
|
||||||
|
final DeviceStateScene deviceStateScene = (DeviceStateScene) device;
|
||||||
|
return new DeviceStateSceneDto(deviceStateScene, mapIfNotNull(deviceStateScene.getStateProperty(), propertyMapper::toDto), mapIfNotNull(deviceStateScene.getSceneProperty(), propertyMapper::toDto));
|
||||||
} else if (device instanceof DeviceShutter) {
|
} else if (device instanceof DeviceShutter) {
|
||||||
final DeviceShutter deviceShutter = (DeviceShutter) device;
|
final DeviceShutter deviceShutter = (DeviceShutter) device;
|
||||||
return new DeviceShutterDto(deviceShutter, mapIfNotNull(deviceShutter.getPositionProperty(), propertyMapper::toDto));
|
return new DeviceShutterDto(deviceShutter, mapIfNotNull(deviceShutter.getPositionProperty(), propertyMapper::toDto));
|
||||||
|
|||||||
@ -1,18 +1,19 @@
|
|||||||
package de.ph87.homeautomation.device;
|
package de.ph87.homeautomation.device;
|
||||||
|
|
||||||
import de.ph87.homeautomation.device.devices.Device;
|
import de.ph87.homeautomation.device.devices.*;
|
||||||
import de.ph87.homeautomation.device.devices.DeviceDto;
|
|
||||||
import de.ph87.homeautomation.device.devices.DeviceShutter;
|
|
||||||
import de.ph87.homeautomation.device.devices.DeviceSwitch;
|
|
||||||
import de.ph87.homeautomation.property.Property;
|
import de.ph87.homeautomation.property.Property;
|
||||||
|
import de.ph87.homeautomation.scene.SceneDto;
|
||||||
import de.ph87.homeautomation.schedule.ScheduleWriteService;
|
import de.ph87.homeautomation.schedule.ScheduleWriteService;
|
||||||
import de.ph87.homeautomation.web.BadRequestException;
|
import de.ph87.homeautomation.web.BadRequestException;
|
||||||
|
import de.ph87.homeautomation.web.WebSocketService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -24,6 +25,8 @@ public class DeviceWriteService {
|
|||||||
|
|
||||||
private final DeviceReadService deviceReadService;
|
private final DeviceReadService deviceReadService;
|
||||||
|
|
||||||
|
private final WebSocketService webSocketService;
|
||||||
|
|
||||||
public DeviceDto createDeviceSwitch(final Property stateProperty) {
|
public DeviceDto createDeviceSwitch(final Property stateProperty) {
|
||||||
return createDeviceSwitch(null, stateProperty);
|
return createDeviceSwitch(null, stateProperty);
|
||||||
}
|
}
|
||||||
@ -33,7 +36,7 @@ public class DeviceWriteService {
|
|||||||
deviceSwitch.setTitle(getTitle(title, stateProperty));
|
deviceSwitch.setTitle(getTitle(title, stateProperty));
|
||||||
deviceSwitch.setStateProperty(stateProperty);
|
deviceSwitch.setStateProperty(stateProperty);
|
||||||
deviceRepository.save(deviceSwitch);
|
deviceRepository.save(deviceSwitch);
|
||||||
return deviceReadService.toDto(deviceSwitch);
|
return publish(deviceSwitch, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceDto createDeviceShutter(final Property positionProperty) {
|
public DeviceDto createDeviceShutter(final Property positionProperty) {
|
||||||
@ -45,13 +48,27 @@ public class DeviceWriteService {
|
|||||||
deviceShutter.setTitle(getTitle(title, positionProperty));
|
deviceShutter.setTitle(getTitle(title, positionProperty));
|
||||||
deviceShutter.setPositionProperty(positionProperty);
|
deviceShutter.setPositionProperty(positionProperty);
|
||||||
deviceRepository.save(deviceShutter);
|
deviceRepository.save(deviceShutter);
|
||||||
return deviceReadService.toDto(deviceShutter);
|
return publish(deviceShutter, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceDto createDeviceStateScene(final Property stateProperty, final Property sceneProperty, final SceneDto... scenes) {
|
||||||
|
return createDeviceStateScene(null, stateProperty, sceneProperty, scenes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceDto createDeviceStateScene(final String title, final Property stateProperty, final Property sceneProperty, final SceneDto... scenes) {
|
||||||
|
final DeviceStateScene deviceStateScene = new DeviceStateScene();
|
||||||
|
deviceStateScene.setTitle(getTitle(title, stateProperty));
|
||||||
|
deviceStateScene.setStateProperty(stateProperty);
|
||||||
|
deviceStateScene.setSceneProperty(sceneProperty);
|
||||||
|
deviceStateScene.setSceneNumbers(Arrays.stream(scenes).map(SceneDto::getNumber).collect(Collectors.toList()));
|
||||||
|
deviceRepository.save(deviceStateScene);
|
||||||
|
return publish(deviceStateScene, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> DeviceDto set(final long id, final BiConsumer<Device, T> setter, final T value) {
|
public <T> DeviceDto set(final long id, final BiConsumer<Device, T> setter, final T value) {
|
||||||
final Device device = deviceReadService.getById(id);
|
final Device device = deviceReadService.getById(id);
|
||||||
setter.accept(device, value);
|
setter.accept(device, value);
|
||||||
return deviceReadService.toDto(device);
|
return publish(device, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> DeviceDto setDeviceSwitch(final long id, final BiConsumer<DeviceSwitch, T> setter, final T value) {
|
public <T> DeviceDto setDeviceSwitch(final long id, final BiConsumer<DeviceSwitch, T> setter, final T value) {
|
||||||
@ -60,7 +77,16 @@ public class DeviceWriteService {
|
|||||||
throw new BadRequestException("Not a DeviceSwitch: %s", device);
|
throw new BadRequestException("Not a DeviceSwitch: %s", device);
|
||||||
}
|
}
|
||||||
setter.accept((DeviceSwitch) device, value);
|
setter.accept((DeviceSwitch) device, value);
|
||||||
return deviceReadService.toDto(device);
|
return publish(device, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> DeviceDto setDeviceStateScene(final long id, final BiConsumer<DeviceStateScene, T> setter, final T value) {
|
||||||
|
final Device device = deviceReadService.getById(id);
|
||||||
|
if (!(device instanceof DeviceStateScene)) {
|
||||||
|
throw new BadRequestException("Not a DeviceStateScene: %s", device);
|
||||||
|
}
|
||||||
|
setter.accept((DeviceStateScene) device, value);
|
||||||
|
return publish(device, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> DeviceDto setDeviceShutter(final long id, final BiConsumer<DeviceShutter, T> setter, final T value) {
|
public <T> DeviceDto setDeviceShutter(final long id, final BiConsumer<DeviceShutter, T> setter, final T value) {
|
||||||
@ -69,14 +95,20 @@ public class DeviceWriteService {
|
|||||||
throw new BadRequestException("Not a DeviceShutter: %s", device);
|
throw new BadRequestException("Not a DeviceShutter: %s", device);
|
||||||
}
|
}
|
||||||
setter.accept((DeviceShutter) device, value);
|
setter.accept((DeviceShutter) device, value);
|
||||||
return deviceReadService.toDto(device);
|
return publish(device, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(final long id) {
|
public void delete(final long id) {
|
||||||
deviceRepository.deleteById(id);
|
final Device device = deviceReadService.getById(id);
|
||||||
|
deviceRepository.delete(device);
|
||||||
|
publish(device, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceDto create(final String type) {
|
public DeviceDto create(final String type) {
|
||||||
|
return publish(create2(type), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeviceDto create2(final String type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "DeviceSwitch":
|
case "DeviceSwitch":
|
||||||
return createDeviceSwitch(null, null);
|
return createDeviceSwitch(null, null);
|
||||||
@ -86,6 +118,15 @@ public class DeviceWriteService {
|
|||||||
throw new RuntimeException("Not implemented type: " + type);
|
throw new RuntimeException("Not implemented type: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DeviceDto publish(final Device device, final boolean existing) {
|
||||||
|
return publish(deviceReadService.toDto(device), existing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeviceDto publish(final DeviceDto dto, final boolean existing) {
|
||||||
|
webSocketService.send(dto, existing);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
private String getTitle(final String title, final Property property) {
|
private String getTitle(final String title, final Property property) {
|
||||||
if (title != null) {
|
if (title != null) {
|
||||||
return title;
|
return title;
|
||||||
|
|||||||
@ -2,8 +2,10 @@ package de.ph87.homeautomation.device.devices;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public abstract class DeviceDto {
|
public abstract class DeviceDto implements Serializable {
|
||||||
|
|
||||||
public final long id;
|
public final long id;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
package de.ph87.homeautomation.device.devices;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.property.Property;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@Entity
|
||||||
|
public class DeviceStateScene extends Device {
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Property stateProperty;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Property sceneProperty;
|
||||||
|
|
||||||
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
|
private List<Integer> sceneNumbers = new ArrayList<>();
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package de.ph87.homeautomation.device.devices;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.property.PropertyDto;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class DeviceStateSceneDto extends DeviceDto {
|
||||||
|
|
||||||
|
public final PropertyDto stateProperty;
|
||||||
|
|
||||||
|
public final PropertyDto sceneProperty;
|
||||||
|
|
||||||
|
public final List<Integer> sceneNumbers;
|
||||||
|
|
||||||
|
public DeviceStateSceneDto(final DeviceStateScene device, final PropertyDto stateProperty, final PropertyDto sceneProperty) {
|
||||||
|
super(device);
|
||||||
|
this.stateProperty = stateProperty;
|
||||||
|
this.sceneProperty = sceneProperty;
|
||||||
|
this.sceneNumbers = device.getSceneNumbers();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package de.ph87.homeautomation.knx.group;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class KnxGroupDto implements Serializable {
|
||||||
|
|
||||||
|
public final int addressRaw;
|
||||||
|
|
||||||
|
public final String addressStr;
|
||||||
|
|
||||||
|
public final int dptMain;
|
||||||
|
|
||||||
|
public final int dptSub;
|
||||||
|
|
||||||
|
public final String name;
|
||||||
|
|
||||||
|
public final String description;
|
||||||
|
|
||||||
|
public final int puid;
|
||||||
|
|
||||||
|
public final boolean ets;
|
||||||
|
|
||||||
|
public final KnxTelegram lastTelegram;
|
||||||
|
|
||||||
|
public final Double value;
|
||||||
|
|
||||||
|
public final ZonedDateTime timestamp;
|
||||||
|
|
||||||
|
public final KnxGroupLinkInfo read;
|
||||||
|
|
||||||
|
public final byte[] sendValue;
|
||||||
|
|
||||||
|
public final KnxGroupLinkInfo send;
|
||||||
|
|
||||||
|
public KnxGroupDto(final KnxGroup knxGroup) {
|
||||||
|
this.addressRaw = knxGroup.getAddressRaw();
|
||||||
|
this.addressStr = knxGroup.getAddressStr();
|
||||||
|
this.dptMain = knxGroup.getDptMain();
|
||||||
|
this.dptSub = knxGroup.getDptSub();
|
||||||
|
this.name = knxGroup.getName();
|
||||||
|
this.description = knxGroup.getDescription();
|
||||||
|
this.puid = knxGroup.getPuid();
|
||||||
|
this.ets = knxGroup.isEts();
|
||||||
|
this.lastTelegram = knxGroup.getLastTelegram();
|
||||||
|
this.value = knxGroup.getValue();
|
||||||
|
this.timestamp = knxGroup.getTimestamp();
|
||||||
|
this.read = knxGroup.getRead();
|
||||||
|
this.sendValue = knxGroup.getSendValue();
|
||||||
|
this.send = knxGroup.getSend();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package de.ph87.homeautomation.knx.group;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class KnxGroupMapper {
|
||||||
|
|
||||||
|
public KnxGroupDto toDto(final KnxGroup knxGroup) {
|
||||||
|
return new KnxGroupDto(knxGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
package de.ph87.homeautomation.knx.group;
|
package de.ph87.homeautomation.knx.group;
|
||||||
|
|
||||||
import de.ph87.homeautomation.channel.ChannelChangedEvent;
|
import de.ph87.homeautomation.channel.ChannelChangedEvent;
|
||||||
|
import de.ph87.homeautomation.web.WebSocketService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
@ -26,6 +27,10 @@ public class KnxGroupWriteService {
|
|||||||
|
|
||||||
private final ApplicationEventPublisher applicationEventPublisher;
|
private final ApplicationEventPublisher applicationEventPublisher;
|
||||||
|
|
||||||
|
private final WebSocketService webSocketService;
|
||||||
|
|
||||||
|
private final KnxGroupMapper knxGroupMapper;
|
||||||
|
|
||||||
public void requestRead(final KnxGroup knxGroup) {
|
public void requestRead(final KnxGroup knxGroup) {
|
||||||
knxGroup.getRead().setNextTimestamp(ZonedDateTime.now());
|
knxGroup.getRead().setNextTimestamp(ZonedDateTime.now());
|
||||||
log.debug("Requesting read for KnxGroup: {}", knxGroup);
|
log.debug("Requesting read for KnxGroup: {}", knxGroup);
|
||||||
@ -39,11 +44,14 @@ public class KnxGroupWriteService {
|
|||||||
((DPTXlatorBoolean) translator).setValue(value == 1.0);
|
((DPTXlatorBoolean) translator).setValue(value == 1.0);
|
||||||
} else if (translator instanceof DPTXlator8BitUnsigned) {
|
} else if (translator instanceof DPTXlator8BitUnsigned) {
|
||||||
((DPTXlator8BitUnsigned) translator).setValue((int) value);
|
((DPTXlator8BitUnsigned) translator).setValue((int) value);
|
||||||
|
} else if (translator instanceof DPTXlatorSceneNumber) {
|
||||||
|
((DPTXlatorSceneNumber) translator).setValue((int) value - 1);
|
||||||
} else { // TODO implement all DPTXlator...
|
} else { // TODO implement all DPTXlator...
|
||||||
translator.setValue("" + value);
|
translator.setValue("" + value);
|
||||||
}
|
}
|
||||||
knxGroup.getSend().setNextTimestamp(ZonedDateTime.now());
|
knxGroup.getSend().setNextTimestamp(ZonedDateTime.now());
|
||||||
knxGroup.setSendValue(translator.getData());
|
knxGroup.setSendValue(translator.getData());
|
||||||
|
publish(knxGroup);
|
||||||
sendThreadWakeUpEvent();
|
sendThreadWakeUpEvent();
|
||||||
} catch (KNXFormatException e) {
|
} catch (KNXFormatException e) {
|
||||||
log.error("Failed set value \"{}\" to DptXlator {} for KnxGroup {}", value, translator, knxGroup);
|
log.error("Failed set value \"{}\" to DptXlator {} for KnxGroup {}", value, translator, knxGroup);
|
||||||
@ -84,6 +92,7 @@ public class KnxGroupWriteService {
|
|||||||
knxGroup.setValue(valueOptional.get());
|
knxGroup.setValue(valueOptional.get());
|
||||||
knxGroup.setTimestamp(ZonedDateTime.now());
|
knxGroup.setTimestamp(ZonedDateTime.now());
|
||||||
log.debug("KnxGroup updated: {}", knxGroup);
|
log.debug("KnxGroup updated: {}", knxGroup);
|
||||||
|
publish(knxGroup);
|
||||||
applicationEventPublisher.publishEvent(new ChannelChangedEvent(knxGroup));
|
applicationEventPublisher.publishEvent(new ChannelChangedEvent(knxGroup));
|
||||||
} else {
|
} else {
|
||||||
log.error("Failed to get value from DptXlator {} for KnxGroup {}", translator, knxGroup);
|
log.error("Failed to get value from DptXlator {} for KnxGroup {}", translator, knxGroup);
|
||||||
@ -109,4 +118,10 @@ public class KnxGroupWriteService {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private KnxGroupDto publish(final KnxGroup knxGroup) {
|
||||||
|
final KnxGroupDto dto = knxGroupMapper.toDto(knxGroup);
|
||||||
|
webSocketService.send(dto, true);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,11 @@ public class PropertyController implements ISearchController {
|
|||||||
return propertyWriteService.set(id, Property::setName, propertyName);
|
return propertyWriteService.set(id, Property::setName, propertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("set/{id}/title")
|
||||||
|
public PropertyDto setPropertyTitle(@PathVariable final long id, @RequestBody final String propertyTitle) {
|
||||||
|
return propertyWriteService.set(id, Property::setTitle, propertyTitle);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("set/{id}/value")
|
@PostMapping("set/{id}/value")
|
||||||
public PropertyDto setValue(@PathVariable final long id, @RequestBody final double value) {
|
public PropertyDto setValue(@PathVariable final long id, @RequestBody final double value) {
|
||||||
return propertyWriteService.set(id, propertyWriteService::write, value);
|
return propertyWriteService.set(id, propertyWriteService::write, value);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
package de.ph87.homeautomation.property;
|
package de.ph87.homeautomation.property;
|
||||||
|
|
||||||
public enum PropertyType {
|
public enum PropertyType {
|
||||||
SWITCH, SHUTTER, BRIGHTNESS_PERCENT, COLOR_TEMPERATURE, LUX, SCENE
|
BOOLEAN, SHUTTER, BRIGHTNESS_PERCENT, COLOR_TEMPERATURE, LUX, SCENE
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,7 @@ public class PropertyWriteService {
|
|||||||
property.setValue(property.getReadChannel().getValue());
|
property.setValue(property.getReadChannel().getValue());
|
||||||
property.setTimestamp(property.getReadChannel().getTimestamp());
|
property.setTimestamp(property.getReadChannel().getTimestamp());
|
||||||
log.debug("Updated Property from Channel: {}", property);
|
log.debug("Updated Property from Channel: {}", property);
|
||||||
webSocketService.send(propertyMapper.toDto(property), true);
|
publish(property, true);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ public class PropertyWriteService {
|
|||||||
public PropertyDto create() {
|
public PropertyDto create() {
|
||||||
final Property entry = new Property();
|
final Property entry = new Property();
|
||||||
entry.setTitle(generateUnusedName());
|
entry.setTitle(generateUnusedName());
|
||||||
return propertyMapper.toDto(propertyRepository.save(entry));
|
return publish(propertyRepository.save(entry), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateUnusedName() {
|
private String generateUnusedName() {
|
||||||
@ -68,11 +68,19 @@ public class PropertyWriteService {
|
|||||||
public <T> PropertyDto set(final long id, final BiConsumer<Property, T> setter, final T value) {
|
public <T> PropertyDto set(final long id, final BiConsumer<Property, T> setter, final T value) {
|
||||||
final Property property = propertyReadService.getById(id);
|
final Property property = propertyReadService.getById(id);
|
||||||
setter.accept(property, value);
|
setter.accept(property, value);
|
||||||
return propertyMapper.toDto(property);
|
return publish(property, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(final long id) {
|
public void delete(final long id) {
|
||||||
propertyRepository.deleteById(id);
|
final Property property = propertyReadService.getById(id);
|
||||||
|
propertyRepository.delete(property);
|
||||||
|
publish(property, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PropertyDto publish(final Property property, final boolean existing) {
|
||||||
|
final PropertyDto dto = propertyMapper.toDto(property);
|
||||||
|
webSocketService.send(dto, existing);
|
||||||
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,8 +2,10 @@ package de.ph87.homeautomation.scene;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class SceneDto {
|
public class SceneDto implements Serializable {
|
||||||
|
|
||||||
public final long id;
|
public final long id;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package de.ph87.homeautomation.scene;
|
package de.ph87.homeautomation.scene;
|
||||||
|
|
||||||
import de.ph87.homeautomation.schedule.ScheduleWriteService;
|
import de.ph87.homeautomation.schedule.ScheduleWriteService;
|
||||||
|
import de.ph87.homeautomation.web.WebSocketService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -22,18 +23,29 @@ public class SceneWriteService {
|
|||||||
|
|
||||||
private final SceneMapper sceneMapper;
|
private final SceneMapper sceneMapper;
|
||||||
|
|
||||||
|
private final WebSocketService webSocketService;
|
||||||
|
|
||||||
public <T> SceneDto set(final long id, final BiConsumer<Scene, T> setter, final T value) {
|
public <T> SceneDto set(final long id, final BiConsumer<Scene, T> setter, final T value) {
|
||||||
final Scene scene = sceneReadService.getById(id);
|
final Scene scene = sceneReadService.getById(id);
|
||||||
setter.accept(scene, value);
|
setter.accept(scene, value);
|
||||||
return sceneMapper.toDto(scene);
|
return publish(scene, true);
|
||||||
}
|
|
||||||
|
|
||||||
public void delete(final long id) {
|
|
||||||
sceneRepository.deleteById(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SceneDto create(final int number, final String title) {
|
public SceneDto create(final int number, final String title) {
|
||||||
return sceneMapper.toDto(sceneRepository.save(new Scene(number, orElseGet(title, this::generateUnusedTitle))));
|
final Scene scene = sceneRepository.save(new Scene(number, orElseGet(title, this::generateUnusedTitle)));
|
||||||
|
return publish(scene, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(final long id) {
|
||||||
|
final Scene scene = sceneReadService.getById(id);
|
||||||
|
sceneRepository.delete(scene);
|
||||||
|
publish(scene, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SceneDto publish(final Scene scene, final boolean existing) {
|
||||||
|
final SceneDto dto = sceneMapper.toDto(scene);
|
||||||
|
webSocketService.send(dto, existing);
|
||||||
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateUnusedTitle() {
|
private String generateUnusedTitle() {
|
||||||
|
|||||||
@ -4,11 +4,12 @@ import de.ph87.homeautomation.property.PropertyDto;
|
|||||||
import de.ph87.homeautomation.schedule.entry.ScheduleEntryDto;
|
import de.ph87.homeautomation.schedule.entry.ScheduleEntryDto;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class ScheduleDto {
|
public class ScheduleDto implements Serializable {
|
||||||
|
|
||||||
public final long id;
|
public final long id;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package de.ph87.homeautomation.schedule;
|
package de.ph87.homeautomation.schedule;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.web.WebSocketService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -24,10 +25,12 @@ public class ScheduleWriteService {
|
|||||||
|
|
||||||
private final ScheduleRepository scheduleRepository;
|
private final ScheduleRepository scheduleRepository;
|
||||||
|
|
||||||
|
private final WebSocketService webSocketService;
|
||||||
|
|
||||||
public ScheduleDto create() {
|
public ScheduleDto create() {
|
||||||
final Schedule entry = new Schedule();
|
final Schedule entry = new Schedule();
|
||||||
entry.setTitle(generateUnusedName());
|
entry.setTitle(generateUnusedName());
|
||||||
return scheduleMapper.toDto(scheduleRepository.save(entry));
|
return publish(scheduleRepository.save(entry), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateUnusedName() {
|
private String generateUnusedName() {
|
||||||
@ -43,11 +46,19 @@ public class ScheduleWriteService {
|
|||||||
final Schedule schedule = scheduleReadService.getById(id);
|
final Schedule schedule = scheduleReadService.getById(id);
|
||||||
setter.accept(schedule, value);
|
setter.accept(schedule, value);
|
||||||
scheduleCalculationService.calculateSchedule(schedule, ZonedDateTime.now());
|
scheduleCalculationService.calculateSchedule(schedule, ZonedDateTime.now());
|
||||||
return scheduleMapper.toDto(schedule);
|
return publish(schedule, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(final long id) {
|
public void delete(final long id) {
|
||||||
scheduleRepository.deleteById(id);
|
final Schedule schedule = scheduleReadService.getById(id);
|
||||||
|
scheduleRepository.delete(schedule);
|
||||||
|
publish(schedule, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScheduleDto publish(final Schedule schedule, final boolean existing) {
|
||||||
|
final ScheduleDto dto = scheduleMapper.toDto(schedule);
|
||||||
|
webSocketService.send(dto, existing);
|
||||||
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,10 +2,11 @@ package de.ph87.homeautomation.schedule.entry;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class ScheduleEntryDto {
|
public class ScheduleEntryDto implements Serializable {
|
||||||
|
|
||||||
public final long id;
|
public final long id;
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package de.ph87.homeautomation.schedule.entry;
|
|||||||
import de.ph87.homeautomation.schedule.Schedule;
|
import de.ph87.homeautomation.schedule.Schedule;
|
||||||
import de.ph87.homeautomation.schedule.ScheduleCalculationService;
|
import de.ph87.homeautomation.schedule.ScheduleCalculationService;
|
||||||
import de.ph87.homeautomation.schedule.ScheduleReadService;
|
import de.ph87.homeautomation.schedule.ScheduleReadService;
|
||||||
|
import de.ph87.homeautomation.web.WebSocketService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -27,25 +28,34 @@ public class ScheduleEntryWriteService {
|
|||||||
|
|
||||||
private final ScheduleEntryRepository scheduleEntryRepository;
|
private final ScheduleEntryRepository scheduleEntryRepository;
|
||||||
|
|
||||||
|
private final WebSocketService webSocketService;
|
||||||
|
|
||||||
public <T> ScheduleEntryDto set(final long id, final BiConsumer<ScheduleEntry, T> setter, final T value) {
|
public <T> ScheduleEntryDto set(final long id, final BiConsumer<ScheduleEntry, T> setter, final T value) {
|
||||||
final ScheduleEntry entry = scheduleEntryReadService.getById(id);
|
final ScheduleEntry entry = scheduleEntryReadService.getById(id);
|
||||||
setter.accept(entry, value);
|
setter.accept(entry, value);
|
||||||
final Schedule schedule = scheduleReadService.getByEntry(entry);
|
final Schedule schedule = scheduleReadService.getByEntry(entry);
|
||||||
scheduleCalculationService.calculateSchedule(schedule, ZonedDateTime.now());
|
scheduleCalculationService.calculateSchedule(schedule, ZonedDateTime.now());
|
||||||
return scheduleEntryMapper.toDto(entry);
|
return publish(entry, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduleEntryDto create(final long scheduleId) {
|
public ScheduleEntryDto create(final long scheduleId) {
|
||||||
final Schedule schedule = scheduleReadService.getById(scheduleId);
|
final Schedule schedule = scheduleReadService.getById(scheduleId);
|
||||||
final ScheduleEntry entry = new ScheduleEntry();
|
final ScheduleEntry entry = new ScheduleEntry();
|
||||||
schedule.getEntries().add(scheduleEntryRepository.save(entry));
|
schedule.getEntries().add(scheduleEntryRepository.save(entry));
|
||||||
return scheduleEntryMapper.toDto(entry);
|
return publish(entry, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(final long id) {
|
public void delete(final long id) {
|
||||||
final ScheduleEntry entry = scheduleEntryReadService.getById(id);
|
final ScheduleEntry entry = scheduleEntryReadService.getById(id);
|
||||||
scheduleReadService.getByEntry(entry).getEntries().remove(entry);
|
scheduleReadService.getByEntry(entry).getEntries().remove(entry);
|
||||||
scheduleEntryRepository.delete(entry);
|
scheduleEntryRepository.delete(entry);
|
||||||
|
publish(entry, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScheduleEntryDto publish(final ScheduleEntry entry, final boolean existing) {
|
||||||
|
final ScheduleEntryDto dto = scheduleEntryMapper.toDto(entry);
|
||||||
|
webSocketService.send(dto, existing);
|
||||||
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user