UI device editing
This commit is contained in:
parent
4939d9398f
commit
927e8df13a
@ -1,5 +1,4 @@
|
|||||||
import {validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators";
|
import {validateBooleanAllowNull, validateNumberAllowNull, validateNumberNotNull, validateStringNotEmptyNotNull, validateStringNullToEmpty} from "../validators";
|
||||||
import {Property} from "../property/property.service";
|
|
||||||
|
|
||||||
export abstract class Device {
|
export abstract class Device {
|
||||||
|
|
||||||
@ -19,16 +18,18 @@ export abstract class Device {
|
|||||||
validateNumberNotNull(json['id']),
|
validateNumberNotNull(json['id']),
|
||||||
validateStringNotEmptyNotNull(json['title']),
|
validateStringNotEmptyNotNull(json['title']),
|
||||||
type,
|
type,
|
||||||
Property.fromJsonAllowNull(json['getState']),
|
validateStringNullToEmpty(json['getState']),
|
||||||
Property.fromJsonAllowNull(json['setState']),
|
validateStringNullToEmpty(json['setState']),
|
||||||
|
validateBooleanAllowNull(json['state']),
|
||||||
);
|
);
|
||||||
case "DeviceShutter":
|
case "DeviceShutter":
|
||||||
return new DeviceShutter(
|
return new DeviceShutter(
|
||||||
validateNumberNotNull(json['id']),
|
validateNumberNotNull(json['id']),
|
||||||
validateStringNotEmptyNotNull(json['title']),
|
validateStringNotEmptyNotNull(json['title']),
|
||||||
type,
|
type,
|
||||||
Property.fromJsonAllowNull(json['getPercent']),
|
validateStringNullToEmpty(json['getPercent']),
|
||||||
Property.fromJsonAllowNull(json['setPercent']),
|
validateStringNullToEmpty(json['setPercent']),
|
||||||
|
validateNumberAllowNull(json['percent']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw new Error("No such type: " + type);
|
throw new Error("No such type: " + type);
|
||||||
@ -50,8 +51,9 @@ export class DeviceSwitch extends Device {
|
|||||||
id: number,
|
id: number,
|
||||||
title: string,
|
title: string,
|
||||||
type: string,
|
type: string,
|
||||||
readonly getState: Property | null,
|
public getState: string,
|
||||||
readonly setState: Property | null,
|
public setState: string,
|
||||||
|
public state: boolean | null,
|
||||||
) {
|
) {
|
||||||
super(id, title, type);
|
super(id, title, type);
|
||||||
}
|
}
|
||||||
@ -64,8 +66,9 @@ export class DeviceShutter extends Device {
|
|||||||
id: number,
|
id: number,
|
||||||
title: string,
|
title: string,
|
||||||
type: string,
|
type: string,
|
||||||
readonly getPercent: Property | null,
|
public getPercent: string,
|
||||||
readonly setPercent: Property | null,
|
public setPercent: string,
|
||||||
|
public percent: number | null,
|
||||||
) {
|
) {
|
||||||
super(id, title, type);
|
super(id, title, type);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,4 +17,28 @@ export class DeviceService {
|
|||||||
this.api.getList("device/findAll", Device.fromJson, compare, next, error);
|
this.api.getList("device/findAll", Device.fromJson, compare, next, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set(device: Device, key: string, value: any, next: (item: Device) => void, error: (error: any) => void = NO_OP): void {
|
||||||
|
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 {
|
||||||
|
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 {
|
||||||
|
this.api.postReturnItem("device/set/" + device.id + "/DeviceShutter/" + key, value, Device.fromJson, next, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
getById(id: number, next: (item: Device) => void, error: (error: any) => void = NO_OP): void {
|
||||||
|
this.api.getItem("device/getById/" + id, Device.fromJson, next, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
create(type: string, next: (item: Device) => void, error: (error: any) => void = NO_OP): void {
|
||||||
|
this.api.postReturnItem("device/create/", type, Device.fromJson, next, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(device: Device, next: () => void, error: (error: any) => void = NO_OP): void {
|
||||||
|
this.api.getItem("device/delete/" + device.id, _ => _, next, error);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export class Schedule {
|
|||||||
constructor(
|
constructor(
|
||||||
public id: number,
|
public id: number,
|
||||||
public enabled: boolean,
|
public enabled: boolean,
|
||||||
public name: string,
|
public title: string,
|
||||||
public propertyName: string,
|
public propertyName: string,
|
||||||
public propertyType: string,
|
public propertyType: string,
|
||||||
public entries: ScheduleEntry[],
|
public entries: ScheduleEntry[],
|
||||||
@ -18,7 +18,7 @@ export class Schedule {
|
|||||||
return new Schedule(
|
return new Schedule(
|
||||||
validateNumberNotNull(json['id']),
|
validateNumberNotNull(json['id']),
|
||||||
validateBooleanNotNull(json['enabled']),
|
validateBooleanNotNull(json['enabled']),
|
||||||
validateStringNotEmptyNotNull(json['name']),
|
validateStringNotEmptyNotNull(json['title']),
|
||||||
validateStringNullToEmpty(json['propertyName']),
|
validateStringNullToEmpty(json['propertyName']),
|
||||||
validateStringNullToEmpty(json['propertyType']),
|
validateStringNullToEmpty(json['propertyType']),
|
||||||
validateListOrEmpty(json['entries'], ScheduleEntry.fromJson, ScheduleEntry.compare),
|
validateListOrEmpty(json['entries'], ScheduleEntry.fromJson, ScheduleEntry.compare),
|
||||||
@ -34,7 +34,7 @@ export class Schedule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static compareName(a: Schedule, b: Schedule): number {
|
public static compareName(a: Schedule, b: Schedule): number {
|
||||||
return a.name.localeCompare(b.name);
|
return a.title.localeCompare(b.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,8 +21,8 @@ export class ScheduleService {
|
|||||||
this.api.postReturnItem("schedule/set/" + schedule.id + "/" + key, value, Schedule.fromJson, next, error);
|
this.api.postReturnItem("schedule/set/" + schedule.id + "/" + key, value, Schedule.fromJson, next, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
findById(id: number, next: (item: Schedule) => void, error: (error: any) => void = NO_OP): void {
|
getById(id: number, next: (item: Schedule) => void, error: (error: any) => void = NO_OP): void {
|
||||||
this.api.getItem("schedule/findById/" + id, Schedule.fromJson, next, error);
|
this.api.getItem("schedule/getById/" + id, Schedule.fromJson, next, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
create(next: (item: Schedule) => void, error: (error: any) => void = NO_OP): void {
|
create(next: (item: Schedule) => void, error: (error: any) => void = NO_OP): void {
|
||||||
|
|||||||
@ -3,8 +3,10 @@ import {RouterModule, Routes} from '@angular/router';
|
|||||||
import {ScheduleListComponent} from "./pages/schedule-list/schedule-list.component";
|
import {ScheduleListComponent} from "./pages/schedule-list/schedule-list.component";
|
||||||
import {ScheduleComponent} from "./pages/schedule/schedule.component";
|
import {ScheduleComponent} from "./pages/schedule/schedule.component";
|
||||||
import {DeviceListComponent} from "./pages/device-list/device-list.component";
|
import {DeviceListComponent} from "./pages/device-list/device-list.component";
|
||||||
|
import {DeviceComponent} from "./pages/device/device.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
|
{path: 'Device', component: DeviceComponent},
|
||||||
{path: 'DeviceList', component: DeviceListComponent},
|
{path: 'DeviceList', component: DeviceListComponent},
|
||||||
{path: 'Schedule', component: ScheduleComponent},
|
{path: 'Schedule', component: ScheduleComponent},
|
||||||
{path: 'ScheduleList', component: ScheduleListComponent},
|
{path: 'ScheduleList', component: ScheduleListComponent},
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import {NumberComponent} from './shared/number/number.component';
|
|||||||
import {ScheduleComponent} from "./pages/schedule/schedule.component";
|
import {ScheduleComponent} from "./pages/schedule/schedule.component";
|
||||||
import {SearchComponent} from './shared/search/search.component';
|
import {SearchComponent} from './shared/search/search.component';
|
||||||
import {DeviceListComponent} from './pages/device-list/device-list.component';
|
import {DeviceListComponent} from './pages/device-list/device-list.component';
|
||||||
|
import {DeviceComponent} from './pages/device/device.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -22,6 +23,7 @@ import {DeviceListComponent} from './pages/device-list/device-list.component';
|
|||||||
NumberComponent,
|
NumberComponent,
|
||||||
SearchComponent,
|
SearchComponent,
|
||||||
DeviceListComponent,
|
DeviceListComponent,
|
||||||
|
DeviceComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {Schedule} from "./api/schedule/Schedule";
|
import {Schedule} from "./api/schedule/Schedule";
|
||||||
|
import {Device} from "./api/device/Device";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -16,6 +17,16 @@ export class DataService {
|
|||||||
this._schedule = schedule;
|
this._schedule = schedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _device?: Device;
|
||||||
|
|
||||||
|
get device(): Device | undefined {
|
||||||
|
return this._device;
|
||||||
|
}
|
||||||
|
|
||||||
|
set device(device: Device | undefined) {
|
||||||
|
this._device = device;
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,24 @@
|
|||||||
<ng-container *ngFor="let device of devices">
|
<ng-container *ngFor="let device of devices.sort(Device.compareTitle); trackBy: Device.trackBy">
|
||||||
<ng-container [ngSwitch]="device.type">
|
<ng-container [ngSwitch]="device.type">
|
||||||
<div class="device" *ngSwitchCase="'DeviceSwitch'" [class.switchOn]="isSwitchStateOn(device)" [class.switchOff]="isSwitchStateOff(device)" [class.switchUnknown]="isSwitchStateUnknown(device)">
|
<div class="device" *ngSwitchCase="'DeviceSwitch'" [ngClass]="getSwitchClassList(device)">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{device.title}}
|
{{device.title}}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="edit" [routerLink]="['/Device', {id: device.id}]">
|
||||||
|
Bearbeiten
|
||||||
|
</div>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<img class="control" src="assets/switch-on.svg" (click)="setSwitchState(device, true)"/>
|
<img alt="An" class="control" src="assets/switch-on.svg" (click)="setSwitchState(device, true)"/>
|
||||||
<img class="control" src="assets/switch-off.svg" (click)="setSwitchState(device, false)"/>
|
<img alt="Aus" class="control" src="assets/switch-off.svg" (click)="setSwitchState(device, false)"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="device" *ngSwitchCase="'DeviceShutter'" [class.blindOpen]="isShutterStateOpen(device)" [class.shutterBetween]="isShutterStateBetween(device)" [class.shutterClosed]="isShutterStateClosed(device)" [class.shutterUnknown]="isShutterStateUnknown(device)">
|
<div class="device" *ngSwitchCase="'DeviceShutter'" [ngClass]="getShutterClassList(device)">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{device.title}}
|
{{device.title}}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="edit" [routerLink]="['/Device', {id: device.id}]">
|
||||||
|
Bearbeiten
|
||||||
|
</div>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<div class="control button" (click)="setShutterPercent(device, 0)">
|
<div class="control button" (click)="setShutterPercent(device, 0)">
|
||||||
<span class="center">Auf</span>
|
<span class="center">Auf</span>
|
||||||
@ -33,3 +39,11 @@
|
|||||||
</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>
|
||||||
|
|||||||
@ -4,10 +4,17 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
float: left;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.edit {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
.controls {
|
.controls {
|
||||||
|
clear: both;
|
||||||
|
|
||||||
.control {
|
.control {
|
||||||
position: relative;
|
position: relative;
|
||||||
float: left;
|
float: left;
|
||||||
@ -49,7 +56,7 @@
|
|||||||
background-color: gray;
|
background-color: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blindOpen {
|
.shutterOpen {
|
||||||
background-color: palegreen;
|
background-color: palegreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,8 +10,12 @@ import {Device, DeviceShutter, DeviceSwitch} from "../../api/device/Device";
|
|||||||
})
|
})
|
||||||
export class DeviceListComponent implements OnInit {
|
export class DeviceListComponent implements OnInit {
|
||||||
|
|
||||||
|
readonly Device = Device;
|
||||||
|
|
||||||
devices: Device[] = [];
|
devices: Device[] = [];
|
||||||
|
|
||||||
|
createType: string = "DeviceSwitch";
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly deviceService: DeviceService,
|
readonly deviceService: DeviceService,
|
||||||
readonly propertyService: PropertyService,
|
readonly propertyService: PropertyService,
|
||||||
@ -36,7 +40,7 @@ export class DeviceListComponent implements OnInit {
|
|||||||
if (!device.setState) {
|
if (!device.setState) {
|
||||||
throw new Error("Property 'setState' not set for: " + device);
|
throw new Error("Property 'setState' not set for: " + device);
|
||||||
}
|
}
|
||||||
this.propertyService.set(device.setState.name, value ? 1 : 0);
|
this.propertyService.set(device.setState, value ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
setShutterPercent(d: Device, value: number): void {
|
setShutterPercent(d: Device, value: number): void {
|
||||||
@ -44,38 +48,30 @@ export class DeviceListComponent implements OnInit {
|
|||||||
if (!device.setPercent) {
|
if (!device.setPercent) {
|
||||||
throw new Error("Property 'setPercent' not set for: " + device);
|
throw new Error("Property 'setPercent' not set for: " + device);
|
||||||
}
|
}
|
||||||
this.propertyService.set(device.setPercent.name, value);
|
this.propertyService.set(device.setPercent, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
isSwitchStateOn(device: Device): boolean {
|
create(): void {
|
||||||
return (device as DeviceSwitch).getState?.booleanValue === true;
|
this.deviceService.create(this.createType, device => this.devices.push(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
isSwitchStateOff(device: Device): boolean {
|
getSwitchClassList(device: Device): object {
|
||||||
return (device as DeviceSwitch).getState?.booleanValue === false;
|
const value: boolean | null | undefined = (device as DeviceSwitch).state;
|
||||||
|
return {
|
||||||
|
switchOn: value === true,
|
||||||
|
switchOff: value === false,
|
||||||
|
switchUnknown: value === null || value === undefined,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
isSwitchStateUnknown(device: Device): boolean {
|
getShutterClassList(device: Device): object {
|
||||||
const value: boolean | null | undefined = (device as DeviceSwitch).getState?.booleanValue;
|
const value: number | null | undefined = (device as DeviceShutter).percent;
|
||||||
return value === null || value === undefined;
|
return {
|
||||||
}
|
shutterOpen: value === 0,
|
||||||
|
shutterBetween: value !== null && value !== undefined && value > 0 && value < 100,
|
||||||
isShutterStateOpen(device: Device): boolean {
|
shutterClosed: value === 100,
|
||||||
return (device as DeviceShutter).getPercent?.numberValue === 0;
|
shutterUnknown: value === null || value === undefined,
|
||||||
}
|
};
|
||||||
|
|
||||||
isShutterStateBetween(device: Device): boolean {
|
|
||||||
const value: number | null | undefined = (device as DeviceShutter).getPercent?.numberValue;
|
|
||||||
return value !== null && value !== undefined && value > 0 && value < 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
isShutterStateClosed(device: Device): boolean {
|
|
||||||
return (device as DeviceShutter).getPercent?.numberValue === 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
isShutterStateUnknown(device: Device): boolean {
|
|
||||||
const value: number | null | undefined = (device as DeviceShutter).getPercent?.numberValue;
|
|
||||||
return value === null || value === undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
53
src/main/angular/src/app/pages/device/device.component.html
Normal file
53
src/main/angular/src/app/pages/device/device.component.html
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<ng-container *ngIf="device">
|
||||||
|
<h1>{{device.title}}</h1>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="deviceSwitch">
|
||||||
|
<table class="vertical">
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<td>
|
||||||
|
<app-edit-field [initial]="deviceSwitch.title" (valueChange)="set('title', $event)"></app-edit-field>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Zustand Lesen</th>
|
||||||
|
<td>
|
||||||
|
<app-search [searchService]="propertyService" [initial]="deviceSwitch.getState" [showKey]="true" (valueChange)="setDeviceSwitch('getState', $event)"></app-search>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Zustand Schreiben</th>
|
||||||
|
<td>
|
||||||
|
<app-search [searchService]="propertyService" [initial]="deviceSwitch.setState" [showKey]="true" (valueChange)="setDeviceSwitch('setState', $event)"></app-search>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="deviceShutter">
|
||||||
|
<table class="vertical">
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<td>
|
||||||
|
<app-edit-field [initial]="deviceShutter.title" (valueChange)="set('title', $event)"></app-edit-field>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Position Lesen</th>
|
||||||
|
<td>
|
||||||
|
<app-search [searchService]="propertyService" [initial]="deviceShutter.getPercent" [showKey]="true" (valueChange)="setDeviceShutter('getPercent', $event)"></app-search>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Position Schreiben</th>
|
||||||
|
<td>
|
||||||
|
<app-search [searchService]="propertyService" [initial]="deviceShutter.setPercent" [showKey]="true" (valueChange)="setDeviceShutter('setPercent', $event)"></app-search>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<button (click)="delete()">Löschen</button>
|
||||||
|
</p>
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||||
|
|
||||||
|
import {DeviceComponent} from './device.component';
|
||||||
|
|
||||||
|
describe('DeviceComponent', () => {
|
||||||
|
let component: DeviceComponent;
|
||||||
|
let fixture: ComponentFixture<DeviceComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [DeviceComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(DeviceComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
77
src/main/angular/src/app/pages/device/device.component.ts
Normal file
77
src/main/angular/src/app/pages/device/device.component.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import {Component, OnInit} from '@angular/core';
|
||||||
|
import {ActivatedRoute, Router} from "@angular/router";
|
||||||
|
import {DataService} from "../../data.service";
|
||||||
|
import {PropertyService} from "../../api/property/property.service";
|
||||||
|
import {Device, DeviceShutter, DeviceSwitch} from "../../api/device/Device";
|
||||||
|
import {DeviceService} from "../../api/device/device.service";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-device',
|
||||||
|
templateUrl: './device.component.html',
|
||||||
|
styleUrls: ['./device.component.less']
|
||||||
|
})
|
||||||
|
export class DeviceComponent implements OnInit {
|
||||||
|
|
||||||
|
device!: Device;
|
||||||
|
|
||||||
|
deviceSwitch: DeviceSwitch | undefined;
|
||||||
|
|
||||||
|
deviceShutter: DeviceShutter | undefined;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
readonly router: Router,
|
||||||
|
readonly activatedRoute: ActivatedRoute,
|
||||||
|
readonly deviceService: DeviceService,
|
||||||
|
readonly dataService: DataService,
|
||||||
|
readonly propertyService: PropertyService,
|
||||||
|
) {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.dataService.device = undefined;
|
||||||
|
this.activatedRoute.params.subscribe(params => this.deviceService.getById(params.id, device => this.setDevice(device)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private setDevice(device: Device): void {
|
||||||
|
this.device = device;
|
||||||
|
switch (device.type) {
|
||||||
|
case "DeviceSwitch":
|
||||||
|
this.deviceSwitch = device as DeviceSwitch;
|
||||||
|
break;
|
||||||
|
case "DeviceShutter":
|
||||||
|
this.deviceShutter = device as DeviceShutter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.dataService.device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
set(key: string, value: any): void {
|
||||||
|
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 {
|
||||||
|
if (confirm(this.getDeviceTypeTitle() + " \"" + this.device.title + "\" wirklich löschen?")) {
|
||||||
|
this.deviceService.delete(this.device, () => this.router.navigate(["/DeviceList"]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getDeviceTypeTitle(): string {
|
||||||
|
switch (this.device.type) {
|
||||||
|
case "DeviceSwitch":
|
||||||
|
return "Schalter";
|
||||||
|
case "DeviceShutter":
|
||||||
|
return "Rollladen";
|
||||||
|
default:
|
||||||
|
return "[TYP ???]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td [routerLink]="['/Schedule', {id: schedule.id}]">
|
<td [routerLink]="['/Schedule', {id: schedule.id}]">
|
||||||
{{schedule.name}}
|
{{schedule.title}}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="delete" (click)="delete(schedule)">
|
<td class="delete" (click)="delete(schedule)">
|
||||||
|
|||||||
@ -50,7 +50,7 @@ export class ScheduleListComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete(schedule: Schedule): void {
|
delete(schedule: Schedule): void {
|
||||||
if (confirm("Zeitplan \"" + schedule.name + "\" wirklich löschen?")) {
|
if (confirm("Zeitplan \"" + schedule.title + "\" wirklich löschen?")) {
|
||||||
this.scheduleService.delete(schedule, () => this.remove(schedule));
|
this.scheduleService.delete(schedule, () => this.remove(schedule));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
<tr class="header">
|
<tr class="header">
|
||||||
<ng-container *ngTemplateOutlet="boolean;context:{schedule: schedule, value: schedule.enabled, key:'enabled'}"></ng-container>
|
<ng-container *ngTemplateOutlet="boolean;context:{schedule: schedule, value: schedule.enabled, key:'enabled'}"></ng-container>
|
||||||
<td colspan="8">
|
<td colspan="8">
|
||||||
<app-edit-field [initial]="schedule.name" (valueChange)="set(null, 'name', $event)"></app-edit-field>
|
<app-edit-field [initial]="schedule.title" (valueChange)="set(null, 'title', $event)"></app-edit-field>
|
||||||
</td>
|
</td>
|
||||||
<td colspan="5">
|
<td colspan="5">
|
||||||
<app-search [searchService]="propertyService" [initial]="schedule.propertyName" (valueChange)="set(null, 'propertyName', $event)"></app-search>
|
<app-search [searchService]="propertyService" [initial]="schedule.propertyName" (valueChange)="set(null, 'propertyName', $event)"></app-search>
|
||||||
|
|||||||
@ -34,7 +34,7 @@ export class ScheduleComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.dataService.schedule = undefined;
|
this.dataService.schedule = undefined;
|
||||||
this.activatedRoute.params.subscribe(params => this.scheduleService.findById(params.id, schedule => this.setSchedule(schedule)));
|
this.activatedRoute.params.subscribe(params => this.scheduleService.getById(params.id, schedule => this.setSchedule(schedule)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private setSchedule(schedule: Schedule): void {
|
private setSchedule(schedule: Schedule): void {
|
||||||
|
|||||||
@ -1,9 +1,20 @@
|
|||||||
<div
|
<div
|
||||||
*ngIf="!searching"
|
*ngIf="!searching"
|
||||||
(click)="startSearch()"
|
(click)="start()"
|
||||||
[class.empty]="!selected"
|
[class.empty]="!selected"
|
||||||
>
|
>
|
||||||
{{selected?.value ? selected?.value : "-LEER-"}}
|
|
||||||
|
<ng-container *ngIf="selected">
|
||||||
|
{{selected.value}}
|
||||||
|
<ng-container *ngIf="showKey">
|
||||||
|
[{{selected.key}}]
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="!selected">
|
||||||
|
-LEER-
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
@ -13,8 +24,23 @@
|
|||||||
[(ngModel)]="term"
|
[(ngModel)]="term"
|
||||||
(ngModelChange)="changed()"
|
(ngModelChange)="changed()"
|
||||||
(keydown)="inputKeyPress($event)"
|
(keydown)="inputKeyPress($event)"
|
||||||
|
(blur)="blur()"
|
||||||
>
|
>
|
||||||
|
|
||||||
<div #resultList *ngIf="searching" class="resultList">
|
<div #resultList *ngIf="searching" class="resultList">
|
||||||
<div *ngFor="let result of results" class="result" (click)="select(result)">{{result.value}}</div>
|
<div *ngIf="allowEmpty" class="result" (click)="select(undefined)">
|
||||||
|
-
|
||||||
|
</div>
|
||||||
|
<div *ngIf="selected" class="result selected" (click)="select(undefined)">
|
||||||
|
{{selected.value}}
|
||||||
|
<ng-container *ngIf="showKey">
|
||||||
|
[{{selected.key}}]
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
<div *ngFor="let result of results" class="result" (click)="select(result)">
|
||||||
|
{{result.value}}
|
||||||
|
<ng-container *ngIf="showKey">
|
||||||
|
[{{result.key}}]
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,3 +1,12 @@
|
|||||||
|
.empty {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
.resultList {
|
.resultList {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: lightgray;
|
background-color: lightgray;
|
||||||
|
|||||||
@ -26,8 +26,14 @@ export class SearchComponent<T> implements OnInit {
|
|||||||
@Input()
|
@Input()
|
||||||
initial!: string;
|
initial!: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
showKey: boolean = false;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
allowEmpty: boolean = true;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
valueChange: EventEmitter<string> = new EventEmitter<string>();
|
valueChange: EventEmitter<string | null> = new EventEmitter<string | null>();
|
||||||
|
|
||||||
term: string = "";
|
term: string = "";
|
||||||
|
|
||||||
@ -41,7 +47,9 @@ export class SearchComponent<T> implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.searchService.get(this.initial, result => this.selected = result, _ => _);
|
if (this.initial) {
|
||||||
|
this.searchService.get(this.initial, result => this.selected = result, _ => _);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changed(): void {
|
changed(): void {
|
||||||
@ -56,7 +64,7 @@ export class SearchComponent<T> implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
startSearch(): void {
|
start(): void {
|
||||||
this.term = this.initial;
|
this.term = this.initial;
|
||||||
if (this.resultList && this.input) {
|
if (this.resultList && this.input) {
|
||||||
this.resultList.style.left = this.input.style.left;
|
this.resultList.style.left = this.input.style.left;
|
||||||
@ -72,7 +80,7 @@ export class SearchComponent<T> implements OnInit {
|
|||||||
this.doSearch();
|
this.doSearch();
|
||||||
break;
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
this.cancelSearch();
|
this.cancel();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,11 +94,15 @@ export class SearchComponent<T> implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelSearch(): void {
|
blur() {
|
||||||
setTimeout(() => this.searching = false, 10);
|
setTimeout(() => this.cancel(), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
select(result: KeyValuePair): void {
|
cancel(): void {
|
||||||
|
this.searching = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
select(result: KeyValuePair | undefined): void {
|
||||||
this.searching = false;
|
this.searching = false;
|
||||||
this.selected = result;
|
this.selected = result;
|
||||||
this.valueChange.emit(this.selected?.key);
|
this.valueChange.emit(this.selected?.key);
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package de.ph87.homeautomation;
|
|||||||
|
|
||||||
import com.luckycatlabs.sunrisesunset.Zenith;
|
import com.luckycatlabs.sunrisesunset.Zenith;
|
||||||
import de.ph87.homeautomation.device.DeviceWriteService;
|
import de.ph87.homeautomation.device.DeviceWriteService;
|
||||||
|
import de.ph87.homeautomation.device.devices.DeviceDto;
|
||||||
import de.ph87.homeautomation.knx.group.KnxGroupDto;
|
import de.ph87.homeautomation.knx.group.KnxGroupDto;
|
||||||
import de.ph87.homeautomation.knx.group.KnxGroupRepository;
|
import de.ph87.homeautomation.knx.group.KnxGroupRepository;
|
||||||
import de.ph87.homeautomation.knx.group.KnxGroupWriteService;
|
import de.ph87.homeautomation.knx.group.KnxGroupWriteService;
|
||||||
@ -19,6 +20,8 @@ import tuwien.auto.calimero.GroupAddress;
|
|||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
import static de.ph87.homeautomation.shared.Helpers.mapIfNotNull;
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "UnusedReturnValue", "SameParameterValue", "UnusedAssignment", "RedundantSuppression"})
|
@SuppressWarnings({"unchecked", "UnusedReturnValue", "SameParameterValue", "UnusedAssignment", "RedundantSuppression"})
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -49,8 +52,8 @@ public class DemoDataService {
|
|||||||
final KnxGroupDto bad_licht_mitte_status = createKnxGroupIfNotExists("Bad Licht Mitte Status", 0, 3, 30, "1.001", PropertyType.ON_OFF, true, false);
|
final KnxGroupDto bad_licht_mitte_status = createKnxGroupIfNotExists("Bad Licht Mitte Status", 0, 3, 30, "1.001", PropertyType.ON_OFF, true, false);
|
||||||
final KnxGroupDto helligkeit = createKnxGroupIfNotExists("Helligkeit", 0, 5, 6, "9.004", PropertyType.LUX, false, true);
|
final KnxGroupDto helligkeit = createKnxGroupIfNotExists("Helligkeit", 0, 5, 6, "9.004", PropertyType.LUX, false, true);
|
||||||
|
|
||||||
deviceWriteService.createDeviceSwitch("Bad Licht Mitte", bad_licht_mitte_status, bad_licht_mitte_schalten);
|
createDeviceSwitch("Bad Licht Mitte", bad_licht_mitte_status, bad_licht_mitte_schalten);
|
||||||
deviceWriteService.createDeviceShutter("Flur OG Rollladen", null, flur_rollladen_position_anfahren);
|
createDeviceShutter("Flur OG Rollladen", null, flur_rollladen_position_anfahren);
|
||||||
|
|
||||||
if (scheduleRepository.count() == 0) {
|
if (scheduleRepository.count() == 0) {
|
||||||
final Schedule scheduleEgFlurLicht = createSchedule("EG Flur Licht", eg_flur_licht_schalten);
|
final Schedule scheduleEgFlurLicht = createSchedule("EG Flur Licht", eg_flur_licht_schalten);
|
||||||
@ -106,10 +109,18 @@ public class DemoDataService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DeviceDto createDeviceSwitch(final String title, final PropertyDto getPercent, final PropertyDto setPercent) {
|
||||||
|
return deviceWriteService.createDeviceSwitch(title, mapIfNotNull(getPercent, PropertyDto::getName), mapIfNotNull(setPercent, PropertyDto::getName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeviceDto createDeviceShutter(final String title, final PropertyDto getPercent, final PropertyDto setPercent) {
|
||||||
|
return deviceWriteService.createDeviceShutter(title, mapIfNotNull(getPercent, PropertyDto::getName), mapIfNotNull(setPercent, PropertyDto::getName));
|
||||||
|
}
|
||||||
|
|
||||||
private Schedule createSchedule(final String s, final PropertyDto propertyDto) {
|
private Schedule createSchedule(final String s, final PropertyDto propertyDto) {
|
||||||
final Schedule schedule = new Schedule();
|
final Schedule schedule = new Schedule();
|
||||||
schedule.setEnabled(true);
|
schedule.setEnabled(true);
|
||||||
schedule.setName(s);
|
schedule.setTitle(s);
|
||||||
schedule.setPropertyName(propertyDto.getName());
|
schedule.setPropertyName(propertyDto.getName());
|
||||||
schedule.setPropertyType(propertyDto.getPropertyType());
|
schedule.setPropertyType(propertyDto.getPropertyType());
|
||||||
return schedule;
|
return schedule;
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
package de.ph87.homeautomation.device;
|
package de.ph87.homeautomation.device;
|
||||||
|
|
||||||
|
import de.ph87.homeautomation.device.devices.Device;
|
||||||
import de.ph87.homeautomation.device.devices.DeviceDto;
|
import de.ph87.homeautomation.device.devices.DeviceDto;
|
||||||
import de.ph87.homeautomation.property.PropertySetException;
|
import de.ph87.homeautomation.device.devices.DeviceShutter;
|
||||||
|
import de.ph87.homeautomation.device.devices.DeviceSwitch;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@ -21,9 +23,49 @@ public class DeviceController {
|
|||||||
return deviceReadService.findAll();
|
return deviceReadService.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("set")
|
@GetMapping("getById/{id}")
|
||||||
public void set(@RequestBody final DeviceSetDto dto) throws PropertySetException {
|
public DeviceDto getById(@PathVariable final long id) {
|
||||||
deviceWriteService.set(dto);
|
return deviceReadService.getDtoById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("create")
|
||||||
|
public DeviceDto create(@RequestBody final String typeString) {
|
||||||
|
return deviceWriteService.create(typeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("delete/{id}")
|
||||||
|
public void delete(@PathVariable final long id) {
|
||||||
|
deviceWriteService.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("set/{id}/enabled")
|
||||||
|
public DeviceDto setEnabled(@PathVariable final long id, @RequestBody final boolean enabled) {
|
||||||
|
return deviceWriteService.set(id, Device::setEnabled, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("set/{id}/title")
|
||||||
|
public DeviceDto setName(@PathVariable final long id, @RequestBody final String title) {
|
||||||
|
return deviceWriteService.set(id, Device::setTitle, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("set/{id}/DeviceSwitch/setState")
|
||||||
|
public DeviceDto setDeviceSwitchSetState(@PathVariable final long id, @RequestBody(required = false) final String name) {
|
||||||
|
return deviceWriteService.setDeviceSwitch(id, DeviceSwitch::setSetState, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("set/{id}/DeviceSwitch/getState")
|
||||||
|
public DeviceDto setDeviceSwitchGetState(@PathVariable final long id, @RequestBody(required = false) final String name) {
|
||||||
|
return deviceWriteService.setDeviceSwitch(id, DeviceSwitch::setGetState, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("set/{id}/DeviceShutter/setPercent")
|
||||||
|
public DeviceDto setDeviceShutterSetPercent(@PathVariable final long id, @RequestBody(required = false) final String name) {
|
||||||
|
return deviceWriteService.setDeviceShutter(id, DeviceShutter::setSetPercent, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("set/{id}/DeviceShutter/getPercent")
|
||||||
|
public DeviceDto setDeviceShutterGetPercent(@PathVariable final long id, @RequestBody(required = false) final String name) {
|
||||||
|
return deviceWriteService.setDeviceShutter(id, DeviceShutter::setGetPercent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
package de.ph87.homeautomation.device;
|
package de.ph87.homeautomation.device;
|
||||||
|
|
||||||
import de.ph87.homeautomation.device.devices.*;
|
import de.ph87.homeautomation.device.devices.*;
|
||||||
import de.ph87.homeautomation.property.PropertyDto;
|
|
||||||
import de.ph87.homeautomation.property.PropertyService;
|
import de.ph87.homeautomation.property.PropertyService;
|
||||||
|
import de.ph87.office.web.NotFoundException;
|
||||||
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,19 +27,25 @@ public class DeviceReadService {
|
|||||||
return deviceRepository.findAll().stream().map(this::toDto).collect(Collectors.toList());
|
return deviceRepository.findAll().stream().map(this::toDto).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeviceDto toDto(final Device device) {
|
public DeviceDto toDto(final Device device) {
|
||||||
if (device instanceof DeviceSwitch) {
|
if (device instanceof DeviceSwitch) {
|
||||||
final DeviceSwitch deviceSwitch = (DeviceSwitch) device;
|
final DeviceSwitch deviceSwitch = (DeviceSwitch) device;
|
||||||
final PropertyDto getState = mapIfNotNull(deviceSwitch.getGetState(), propertyService::getById);
|
final Boolean state = mapIfNotNull(deviceSwitch.getGetState(), propertyService::readBoolean);
|
||||||
final PropertyDto setState = mapIfNotNull(deviceSwitch.getSetState(), propertyService::getById);
|
return new DeviceSwitchDto(deviceSwitch, deviceSwitch.getGetState(), deviceSwitch.getSetState(), state);
|
||||||
return new DeviceSwitchDto(deviceSwitch, getState, setState);
|
|
||||||
} else if (device instanceof DeviceShutter) {
|
} else if (device instanceof DeviceShutter) {
|
||||||
final DeviceShutter deviceShutter = (DeviceShutter) device;
|
final DeviceShutter deviceShutter = (DeviceShutter) device;
|
||||||
final PropertyDto getPercent = mapIfNotNull(deviceShutter.getGetPercent(), propertyService::getById);
|
final Double percent = mapIfNotNull(deviceShutter.getGetPercent(), propertyService::readNumber);
|
||||||
final PropertyDto setPercent = mapIfNotNull(deviceShutter.getSetPercent(), propertyService::getById);
|
return new DeviceShutterDto(deviceShutter, deviceShutter.getGetPercent(), deviceShutter.getSetPercent(), percent);
|
||||||
return new DeviceShutterDto(deviceShutter, getPercent, setPercent);
|
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Not implemented: toDto(" + device + ")");
|
throw new RuntimeException("Not implemented: toDto(" + device + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Device getById(final long id) {
|
||||||
|
return deviceRepository.findById(id).orElseThrow(() -> new NotFoundException("Device.id=%d", id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceDto getDtoById(final long id) {
|
||||||
|
return toDto(getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,4 +9,6 @@ public interface DeviceRepository extends CrudRepository<Device, Long> {
|
|||||||
|
|
||||||
List<Device> findAll();
|
List<Device> findAll();
|
||||||
|
|
||||||
|
boolean existsByTitle(String title);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.Device;
|
||||||
|
import de.ph87.homeautomation.device.devices.DeviceDto;
|
||||||
import de.ph87.homeautomation.device.devices.DeviceShutter;
|
import de.ph87.homeautomation.device.devices.DeviceShutter;
|
||||||
import de.ph87.homeautomation.device.devices.DeviceSwitch;
|
import de.ph87.homeautomation.device.devices.DeviceSwitch;
|
||||||
import de.ph87.homeautomation.property.PropertyDto;
|
|
||||||
import de.ph87.homeautomation.property.PropertyService;
|
import de.ph87.homeautomation.property.PropertyService;
|
||||||
import de.ph87.homeautomation.property.PropertySetException;
|
import de.ph87.homeautomation.property.PropertySetException;
|
||||||
import de.ph87.office.web.NotFoundException;
|
import de.ph87.homeautomation.schedule.ScheduleWriteService;
|
||||||
|
import de.ph87.office.web.BadRequestException;
|
||||||
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 static de.ph87.homeautomation.shared.Helpers.mapIfNotNull;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -24,24 +25,28 @@ public class DeviceWriteService {
|
|||||||
|
|
||||||
private final PropertyService propertyService;
|
private final PropertyService propertyService;
|
||||||
|
|
||||||
public void createDeviceSwitch(final String title, final PropertyDto getState, final PropertyDto setState) {
|
private final DeviceReadService deviceReadService;
|
||||||
|
|
||||||
|
public DeviceDto createDeviceSwitch(final String title, final String getStatePropertyName, final String setStatePropertyName) {
|
||||||
final DeviceSwitch deviceSwitch = new DeviceSwitch();
|
final DeviceSwitch deviceSwitch = new DeviceSwitch();
|
||||||
deviceSwitch.setTitle(title);
|
deviceSwitch.setTitle(title);
|
||||||
deviceSwitch.setGetState(mapIfNotNull(getState, PropertyDto::getName));
|
deviceSwitch.setGetState(getStatePropertyName);
|
||||||
deviceSwitch.setSetState(mapIfNotNull(setState, PropertyDto::getName));
|
deviceSwitch.setSetState(setStatePropertyName);
|
||||||
deviceRepository.save(deviceSwitch);
|
deviceRepository.save(deviceSwitch);
|
||||||
|
return deviceReadService.toDto(deviceSwitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void createDeviceShutter(final String title, final PropertyDto getPercent, final PropertyDto setPercent) {
|
public DeviceDto createDeviceShutter(final String title, final String getPercentPropertyName, final String setPercentPropertyName) {
|
||||||
final DeviceShutter deviceShutter = new DeviceShutter();
|
final DeviceShutter deviceShutter = new DeviceShutter();
|
||||||
deviceShutter.setTitle(title);
|
deviceShutter.setTitle(title);
|
||||||
deviceShutter.setGetPercent(mapIfNotNull(getPercent, PropertyDto::getName));
|
deviceShutter.setGetPercent(getPercentPropertyName);
|
||||||
deviceShutter.setSetPercent(mapIfNotNull(setPercent, PropertyDto::getName));
|
deviceShutter.setSetPercent(setPercentPropertyName);
|
||||||
deviceRepository.save(deviceShutter);
|
deviceRepository.save(deviceShutter);
|
||||||
|
return deviceReadService.toDto(deviceShutter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(final DeviceSetDto dto) throws PropertySetException {
|
public void set(final DeviceSetDto dto) throws PropertySetException {
|
||||||
final Device device = getById(dto.getId());
|
final Device device = deviceReadService.getById(dto.getId());
|
||||||
if (device instanceof DeviceSwitch) {
|
if (device instanceof DeviceSwitch) {
|
||||||
setSwitch((DeviceSwitch) device, dto.getProperty(), dto.getValue());
|
setSwitch((DeviceSwitch) device, dto.getProperty(), dto.getValue());
|
||||||
} else if (device instanceof DeviceShutter) {
|
} else if (device instanceof DeviceShutter) {
|
||||||
@ -63,8 +68,51 @@ public class DeviceWriteService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Device getById(final long id) {
|
public <T> DeviceDto set(final long id, final BiConsumer<Device, T> setter, final T value) {
|
||||||
return deviceRepository.findById(id).orElseThrow(() -> new NotFoundException("Device.id=%d", id));
|
final Device device = deviceReadService.getById(id);
|
||||||
|
setter.accept(device, value);
|
||||||
|
return deviceReadService.toDto(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> DeviceDto setDeviceSwitch(final long id, final BiConsumer<DeviceSwitch, T> setter, final T value) {
|
||||||
|
final Device device = deviceReadService.getById(id);
|
||||||
|
if (!(device instanceof DeviceSwitch)) {
|
||||||
|
throw new BadRequestException("Not a DeviceSwitch: %s", device);
|
||||||
|
}
|
||||||
|
setter.accept((DeviceSwitch) device, value);
|
||||||
|
return deviceReadService.toDto(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> DeviceDto setDeviceShutter(final long id, final BiConsumer<DeviceShutter, T> setter, final T value) {
|
||||||
|
final Device device = deviceReadService.getById(id);
|
||||||
|
if (!(device instanceof DeviceShutter)) {
|
||||||
|
throw new BadRequestException("Not a DeviceShutter: %s", device);
|
||||||
|
}
|
||||||
|
setter.accept((DeviceShutter) device, value);
|
||||||
|
return deviceReadService.toDto(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(final long id) {
|
||||||
|
deviceRepository.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceDto create(final String type) {
|
||||||
|
switch (type) {
|
||||||
|
case "DeviceSwitch":
|
||||||
|
return createDeviceSwitch(generateUnusedTitle(), null, null);
|
||||||
|
case "DeviceShutter":
|
||||||
|
return createDeviceShutter(generateUnusedTitle(), null, null);
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Not implemented type: " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateUnusedTitle() {
|
||||||
|
int index = 0;
|
||||||
|
String title = null;
|
||||||
|
while (title == null || deviceRepository.existsByTitle(title)) {
|
||||||
|
title = ScheduleWriteService.NAME_PREFIX + ++index;
|
||||||
|
}
|
||||||
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,4 +21,6 @@ public abstract class Device {
|
|||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
|
private boolean enabled = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,21 @@
|
|||||||
package de.ph87.homeautomation.device.devices;
|
package de.ph87.homeautomation.device.devices;
|
||||||
|
|
||||||
import de.ph87.homeautomation.property.PropertyDto;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class DeviceShutterDto extends DeviceDto {
|
public class DeviceShutterDto extends DeviceDto {
|
||||||
|
|
||||||
public final PropertyDto getPercent;
|
public final String getPercent;
|
||||||
|
|
||||||
public final PropertyDto setPercent;
|
public final String setPercent;
|
||||||
|
|
||||||
public DeviceShutterDto(final DeviceShutter device, final PropertyDto getPercent, final PropertyDto setPercent) {
|
public final Double percent;
|
||||||
|
|
||||||
|
public DeviceShutterDto(final DeviceShutter device, final String getPercent, final String setPercent, final Double percent) {
|
||||||
super(device);
|
super(device);
|
||||||
this.getPercent = getPercent;
|
this.getPercent = getPercent;
|
||||||
this.setPercent = setPercent;
|
this.setPercent = setPercent;
|
||||||
|
this.percent = percent;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,21 @@
|
|||||||
package de.ph87.homeautomation.device.devices;
|
package de.ph87.homeautomation.device.devices;
|
||||||
|
|
||||||
import de.ph87.homeautomation.property.PropertyDto;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class DeviceSwitchDto extends DeviceDto {
|
public class DeviceSwitchDto extends DeviceDto {
|
||||||
|
|
||||||
public final PropertyDto getState;
|
public final String getState;
|
||||||
|
|
||||||
public final PropertyDto setState;
|
public final String setState;
|
||||||
|
|
||||||
public DeviceSwitchDto(final DeviceSwitch device, final PropertyDto getState, final PropertyDto setState) {
|
public final Boolean state;
|
||||||
|
|
||||||
|
public DeviceSwitchDto(final DeviceSwitch device, final String getState, final String setState, final Boolean state) {
|
||||||
super(device);
|
super(device);
|
||||||
this.getState = getState;
|
this.getState = getState;
|
||||||
this.setState = setState;
|
this.setState = setState;
|
||||||
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package de.ph87.homeautomation.knx.group;
|
package de.ph87.homeautomation.knx.group;
|
||||||
|
|
||||||
import de.ph87.homeautomation.property.IProperty;
|
|
||||||
import de.ph87.homeautomation.property.PropertyType;
|
import de.ph87.homeautomation.property.PropertyType;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -15,7 +14,7 @@ import java.time.ZonedDateTime;
|
|||||||
@Setter
|
@Setter
|
||||||
@ToString
|
@ToString
|
||||||
@Entity
|
@Entity
|
||||||
public class KnxGroup implements IProperty {
|
public class KnxGroup {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
|
|||||||
@ -62,7 +62,7 @@ public class KnxGroupSetService implements IPropertyOwner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Number readNumber(final String propertyName) {
|
public Double readNumber(final String propertyName) {
|
||||||
return knxGroupRepository.findByAddressRaw(parseGroupAddress(propertyName).getRawAddress()).map(KnxGroup::getNumberValue).orElse(null);
|
return knxGroupRepository.findByAddressRaw(parseGroupAddress(propertyName).getRawAddress()).map(KnxGroup::getNumberValue).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +0,0 @@
|
|||||||
package de.ph87.homeautomation.property;
|
|
||||||
|
|
||||||
public interface IProperty {
|
|
||||||
|
|
||||||
String getPropertyName();
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -12,7 +12,7 @@ public interface IPropertyOwner {
|
|||||||
|
|
||||||
Boolean readBoolean(String propertyName);
|
Boolean readBoolean(String propertyName);
|
||||||
|
|
||||||
Number readNumber(String propertyName);
|
Double readNumber(String propertyName);
|
||||||
|
|
||||||
List<PropertyDto> findAllProperties();
|
List<PropertyDto> findAllProperties();
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ public class PropertyService {
|
|||||||
return getOwnerOrThrow(propertyName).readBoolean(propertyName);
|
return getOwnerOrThrow(propertyName).readBoolean(propertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number readNumber(final String propertyName) {
|
public Double readNumber(final String propertyName) {
|
||||||
return getOwnerOrThrow(propertyName).readNumber(propertyName);
|
return getOwnerOrThrow(propertyName).readNumber(propertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ public class Schedule {
|
|||||||
private boolean enabled = false;
|
private boolean enabled = false;
|
||||||
|
|
||||||
@Column(nullable = false, unique = true)
|
@Column(nullable = false, unique = true)
|
||||||
private String name;
|
private String title;
|
||||||
|
|
||||||
private String propertyName;
|
private String propertyName;
|
||||||
|
|
||||||
|
|||||||
@ -45,15 +45,15 @@ public class ScheduleCalculationService {
|
|||||||
.filter(entry -> entry.getNextFuzzyTimestamp() != null && entry.getNextFuzzyTimestamp().isAfter(now))
|
.filter(entry -> entry.getNextFuzzyTimestamp() != null && entry.getNextFuzzyTimestamp().isAfter(now))
|
||||||
.min(Comparator.comparing(ScheduleEntry::getNextFuzzyTimestamp));
|
.min(Comparator.comparing(ScheduleEntry::getNextFuzzyTimestamp));
|
||||||
if (nextEntry.isEmpty()) {
|
if (nextEntry.isEmpty()) {
|
||||||
log.info("No next schedule for \"{}\"", schedule.getName());
|
log.info("No next schedule for \"{}\"", schedule.getTitle());
|
||||||
} else {
|
} else {
|
||||||
log.info("Next schedule for \"{}\": {}", schedule.getName(), nextEntry.get().getNextFuzzyTimestamp());
|
log.info("Next schedule for \"{}\": {}", schedule.getTitle(), nextEntry.get().getNextFuzzyTimestamp());
|
||||||
}
|
}
|
||||||
eventPublisher.publishEvent(new ScheduleThreadWakeUpEvent());
|
eventPublisher.publishEvent(new ScheduleThreadWakeUpEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void calculateEntry(final Schedule schedule, final ScheduleEntry entry, final ZonedDateTime now) {
|
private void calculateEntry(final Schedule schedule, final ScheduleEntry entry, final ZonedDateTime now) {
|
||||||
log.debug("calculateNext \"{}\", {}:", schedule.getName(), entry);
|
log.debug("calculateNext \"{}\", {}:", schedule.getTitle(), entry);
|
||||||
if (!schedule.isEnabled() || !entry.isEnabled() || !isAnyWeekdayEnabled(entry)) {
|
if (!schedule.isEnabled() || !entry.isEnabled() || !isAnyWeekdayEnabled(entry)) {
|
||||||
entry.setNextClearTimestamp(null);
|
entry.setNextClearTimestamp(null);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package de.ph87.homeautomation.schedule;
|
package de.ph87.homeautomation.schedule;
|
||||||
|
|
||||||
import de.ph87.homeautomation.property.PropertyType;
|
import de.ph87.homeautomation.property.PropertyType;
|
||||||
import de.ph87.homeautomation.schedule.entry.ScheduleNextExecutionDto;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@ -21,16 +20,11 @@ public class ScheduleController {
|
|||||||
return scheduleReadService.findAllDtos();
|
return scheduleReadService.findAllDtos();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("findById/{id}")
|
@GetMapping("getById/{id}")
|
||||||
public ScheduleDto findById(@PathVariable final long id) {
|
public ScheduleDto getById(@PathVariable final long id) {
|
||||||
return scheduleReadService.getDtoById(id);
|
return scheduleReadService.getDtoById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("findAllNext")
|
|
||||||
public List<ScheduleNextExecutionDto> findAllNext() {
|
|
||||||
return scheduleReadService.findAllNextExecutionDtos();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("create")
|
@GetMapping("create")
|
||||||
public ScheduleDto create() {
|
public ScheduleDto create() {
|
||||||
return scheduleWriteService.create();
|
return scheduleWriteService.create();
|
||||||
@ -48,7 +42,7 @@ public class ScheduleController {
|
|||||||
|
|
||||||
@PostMapping("set/{id}/name")
|
@PostMapping("set/{id}/name")
|
||||||
public ScheduleDto setName(@PathVariable final long id, @RequestBody final String name) {
|
public ScheduleDto setName(@PathVariable final long id, @RequestBody final String name) {
|
||||||
return scheduleWriteService.set(id, Schedule::setName, name);
|
return scheduleWriteService.set(id, Schedule::setTitle, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("set/{id}/propertyName")
|
@PostMapping("set/{id}/propertyName")
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public class ScheduleDto {
|
|||||||
|
|
||||||
public final boolean enabled;
|
public final boolean enabled;
|
||||||
|
|
||||||
public final String name;
|
public final String title;
|
||||||
|
|
||||||
public final String propertyName;
|
public final String propertyName;
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ public class ScheduleDto {
|
|||||||
public ScheduleDto(final Schedule schedule) {
|
public ScheduleDto(final Schedule schedule) {
|
||||||
this.id = schedule.getId();
|
this.id = schedule.getId();
|
||||||
this.enabled = schedule.isEnabled();
|
this.enabled = schedule.isEnabled();
|
||||||
this.name = schedule.getName();
|
this.title = schedule.getTitle();
|
||||||
this.propertyName = schedule.getPropertyName();
|
this.propertyName = schedule.getPropertyName();
|
||||||
this.propertyType = schedule.getPropertyType();
|
this.propertyType = schedule.getPropertyType();
|
||||||
this.entries = schedule.getEntries().stream().map(ScheduleEntryDto::new).collect(Collectors.toSet());
|
this.entries = schedule.getEntries().stream().map(ScheduleEntryDto::new).collect(Collectors.toSet());
|
||||||
|
|||||||
@ -41,7 +41,7 @@ public class ScheduleExecutionService {
|
|||||||
|
|
||||||
private void executeEntry(final Schedule schedule, final ScheduleEntry entry, final ZonedDateTime now) {
|
private void executeEntry(final Schedule schedule, final ScheduleEntry entry, final ZonedDateTime now) {
|
||||||
entry.setLastClearTimestamp(entry.getNextClearTimestamp());
|
entry.setLastClearTimestamp(entry.getNextClearTimestamp());
|
||||||
log.info("Executing Schedule \"{}\" Entry {}", schedule.getName(), entry);
|
log.info("Executing Schedule \"{}\" Entry {}", schedule.getTitle(), entry);
|
||||||
try {
|
try {
|
||||||
propertyService.set(schedule.getPropertyName(), entry.getValue());
|
propertyService.set(schedule.getPropertyName(), entry.getValue());
|
||||||
} catch (PropertySetException e) {
|
} catch (PropertySetException e) {
|
||||||
|
|||||||
@ -1,17 +1,13 @@
|
|||||||
package de.ph87.homeautomation.schedule;
|
package de.ph87.homeautomation.schedule;
|
||||||
|
|
||||||
import de.ph87.homeautomation.schedule.entry.ScheduleEntry;
|
import de.ph87.homeautomation.schedule.entry.ScheduleEntry;
|
||||||
import de.ph87.homeautomation.schedule.entry.ScheduleNextExecutionDto;
|
|
||||||
import de.ph87.office.web.NotFoundException;
|
import de.ph87.office.web.NotFoundException;
|
||||||
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.time.ZonedDateTime;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -36,16 +32,6 @@ public class ScheduleReadService {
|
|||||||
return findAll().stream().map(scheduleMapper::toDto).collect(Collectors.toList());
|
return findAll().stream().map(scheduleMapper::toDto).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ScheduleNextExecutionDto> findAllNextExecutionDtos() {
|
|
||||||
final ZonedDateTime now = ZonedDateTime.now();
|
|
||||||
return scheduleRepository.findAll().stream()
|
|
||||||
.map(schedule -> ScheduleNextExecutionDto.create(schedule, now))
|
|
||||||
.filter(Optional::isPresent)
|
|
||||||
.map(Optional::get)
|
|
||||||
.sorted(Comparator.comparing(ScheduleNextExecutionDto::getNextTimestamp))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Schedule getByEntry(final ScheduleEntry entry) {
|
public Schedule getByEntry(final ScheduleEntry entry) {
|
||||||
return scheduleRepository.getByEntriesContaining(entry);
|
return scheduleRepository.getByEntriesContaining(entry);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,6 @@ public interface ScheduleRepository extends CrudRepository<Schedule, Long> {
|
|||||||
|
|
||||||
Schedule getByEntriesContaining(ScheduleEntry entry);
|
Schedule getByEntriesContaining(ScheduleEntry entry);
|
||||||
|
|
||||||
boolean existsByName(String name);
|
boolean existsByTitle(String title);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,21 @@ public class ScheduleWriteService {
|
|||||||
|
|
||||||
private final ScheduleRepository scheduleRepository;
|
private final ScheduleRepository scheduleRepository;
|
||||||
|
|
||||||
|
public ScheduleDto create() {
|
||||||
|
final Schedule entry = new Schedule();
|
||||||
|
entry.setTitle(generateUnusedName());
|
||||||
|
return scheduleMapper.toDto(scheduleRepository.save(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateUnusedName() {
|
||||||
|
int index = 0;
|
||||||
|
String name = null;
|
||||||
|
while (name == null || scheduleRepository.existsByTitle(name)) {
|
||||||
|
name = ScheduleWriteService.NAME_PREFIX + ++index;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
public <T> ScheduleDto set(final long id, final BiConsumer<Schedule, T> setter, final T value) {
|
public <T> ScheduleDto set(final long id, final BiConsumer<Schedule, T> setter, final T value) {
|
||||||
final Schedule schedule = scheduleReadService.getById(id);
|
final Schedule schedule = scheduleReadService.getById(id);
|
||||||
setter.accept(schedule, value);
|
setter.accept(schedule, value);
|
||||||
@ -31,21 +46,6 @@ public class ScheduleWriteService {
|
|||||||
return scheduleMapper.toDto(schedule);
|
return scheduleMapper.toDto(schedule);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduleDto create() {
|
|
||||||
final Schedule entry = new Schedule();
|
|
||||||
entry.setName(generateUnusedName());
|
|
||||||
return scheduleMapper.toDto(scheduleRepository.save(entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String generateUnusedName() {
|
|
||||||
int index = 0;
|
|
||||||
String name = null;
|
|
||||||
while (name == null || scheduleRepository.existsByName(name)) {
|
|
||||||
name = ScheduleWriteService.NAME_PREFIX + ++index;
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete(final long id) {
|
public void delete(final long id) {
|
||||||
scheduleRepository.deleteById(id);
|
scheduleRepository.deleteById(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ public class ScheduleNextExecutionDto {
|
|||||||
public final double numberValue;
|
public final double numberValue;
|
||||||
|
|
||||||
private ScheduleNextExecutionDto(final Schedule schedule, final ScheduleEntry entry) {
|
private ScheduleNextExecutionDto(final Schedule schedule, final ScheduleEntry entry) {
|
||||||
this.name = schedule.getName();
|
this.name = schedule.getTitle();
|
||||||
this.nextTimestamp = entry.getNextFuzzyTimestamp();
|
this.nextTimestamp = entry.getNextFuzzyTimestamp();
|
||||||
this.numberValue = entry.getValue();
|
this.numberValue = entry.getValue();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user