diff --git a/src/main/angular/src/app/api/STUB.ts b/src/main/angular/src/app/api/STUB.ts new file mode 100644 index 0000000..8a4567c --- /dev/null +++ b/src/main/angular/src/app/api/STUB.ts @@ -0,0 +1,87 @@ +import {Area} from './area/Area'; +import {Room} from './room/Room'; +import {Device, DeviceStateScene, DeviceSwitch} from './device/Device'; + +const ____ = null; + +let areaId = 0; +const OG2 = ++areaId; +const OG1 = ++areaId; +const EG = ++areaId; +const KELLER = ++areaId; +const GARAGE = ++areaId; +const GARTEN = ++areaId; + +export const STUB_AREAS: Area[] = [ + new Area(OG2, OG2, 'Dachgeschoss'), + new Area(OG1, OG1, 'Obergeschoss'), + new Area(EG, EG, 'Erdgeschoss'), + new Area(KELLER, KELLER, 'Keller'), + new Area(GARAGE, GARAGE, 'Garage'), + new Area(GARTEN, GARTEN, 'Garten'), +]; + +let roomId = 0; +const PATRICK = ++roomId; +const KATRIN = ++roomId; +const FLUR = ++roomId; +const BAD = ++roomId; +const ELTERN = ++roomId; +const EMIL = ++roomId; +const KIND2 = ++roomId; +const FLUR_OG1 = ++roomId; +const KUECHE = ++roomId; +const WOHNZIMMER = ++roomId; +const WASCHKUECHE = ++roomId; +const FLUR_EG = ++roomId; +const BIERKELLER = ++roomId; +const HEIZUNGSRAUM = ++roomId; +const GARAGE_KATRIN = ++roomId; +const GARAGE_PATRICK = ++roomId; +const WERKSTATT = ++roomId; +const TERRASSE = ++roomId; +const VORGARTEN = ++roomId; + +export const STUB_ROOMS: Room[] = [ + new Room(PATRICK, PATRICK, 'Patrick', OG2), + new Room(KATRIN, KATRIN, 'Katrin', OG2), + new Room(FLUR, FLUR, 'Flur', OG2), + new Room(BAD, BAD, 'Bad', OG1), + new Room(ELTERN, ELTERN, 'Eltern', OG1), + new Room(EMIL, EMIL, 'Emil', OG1), + new Room(KIND2, KIND2, 'Kind 2', OG1), + new Room(FLUR_OG1, FLUR_OG1, 'Flur', OG1), + new Room(KUECHE, KUECHE, 'Küche', EG), + new Room(WOHNZIMMER, WOHNZIMMER, 'Wohnzimmer', EG), + new Room(WASCHKUECHE, WASCHKUECHE, 'Waschküche', EG), + new Room(FLUR_EG, FLUR_EG, 'Flur', EG), + new Room(BIERKELLER, BIERKELLER, 'Bierkeller', KELLER), + new Room(HEIZUNGSRAUM, HEIZUNGSRAUM, 'Heizungsraum', KELLER), + new Room(GARAGE_KATRIN, GARAGE_KATRIN, 'Katrin', GARAGE), + new Room(GARAGE_PATRICK, GARAGE_PATRICK, 'Patrick', GARAGE), + new Room(WERKSTATT, WERKSTATT, 'Werkstatt', GARAGE), + new Room(TERRASSE, TERRASSE, 'Terrasse', GARTEN), + new Room(VORGARTEN, VORGARTEN, 'Vorgarten', GARTEN), +]; + +let deviceId = 0; +export const STUB_DEVICES: Device[] = [ + new DeviceStateScene(++deviceId, deviceId, ____, ____, 'Alles Aus', 'DeviceStateScene', null, null, [1]), + new DeviceStateScene(++deviceId, deviceId, ____, ____, 'Rollläden Runter', 'DeviceStateScene', null, null, [40]), + + new DeviceStateScene(++deviceId, deviceId, OG2, ____, 'Alles Aus', 'DeviceStateScene', null, null, [1]), + new DeviceStateScene(++deviceId, deviceId, OG2, ____, 'Rollläden Runter', 'DeviceStateScene', null, null, [40]), + + new DeviceStateScene(++deviceId, deviceId, OG2, PATRICK, 'Alles Aus', 'DeviceStateScene', null, null, [1]), + new DeviceStateScene(++deviceId, deviceId, OG2, PATRICK, 'Rollläden Runter', 'DeviceStateScene', null, null, [40]), + + new DeviceStateScene(++deviceId, deviceId, OG2, KATRIN, 'Alles Aus', 'DeviceStateScene', null, null, [1]), + new DeviceStateScene(++deviceId, deviceId, OG2, KATRIN, 'Rollläden Runter', 'DeviceStateScene', null, null, [40]), + + new DeviceStateScene(++deviceId, deviceId, OG2, FLUR, 'Alles Aus', 'DeviceStateScene', null, null, [1]), + new DeviceStateScene(++deviceId, deviceId, OG2, FLUR, 'Rollläden Runter', 'DeviceStateScene', null, null, [40]), + + new DeviceStateScene(++deviceId, deviceId, OG1, ____, 'Alles Aus', 'DeviceStateScene', null, null, [1]), + new DeviceSwitch(++deviceId, deviceId, OG1, BAD, 'Licht', 'DeviceSwitch', null), + new DeviceStateScene(++deviceId, deviceId, OG1, BAD, 'Alles Aus', 'DeviceStateScene', null, null, [1]), +]; diff --git a/src/main/angular/src/app/api/area/Area.ts b/src/main/angular/src/app/api/area/Area.ts new file mode 100644 index 0000000..73667e8 --- /dev/null +++ b/src/main/angular/src/app/api/area/Area.ts @@ -0,0 +1,29 @@ +import {validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators"; + +export class Area { + + constructor( + readonly id: number, + readonly position: number, + readonly title: string, + ) { + // nothing + } + + static fromJson(json: any) { + return new Area( + validateNumberNotNull(json['id']), + validateNumberNotNull(json['position']), + validateStringNotEmptyNotNull(json['title']), + ); + } + + static comparePosition(a: Area, b: Area) { + return a.position - b.position; + } + + static filterById(id: number): (_: Area) => boolean { + return a => a.id === id; + } + +} diff --git a/src/main/angular/src/app/api/area/area.service.spec.ts b/src/main/angular/src/app/api/area/area.service.spec.ts new file mode 100644 index 0000000..746b0f2 --- /dev/null +++ b/src/main/angular/src/app/api/area/area.service.spec.ts @@ -0,0 +1,16 @@ +import {TestBed} from '@angular/core/testing'; + +import {AreaService} from './area.service'; + +describe('AreaService', () => { + let service: AreaService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AreaService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/main/angular/src/app/api/area/area.service.ts b/src/main/angular/src/app/api/area/area.service.ts new file mode 100644 index 0000000..ef4739f --- /dev/null +++ b/src/main/angular/src/app/api/area/area.service.ts @@ -0,0 +1,39 @@ +import {Injectable} from '@angular/core'; +import {ApiService, NO_COMPARE, NO_OP} from "../api.service"; +import {ISearchService} from "../ISearchService"; +import {SearchResult} from "../SearchResult"; +import {Update} from "../Update"; +import {Area} from "./Area"; + +@Injectable({ + providedIn: 'root' +}) +export class AreaService implements ISearchService { + + constructor( + readonly api: ApiService, + ) { + // nothing + } + + findAll(next: (list: Area[]) => void, compare: (a: Area, b: Area) => number = NO_COMPARE, error: (error: any) => void = NO_OP): void { + this.api.getList("area/findAll", Area.fromJson, compare, next, error); + } + + subscribe(next: (area: Update) => void): void { + this.api.subscribe("AreaDto", Area.fromJson, next); + } + + get(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { + this.api.getItem("area/getById/" + id, SearchResult.fromJson, next, error); + } + + search(term: string, next: (results: SearchResult[]) => void = NO_OP, error: (error: any) => void = NO_OP): void { + this.api.postReturnList("area/searchLike", term, SearchResult.fromJson, next, error); + } + + set(area: Area, key: string, value: any, next: (item: Area) => void = NO_OP, error: (error: any) => void = NO_OP): void { + this.api.postReturnItem("area/set/" + area.id + "/" + key, value, Area.fromJson, next, error); + } + +} diff --git a/src/main/angular/src/app/api/device/Device.ts b/src/main/angular/src/app/api/device/Device.ts index 0d80dd9..86d8a47 100644 --- a/src/main/angular/src/app/api/device/Device.ts +++ b/src/main/angular/src/app/api/device/Device.ts @@ -1,12 +1,15 @@ -import {validateListOrEmpty, validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators"; +import {validateListOrEmpty, validateNumberAllowNull, validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators"; import {Property} from "../property/Property"; export abstract class Device { - constructor( + protected constructor( readonly id: number, + readonly position: number, readonly title: string, readonly type: string, + readonly areaId: number | null, + readonly roomId: number | null, ) { // nothing } @@ -17,24 +20,34 @@ export abstract class Device { case "DeviceSwitch": return new DeviceSwitch( validateNumberNotNull(json['id']), + validateNumberAllowNull(json['position']) || 0, + validateNumberAllowNull(json['areaId']), + validateNumberAllowNull(json['roomId']), validateStringNotEmptyNotNull(json['title']), type, - Property.fromJsonAllowNull(json['stateProperty']), + Property.fromJsonAllowNull(json['stateProperty']) ); case "DeviceStateScene": return new DeviceStateScene( validateNumberNotNull(json['id']), + validateNumberAllowNull(json['position']) || 0, + validateNumberAllowNull(json['areaId']), + validateNumberAllowNull(json['roomId']), validateStringNotEmptyNotNull(json['title']), type, Property.fromJsonAllowNull(json['stateProperty']), Property.fromJsonAllowNull(json['sceneProperty']), - validateListOrEmpty(json['sceneNumbers'], validateNumberNotNull), + validateListOrEmpty(json['sceneNumbers'], + validateNumberNotNull) ); case "DeviceShutter": return new DeviceShutter( validateNumberNotNull(json['id']), + validateNumberAllowNull(json['position']) || 0, validateStringNotEmptyNotNull(json['title']), type, + validateNumberAllowNull(json['areaId']), + validateNumberAllowNull(json['roomId']), Property.fromJsonAllowNull(json['positionProperty']), ); } @@ -45,27 +58,30 @@ export abstract class Device { return item.title; } - public static compareTypeThenTitle(a: Device, b: Device): number { - const type: number = -a.type.localeCompare(b.type); - if (type !== 0) { - return type; - } - return a.title.localeCompare(b.title); + public static comparePosition(a: Device, b: Device): number { + return a.position - b.position; } abstract updateProperty(property: Property): void; + static filterByAreaIdAndRoomId(areaId: number | null, roomId: number | null): (_: Device) => boolean { + return d => d.areaId === areaId && d.roomId === roomId; + } + } export class DeviceSwitch extends Device { constructor( id: number, + position: number, + areaId: number | null, + roomId: number | null, title: string, type: string, public stateProperty: Property | null, ) { - super(id, title, type); + super(id, position, title, type, areaId, roomId); } updateProperty(property: Property): void { @@ -80,13 +96,16 @@ export class DeviceStateScene extends DeviceSwitch { constructor( id: number, + position: number, + areaId: number | null, + roomId: number | null, title: string, type: string, stateProperty: Property | null, public sceneProperty: Property | null, public sceneNumbers: number[], ) { - super(id, title, type, stateProperty); + super(id, position, areaId, roomId, title, type, stateProperty); } updateProperty(property: Property): void { @@ -102,11 +121,14 @@ export class DeviceShutter extends Device { constructor( id: number, + position: number, title: string, type: string, + areaId: number | null, + roomId: number | null, public positionProperty: Property | null, ) { - super(id, title, type); + super(id, position, title, type, areaId, roomId); } updateProperty(property: Property): void { diff --git a/src/main/angular/src/app/api/room/Room.ts b/src/main/angular/src/app/api/room/Room.ts new file mode 100644 index 0000000..c6032c8 --- /dev/null +++ b/src/main/angular/src/app/api/room/Room.ts @@ -0,0 +1,35 @@ +import {validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators"; + +export class Room { + + constructor( + readonly id: number, + readonly position: number, + readonly title: string, + readonly areaId: number, + ) { + // nothing + } + + static fromJson(json: any) { + return new Room( + validateNumberNotNull(json['id']), + validateNumberNotNull(json['position']), + validateStringNotEmptyNotNull(json['title']), + validateNumberNotNull(json['areaId']), + ); + } + + static comparePosition(a: Room, b: Room) { + return a.position - b.position; + } + + static filterByAreaId(areaId: number): (_: Room) => boolean { + return r => r.areaId === areaId; + } + + static filterById(id: number): (_: Room) => boolean { + return r => r.id === id; + } + +} diff --git a/src/main/angular/src/app/api/room/room.service.spec.ts b/src/main/angular/src/app/api/room/room.service.spec.ts new file mode 100644 index 0000000..627f402 --- /dev/null +++ b/src/main/angular/src/app/api/room/room.service.spec.ts @@ -0,0 +1,16 @@ +import {TestBed} from '@angular/core/testing'; + +import {RoomService} from './room.service'; + +describe('RoomService', () => { + let service: RoomService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(RoomService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/main/angular/src/app/api/room/room.service.ts b/src/main/angular/src/app/api/room/room.service.ts new file mode 100644 index 0000000..0e3623a --- /dev/null +++ b/src/main/angular/src/app/api/room/room.service.ts @@ -0,0 +1,39 @@ +import {Injectable} from '@angular/core'; +import {ApiService, NO_COMPARE, NO_OP} from "../api.service"; +import {ISearchService} from "../ISearchService"; +import {SearchResult} from "../SearchResult"; +import {Update} from "../Update"; +import {Room} from "./Room"; + +@Injectable({ + providedIn: 'root' +}) +export class RoomService implements ISearchService { + + constructor( + readonly api: ApiService, + ) { + // nothing + } + + findAll(next: (list: Room[]) => void, compare: (a: Room, b: Room) => number = NO_COMPARE, error: (error: any) => void = NO_OP): void { + this.api.getList("room/findAll", Room.fromJson, compare, next, error); + } + + subscribe(next: (room: Update) => void): void { + this.api.subscribe("RoomDto", Room.fromJson, next); + } + + get(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { + this.api.getItem("room/getById/" + id, SearchResult.fromJson, next, error); + } + + search(term: string, next: (results: SearchResult[]) => void = NO_OP, error: (error: any) => void = NO_OP): void { + this.api.postReturnList("room/searchLike", term, SearchResult.fromJson, next, error); + } + + set(room: Room, key: string, value: any, next: (item: Room) => void = NO_OP, error: (error: any) => void = NO_OP): void { + this.api.postReturnItem("room/set/" + room.id + "/" + key, value, Room.fromJson, next, error); + } + +} diff --git a/src/main/angular/src/app/api/validators.ts b/src/main/angular/src/app/api/validators.ts index 414830e..46ac792 100644 --- a/src/main/angular/src/app/api/validators.ts +++ b/src/main/angular/src/app/api/validators.ts @@ -75,11 +75,11 @@ export function validateListOrEmpty(json: any, fromJson: (json: any) => T, co return json.map(fromJson).sort(compare); } -export function validateMap(json: any, valueFromJson: (json: any) => T): Map { +export function validateMap(json: any, valueFromJson: (json: any) => T): Map { if (typeof json !== 'object') { throw new Error("Not a Map: " + json); } - const map = new Map(); + const map = new Map(); for (const key in json) { if (Object.prototype.hasOwnProperty.call(json, key)) { map.set(key, valueFromJson(json[key])); diff --git a/src/main/angular/src/app/app-routing.module.ts b/src/main/angular/src/app/app-routing.module.ts index 6befd68..8a5eabe 100644 --- a/src/main/angular/src/app/app-routing.module.ts +++ b/src/main/angular/src/app/app-routing.module.ts @@ -2,20 +2,28 @@ import {NgModule} from '@angular/core'; import {RouterModule, Routes} from '@angular/router'; import {ScheduleListComponent} from "./pages/schedule-list/schedule-list.component"; import {ScheduleComponent} from "./pages/schedule/schedule.component"; -import {DeviceListComponent} from "./pages/device-list/device-list.component"; +import {DeviceAllListComponent} from "./pages/device-all-list/device-all-list.component"; import {DeviceComponent} from "./pages/device/device.component"; import {PropertyListComponent} from "./pages/property-list/property-list.component"; import {ChannelListComponent} from "./pages/channel-list/channel-list.component"; +import {AreaListComponent} from "./pages/mobile/device-tree/area-list/area-list.component"; +import {RoomListComponent} from "./pages/mobile/device-tree/room-list/room-list.component"; +import {DeviceListComponent} from "./pages/mobile/device-tree/device-list/device-list.component"; const routes: Routes = [ {path: 'Device', component: DeviceComponent}, - {path: 'DeviceList', component: DeviceListComponent}, + {path: 'DeviceAllList', component: DeviceAllListComponent}, // {path: 'Channel', component: ChannelComponent}, {path: 'ChannelList', component: ChannelListComponent}, // {path: 'Property', component: PropertyComponent}, {path: 'PropertyList', component: PropertyListComponent}, {path: 'Schedule', component: ScheduleComponent}, {path: 'ScheduleList', component: ScheduleListComponent}, + + {path: 'AreaList', component: AreaListComponent}, + {path: 'RoomList', component: RoomListComponent}, + {path: 'DeviceList', component: DeviceListComponent}, + {path: '**', redirectTo: '/ScheduleList'}, ]; diff --git a/src/main/angular/src/app/app.component.html b/src/main/angular/src/app/app.component.html index 649ffc7..a87cc77 100644 --- a/src/main/angular/src/app/app.component.html +++ b/src/main/angular/src/app/app.component.html @@ -3,7 +3,7 @@
Zeitpläne
-
+
Geräte
diff --git a/src/main/angular/src/app/app.component.less b/src/main/angular/src/app/app.component.less index d18eb6b..f5129a4 100644 --- a/src/main/angular/src/app/app.component.less +++ b/src/main/angular/src/app/app.component.less @@ -26,7 +26,3 @@ } } - -.content { - margin: 10px; -} diff --git a/src/main/angular/src/app/app.module.ts b/src/main/angular/src/app/app.module.ts index 7539e54..960a845 100644 --- a/src/main/angular/src/app/app.module.ts +++ b/src/main/angular/src/app/app.module.ts @@ -11,10 +11,13 @@ import {FontAwesomeModule} from '@fortawesome/angular-fontawesome'; import {NumberComponent} from './shared/number/number.component'; import {ScheduleComponent} from "./pages/schedule/schedule.component"; import {SearchComponent} from './shared/search/search.component'; -import {DeviceListComponent} from './pages/device-list/device-list.component'; +import {DeviceAllListComponent} from './pages/device-all-list/device-all-list.component'; import {DeviceComponent} from './pages/device/device.component'; import {PropertyListComponent} from './pages/property-list/property-list.component'; import {ChannelListComponent} from './pages/channel-list/channel-list.component'; +import {AreaListComponent} from './pages/mobile/device-tree/area-list/area-list.component'; +import {RoomListComponent} from './pages/mobile/device-tree/room-list/room-list.component'; +import {DeviceListComponent} from './pages/mobile/device-tree/device-list/device-list.component'; @NgModule({ declarations: [ @@ -24,10 +27,13 @@ import {ChannelListComponent} from './pages/channel-list/channel-list.component' ScheduleListComponent, NumberComponent, SearchComponent, - DeviceListComponent, + DeviceAllListComponent, DeviceComponent, PropertyListComponent, ChannelListComponent, + AreaListComponent, + RoomListComponent, + DeviceListComponent, ], imports: [ BrowserModule, diff --git a/src/main/angular/src/app/pages/device-list/device-list.component.html b/src/main/angular/src/app/pages/device-all-list/device-all-list.component.html similarity index 96% rename from src/main/angular/src/app/pages/device-list/device-list.component.html rename to src/main/angular/src/app/pages/device-all-list/device-all-list.component.html index 3f546f6..16a62c1 100644 --- a/src/main/angular/src/app/pages/device-list/device-list.component.html +++ b/src/main/angular/src/app/pages/device-all-list/device-all-list.component.html @@ -6,7 +6,7 @@
- +
diff --git a/src/main/angular/src/app/pages/device-list/device-list.component.less b/src/main/angular/src/app/pages/device-all-list/device-all-list.component.less similarity index 100% rename from src/main/angular/src/app/pages/device-list/device-list.component.less rename to src/main/angular/src/app/pages/device-all-list/device-all-list.component.less diff --git a/src/main/angular/src/app/pages/device-all-list/device-all-list.component.spec.ts b/src/main/angular/src/app/pages/device-all-list/device-all-list.component.spec.ts new file mode 100644 index 0000000..d7e6234 --- /dev/null +++ b/src/main/angular/src/app/pages/device-all-list/device-all-list.component.spec.ts @@ -0,0 +1,25 @@ +import {ComponentFixture, TestBed} from '@angular/core/testing'; + +import {DeviceAllListComponent} from './device-all-list.component'; + +describe('DeviceAllListComponent', () => { + let component: DeviceAllListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [DeviceAllListComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DeviceAllListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/main/angular/src/app/pages/device-list/device-list.component.ts b/src/main/angular/src/app/pages/device-all-list/device-all-list.component.ts similarity index 94% rename from src/main/angular/src/app/pages/device-list/device-list.component.ts rename to src/main/angular/src/app/pages/device-all-list/device-all-list.component.ts index 4982dde..17e74e0 100644 --- a/src/main/angular/src/app/pages/device-list/device-list.component.ts +++ b/src/main/angular/src/app/pages/device-all-list/device-all-list.component.ts @@ -7,11 +7,11 @@ import {Scene} from "../../api/scene/Scene"; import {SceneService} from "../../api/scene/scene.service"; @Component({ - selector: 'app-device-list', - templateUrl: './device-list.component.html', - styleUrls: ['./device-list.component.less'] + selector: 'app-device-all-list', + templateUrl: './device-all-list.component.html', + styleUrls: ['./device-all-list.component.less'] }) -export class DeviceListComponent implements OnInit { +export class DeviceAllListComponent implements OnInit { readonly Device = Device; diff --git a/src/main/angular/src/app/pages/device/device.component.ts b/src/main/angular/src/app/pages/device/device.component.ts index 12f11ef..5ecb645 100644 --- a/src/main/angular/src/app/pages/device/device.component.ts +++ b/src/main/angular/src/app/pages/device/device.component.ts @@ -57,7 +57,7 @@ export class DeviceComponent implements OnInit { delete(): void { 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(["/DeviceAllList"])); } } diff --git a/src/main/angular/src/app/pages/mobile/device-tree/area-list/area-list.component.html b/src/main/angular/src/app/pages/mobile/device-tree/area-list/area-list.component.html new file mode 100644 index 0000000..44ebc46 --- /dev/null +++ b/src/main/angular/src/app/pages/mobile/device-tree/area-list/area-list.component.html @@ -0,0 +1,17 @@ +
+ +
+ Haus +
+ +
+ {{area.title}} + +
+ +
+ {{device.title}} + +
+ +
diff --git a/src/main/angular/src/app/pages/mobile/device-tree/area-list/area-list.component.spec.ts b/src/main/angular/src/app/pages/mobile/device-tree/area-list/area-list.component.spec.ts new file mode 100644 index 0000000..a6dac34 --- /dev/null +++ b/src/main/angular/src/app/pages/mobile/device-tree/area-list/area-list.component.spec.ts @@ -0,0 +1,25 @@ +import {ComponentFixture, TestBed} from '@angular/core/testing'; + +import {AreaListComponent} from './area-list.component'; + +describe('AreaListComponent', () => { + let component: AreaListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [AreaListComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AreaListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/main/angular/src/app/pages/mobile/device-tree/area-list/area-list.component.ts b/src/main/angular/src/app/pages/mobile/device-tree/area-list/area-list.component.ts new file mode 100644 index 0000000..12d489f --- /dev/null +++ b/src/main/angular/src/app/pages/mobile/device-tree/area-list/area-list.component.ts @@ -0,0 +1,27 @@ +import {Component, OnInit} from '@angular/core'; +import {Area} from "../../../../api/area/Area"; +import {Device} from "../../../../api/device/Device"; +import {faArrowAltCircleRight, faPlayCircle} from '@fortawesome/free-regular-svg-icons'; +import {STUB_AREAS, STUB_DEVICES} from "../../../../api/STUB"; + +@Component({ + selector: 'app-area-list', + templateUrl: './area-list.component.html', + styleUrls: ['../device-tree.less'] +}) +export class AreaListComponent implements OnInit { + + readonly faArrowAltCircleRight = faArrowAltCircleRight; + readonly faPlayCircle = faPlayCircle; + + areas: Area[] = STUB_AREAS.sort(Area.comparePosition); + + devices: Device[] = STUB_DEVICES.filter(d => d.areaId === null && d.roomId === null).sort(Device.comparePosition); + + constructor() { + } + + ngOnInit(): void { + } + +} diff --git a/src/main/angular/src/app/pages/mobile/device-tree/device-list/device-list.component.html b/src/main/angular/src/app/pages/mobile/device-tree/device-list/device-list.component.html new file mode 100644 index 0000000..01ae950 --- /dev/null +++ b/src/main/angular/src/app/pages/mobile/device-tree/device-list/device-list.component.html @@ -0,0 +1,24 @@ +
+ +
+ + | + {{room.title}} +
+ +
+ + {{device.title}} + + + + + + + + + + +
+ +
diff --git a/src/main/angular/src/app/pages/device-list/device-list.component.spec.ts b/src/main/angular/src/app/pages/mobile/device-tree/device-list/device-list.component.spec.ts similarity index 100% rename from src/main/angular/src/app/pages/device-list/device-list.component.spec.ts rename to src/main/angular/src/app/pages/mobile/device-tree/device-list/device-list.component.spec.ts diff --git a/src/main/angular/src/app/pages/mobile/device-tree/device-list/device-list.component.ts b/src/main/angular/src/app/pages/mobile/device-tree/device-list/device-list.component.ts new file mode 100644 index 0000000..f6eab13 --- /dev/null +++ b/src/main/angular/src/app/pages/mobile/device-tree/device-list/device-list.component.ts @@ -0,0 +1,46 @@ +import {Component, OnInit} from '@angular/core'; +import {ActivatedRoute} from "@angular/router"; +import {Device} from "../../../../api/device/Device"; +import {faArrowAltCircleLeft, faArrowAltCircleRight, faCheckCircle, faPlayCircle, faTimesCircle} from '@fortawesome/free-regular-svg-icons'; +import {STUB_DEVICES, STUB_ROOMS} from "../../../../api/STUB"; +import {Room} from "../../../../api/room/Room"; + +@Component({ + selector: 'app-device-list', + templateUrl: './device-list.component.html', + styleUrls: ['../device-tree.less'] +}) +export class DeviceListComponent implements OnInit { + + readonly faArrowAltCircleLeft = faArrowAltCircleLeft; + readonly faArrowAltCircleRight = faArrowAltCircleRight; + readonly faPlayCircle = faPlayCircle; + readonly faCheckCircle = faCheckCircle; + readonly faTimesCircle = faTimesCircle; + + room?: Room; + + devices: Device[] = []; + + constructor( + readonly route: ActivatedRoute, + ) { + this.route.paramMap.subscribe(params => { + const roomIdStr: string | null = params.get("roomId"); + if (roomIdStr != null) { + const roomId: number = parseInt(roomIdStr); + this.room = STUB_ROOMS.find(Room.filterById(roomId)); + if (this.room) { + this.devices = STUB_DEVICES.filter(Device.filterByAreaIdAndRoomId(this.room.areaId, this.room.id)).sort(Device.comparePosition); + } else { + this.devices = []; + } + } + }) + } + + ngOnInit(): void { + + } + +} diff --git a/src/main/angular/src/app/pages/mobile/device-tree/device-tree.less b/src/main/angular/src/app/pages/mobile/device-tree/device-tree.less new file mode 100644 index 0000000..0c0a01f --- /dev/null +++ b/src/main/angular/src/app/pages/mobile/device-tree/device-tree.less @@ -0,0 +1,34 @@ +.list { + font-size: 10vmin; + + .entry { + padding: 3vmin; + border-bottom: 1px solid black; + + .icon { + float: right; + margin-left: 3vmin; + } + } + + .area { + background-color: lightsteelblue; + } + + .area:active { + background-color: cornflowerblue; + } + + .device { + background-color: lightcyan; + } + + .DeviceSwitch { + background-color: gray; + } + + .device:active { + background-color: darkcyan; + } + +} diff --git a/src/main/angular/src/app/pages/mobile/device-tree/room-list/room-list.component.html b/src/main/angular/src/app/pages/mobile/device-tree/room-list/room-list.component.html new file mode 100644 index 0000000..ae3f4ae --- /dev/null +++ b/src/main/angular/src/app/pages/mobile/device-tree/room-list/room-list.component.html @@ -0,0 +1,15 @@ +
+
+ + | + {{area.title}} +
+
+ {{room.title}} + +
+
+ {{device.title}} + +
+
diff --git a/src/main/angular/src/app/pages/mobile/device-tree/room-list/room-list.component.spec.ts b/src/main/angular/src/app/pages/mobile/device-tree/room-list/room-list.component.spec.ts new file mode 100644 index 0000000..69176f8 --- /dev/null +++ b/src/main/angular/src/app/pages/mobile/device-tree/room-list/room-list.component.spec.ts @@ -0,0 +1,25 @@ +import {ComponentFixture, TestBed} from '@angular/core/testing'; + +import {RoomListComponent} from './room-list.component'; + +describe('RoomListComponent', () => { + let component: RoomListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [RoomListComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(RoomListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/main/angular/src/app/pages/mobile/device-tree/room-list/room-list.component.ts b/src/main/angular/src/app/pages/mobile/device-tree/room-list/room-list.component.ts new file mode 100644 index 0000000..ea0b302 --- /dev/null +++ b/src/main/angular/src/app/pages/mobile/device-tree/room-list/room-list.component.ts @@ -0,0 +1,44 @@ +import {Component, OnInit} from '@angular/core'; +import {ActivatedRoute} from "@angular/router"; +import {Room} from "../../../../api/room/Room"; +import {Device} from "../../../../api/device/Device"; +import {faArrowAltCircleLeft, faArrowAltCircleRight, faPlayCircle} from '@fortawesome/free-regular-svg-icons'; +import {STUB_AREAS, STUB_DEVICES, STUB_ROOMS} from "../../../../api/STUB"; +import {Area} from "../../../../api/area/Area"; + +@Component({ + selector: 'app-room-list', + templateUrl: './room-list.component.html', + styleUrls: ['../device-tree.less'] +}) +export class RoomListComponent implements OnInit { + + readonly faArrowAltCircleLeft = faArrowAltCircleLeft; + readonly faArrowAltCircleRight = faArrowAltCircleRight; + readonly faPlayCircle = faPlayCircle; + + area?: Area; + + rooms: Room[] = []; + + devices: Device[] = []; + + constructor( + readonly route: ActivatedRoute, + ) { + this.route.paramMap.subscribe(params => { + const areaIdStr: string | null = params.get("id"); + if (areaIdStr != null) { + const areaId: number = parseInt(areaIdStr); + this.area = STUB_AREAS.find(Area.filterById(areaId)); + this.rooms = STUB_ROOMS.filter(Room.filterByAreaId(areaId)).sort(Room.comparePosition); + this.devices = STUB_DEVICES.filter(Device.filterByAreaIdAndRoomId(areaId, null)).sort(Device.comparePosition); + } + }) + } + + ngOnInit(): void { + + } + +} diff --git a/src/main/java/de/ph87/homeautomation/Config.java b/src/main/java/de/ph87/homeautomation/Config.java index 5214b78..0cd7502 100644 --- a/src/main/java/de/ph87/homeautomation/Config.java +++ b/src/main/java/de/ph87/homeautomation/Config.java @@ -15,4 +15,6 @@ public class Config { private String timezone = "Europe/Berlin"; + private boolean insertDemoData = false; + } diff --git a/src/main/java/de/ph87/homeautomation/DemoDataService.java b/src/main/java/de/ph87/homeautomation/DemoDataService.java index fbf871c..212f708 100644 --- a/src/main/java/de/ph87/homeautomation/DemoDataService.java +++ b/src/main/java/de/ph87/homeautomation/DemoDataService.java @@ -4,6 +4,7 @@ import com.luckycatlabs.sunrisesunset.Zenith; import de.ph87.homeautomation.channel.Channel; import de.ph87.homeautomation.device.DeviceRepository; import de.ph87.homeautomation.device.DeviceWriteService; +import de.ph87.homeautomation.device.devices.DeviceDto; import de.ph87.homeautomation.knx.group.KnxGroup; import de.ph87.homeautomation.knx.group.KnxGroupReadService; import de.ph87.homeautomation.logic.Logic; @@ -13,6 +14,7 @@ import de.ph87.homeautomation.logic.LogicWriter; import de.ph87.homeautomation.property.Property; import de.ph87.homeautomation.property.PropertyRepository; import de.ph87.homeautomation.property.PropertyType; +import de.ph87.homeautomation.scene.SceneDto; import de.ph87.homeautomation.scene.SceneRepository; import de.ph87.homeautomation.scene.SceneWriteService; import de.ph87.homeautomation.schedule.Schedule; @@ -57,100 +59,106 @@ public class DemoDataService { private final LogicRepository logicRepository; + private final Config config; + public void insertDemoData() { -// final Property erdgeschoss = createProperty("Erdgeschoss", PropertyType.BOOLEAN, knx(0, 4, 2), null); -// final Property erdgeschoss_szene = createProperty("Erdgeschoss Szene", PropertyType.SCENE, null, knx(0, 0, 1)); -// final Property obergeschoss = createProperty("Obergeschoss", PropertyType.BOOLEAN, knx(0, 6, 6), null); -// final Property obergeschoss_szene = createProperty("Obergeschoss Szene", PropertyType.SCENE, null, knx(0, 3, 2)); -// -// final Property fernseher = createProperty("Fernseher", PropertyType.BOOLEAN, knx(0, 0, 20), knx(0, 0, 4)); -// final Property verstaerker = createProperty("Verstärker", PropertyType.BOOLEAN, knx(0, 3, 57), knx(0, 3, 56)); -// final Property aussendekoration = createProperty("Außendekoration", PropertyType.BOOLEAN, knx(0, 4, 12), knx(0, 4, 11)); -// final Property terrasse = createProperty("Terrasse Licht", PropertyType.BOOLEAN, knx(0, 4, 1), knx(0, 4, 0)); -// -// final Property ambiente_eg = createProperty("Ambiente EG", PropertyType.BOOLEAN, knx(0, 3, 81), knx(0, 3, 80)); -// final Property ambiente_og = createProperty("Ambiente OG", PropertyType.BOOLEAN, knx(0, 6, 2), knx(0, 6, 3)); + if (!config.isInsertDemoData()) { + return; + } -// final Property flur_eg_licht = createProperty("Flur EG Licht", PropertyType.BOOLEAN, knx(0, 4, 8), knx(0, 5, 14)); -// -// final Property wohnzimmer_rollladen = createProperty("Wohnzimmer Rollladen", PropertyType.SHUTTER, null, knx(0, 4, 24)); -// final Property schlafzimmer_rollladen = createProperty("Schlafzimmer Rollladen", PropertyType.SHUTTER, null, knx(0, 3, 3)); -// final Property flur_og_rollladen = createProperty("Flur OG Rollladen", PropertyType.SHUTTER, null, knx(0, 5, 13)); -// -// final Property helligkeit = createProperty("Helligkeit", PropertyType.LUX, knx(0, 5, 6), null); -// final Property szene_haus = createProperty("Szene Haus ", PropertyType.SCENE, null, knx(0, 0, 21)); + final Property erdgeschoss = createProperty("Erdgeschoss", PropertyType.BOOLEAN, knx(0, 4, 2), null); + final Property erdgeschoss_szene = createProperty("Erdgeschoss Szene", PropertyType.SCENE, null, knx(0, 0, 1)); + final Property obergeschoss = createProperty("Obergeschoss", PropertyType.BOOLEAN, knx(0, 6, 6), null); + final Property obergeschoss_szene = createProperty("Obergeschoss Szene", PropertyType.SCENE, null, knx(0, 3, 2)); -// final SceneDto alles_aus = sceneWriteService.create(1, "Alles AUS"); -// final SceneDto nachtlicht = sceneWriteService.create(2, "Nachtlicht"); -// final SceneDto aussendekoration_aus = sceneWriteService.create(30, "Außendekoration AUS"); -// final SceneDto aussendekoration_an = sceneWriteService.create(31, "Außendekoration AN"); -// -// deviceWriteService.createDeviceStateScene(erdgeschoss, erdgeschoss_szene, alles_aus); -// deviceWriteService.createDeviceStateScene(obergeschoss, obergeschoss_szene, alles_aus); -// -// deviceWriteService.createDeviceSwitch(fernseher); -// deviceWriteService.createDeviceSwitch(verstaerker); -// deviceWriteService.createDeviceSwitch(aussendekoration); -// deviceWriteService.createDeviceSwitch(terrasse); -// -// deviceWriteService.createDeviceSwitch(ambiente_eg); -// deviceWriteService.createDeviceSwitch(ambiente_og); + final Property fernseher = createProperty("Fernseher", PropertyType.BOOLEAN, knx(0, 0, 20), knx(0, 0, 4)); + final Property verstaerker = createProperty("Verstärker", PropertyType.BOOLEAN, knx(0, 3, 57), knx(0, 3, 56)); + final Property aussendekoration = createProperty("Außendekoration", PropertyType.BOOLEAN, knx(0, 4, 12), knx(0, 4, 11)); + final Property terrasse = createProperty("Terrasse Licht", PropertyType.BOOLEAN, knx(0, 4, 1), knx(0, 4, 0)); -// deviceWriteService.createDeviceSwitch(flur_eg_licht); -// -// deviceWriteService.createDeviceShutter(wohnzimmer_rollladen); -// deviceWriteService.createDeviceShutter(schlafzimmer_rollladen); -// deviceWriteService.createDeviceShutter(flur_og_rollladen); -// -// final Schedule scheduleEgFlurLicht = createSchedule(true, "EG Flur Licht", flur_eg_licht); -// createTime(scheduleEgFlurLicht, true, 1, 0, 0, MIN30, true); -// createTime(scheduleEgFlurLicht, true, 2, 0, 0, MIN30, false); -// createTime(scheduleEgFlurLicht, true, 7, 30, 0, MIN30, true); -// createTime(scheduleEgFlurLicht, true, 8, 30, 0, MIN30, false); -// createTime(scheduleEgFlurLicht, true, 13, 30, 0, MIN30, true); -// createTime(scheduleEgFlurLicht, true, 14, 30, 0, MIN30, false); -// createTime(scheduleEgFlurLicht, true, 19, 0, 0, MIN30, true); -// createTime(scheduleEgFlurLicht, true, 20, 0, 0, MIN30, false); -// scheduleRepository.save(scheduleEgFlurLicht); -// -// final Schedule scheduleEgAmbiente = createSchedule(false, "Ambiente EG", ambiente_eg); -// createTime(scheduleEgAmbiente, true, 7, 15, 0, MIN30, true); -// createTime(scheduleEgAmbiente, true, 9, 30, 0, MIN30, false); -// createSunset(scheduleEgAmbiente, true, Zenith.OFFICIAL, MIN30, true); -// createSunset(scheduleEgAmbiente, true, Zenith.ASTRONOMICAL, MIN30, false); -// scheduleRepository.save(scheduleEgAmbiente); -// -// final Schedule scheduleOgAmbiente = createSchedule(false, "Ambiente OG", ambiente_og); -// createTime(scheduleOgAmbiente, true, 7, 15, 0, MIN30, true); -// createTime(scheduleOgAmbiente, true, 9, 30, 0, MIN30, false); -// createSunset(scheduleOgAmbiente, true, Zenith.OFFICIAL, MIN30, true); -// createSunset(scheduleOgAmbiente, true, Zenith.ASTRONOMICAL, MIN30, false); -// scheduleRepository.save(scheduleOgAmbiente); -// -// final Schedule scheduleWohnzimmerRollladen = createSchedule(true, "Rollläden Wohnzimmer", wohnzimmer_rollladen); -// createSunrise(scheduleWohnzimmerRollladen, true, BETWEEN_OFFICIAL_AND_CIVIL, 0, 0); -// createSunset(scheduleWohnzimmerRollladen, true, BETWEEN_OFFICIAL_AND_CIVIL, 0, 100); -// scheduleRepository.save(scheduleWohnzimmerRollladen); -// -// final Schedule scheduleSchlafzimmerRollladen = createSchedule(true, "Rollläden Schlafzimmer", schlafzimmer_rollladen); -// createTime(scheduleSchlafzimmerRollladen, true, 7, 0, 0, 0, 0); -// createSunset(scheduleSchlafzimmerRollladen, true, BETWEEN_OFFICIAL_AND_CIVIL, 0, 100); -// scheduleRepository.save(scheduleSchlafzimmerRollladen); -// -// final Schedule scheduleFlurRollladen = createSchedule(true, "Rollladen Flur", flur_og_rollladen); -// createSunrise(scheduleFlurRollladen, true, BETWEEN_OFFICIAL_AND_CIVIL, 0, 0); -// createSunset(scheduleFlurRollladen, true, BETWEEN_OFFICIAL_AND_CIVIL, 0, 100); -// scheduleRepository.save(scheduleFlurRollladen); -// -// final Schedule scheduleSzeneHaus = createSchedule(true, "Dekoration", szene_haus); -// createTime(scheduleSzeneHaus, true, 6, 0, 0, 0, 31); -// createTime(scheduleSzeneHaus, true, 8, 30, 0, 0, 30); -// createSunset(scheduleSzeneHaus, true, Zenith.OFFICIAL, 0, 31); -// createTime(scheduleSzeneHaus, true, 22, 0, 0, 0, 30); -// scheduleRepository.save(scheduleSzeneHaus); -// -// final Property propertyBadLicht = createProperty("Bad Licht", PropertyType.BOOLEAN, knx(0, 5, 19), knx(0, 3, 73)); -// final DeviceDto deviceBadLicht = deviceWriteService.createDeviceSwitch(propertyBadLicht); + final Property ambiente_eg = createProperty("Ambiente EG", PropertyType.BOOLEAN, knx(0, 3, 81), knx(0, 3, 80)); + final Property ambiente_og = createProperty("Ambiente OG", PropertyType.BOOLEAN, knx(0, 6, 2), knx(0, 6, 3)); + + final Property flur_eg_licht = createProperty("Flur EG Licht", PropertyType.BOOLEAN, knx(0, 4, 8), knx(0, 5, 14)); + + final Property wohnzimmer_rollladen = createProperty("Wohnzimmer Rollladen", PropertyType.SHUTTER, null, knx(0, 4, 24)); + final Property schlafzimmer_rollladen = createProperty("Schlafzimmer Rollladen", PropertyType.SHUTTER, null, knx(0, 3, 3)); + final Property flur_og_rollladen = createProperty("Flur OG Rollladen", PropertyType.SHUTTER, null, knx(0, 5, 13)); + + final Property helligkeit = createProperty("Helligkeit", PropertyType.LUX, knx(0, 5, 6), null); + final Property szene_haus = createProperty("Szene Haus ", PropertyType.SCENE, null, knx(0, 0, 21)); + + final SceneDto alles_aus = sceneWriteService.create(1, "Alles AUS"); + final SceneDto nachtlicht = sceneWriteService.create(2, "Nachtlicht"); + final SceneDto aussendekoration_aus = sceneWriteService.create(30, "Außendekoration AUS"); + final SceneDto aussendekoration_an = sceneWriteService.create(31, "Außendekoration AN"); + + deviceWriteService.createDeviceStateScene(erdgeschoss, erdgeschoss_szene, alles_aus); + deviceWriteService.createDeviceStateScene(obergeschoss, obergeschoss_szene, alles_aus); + + deviceWriteService.createDeviceSwitch(fernseher); + deviceWriteService.createDeviceSwitch(verstaerker); + deviceWriteService.createDeviceSwitch(aussendekoration); + deviceWriteService.createDeviceSwitch(terrasse); + + deviceWriteService.createDeviceSwitch(ambiente_eg); + deviceWriteService.createDeviceSwitch(ambiente_og); + + deviceWriteService.createDeviceSwitch(flur_eg_licht); + + deviceWriteService.createDeviceShutter(wohnzimmer_rollladen); + deviceWriteService.createDeviceShutter(schlafzimmer_rollladen); + deviceWriteService.createDeviceShutter(flur_og_rollladen); + + final Schedule scheduleEgFlurLicht = createSchedule(true, "EG Flur Licht", flur_eg_licht); + createTime(scheduleEgFlurLicht, true, 1, 0, 0, MIN30, true); + createTime(scheduleEgFlurLicht, true, 2, 0, 0, MIN30, false); + createTime(scheduleEgFlurLicht, true, 7, 30, 0, MIN30, true); + createTime(scheduleEgFlurLicht, true, 8, 30, 0, MIN30, false); + createTime(scheduleEgFlurLicht, true, 13, 30, 0, MIN30, true); + createTime(scheduleEgFlurLicht, true, 14, 30, 0, MIN30, false); + createTime(scheduleEgFlurLicht, true, 19, 0, 0, MIN30, true); + createTime(scheduleEgFlurLicht, true, 20, 0, 0, MIN30, false); + scheduleRepository.save(scheduleEgFlurLicht); + + final Schedule scheduleEgAmbiente = createSchedule(false, "Ambiente EG", ambiente_eg); + createTime(scheduleEgAmbiente, true, 7, 15, 0, MIN30, true); + createTime(scheduleEgAmbiente, true, 9, 30, 0, MIN30, false); + createSunset(scheduleEgAmbiente, true, Zenith.OFFICIAL, MIN30, true); + createSunset(scheduleEgAmbiente, true, Zenith.ASTRONOMICAL, MIN30, false); + scheduleRepository.save(scheduleEgAmbiente); + + final Schedule scheduleOgAmbiente = createSchedule(false, "Ambiente OG", ambiente_og); + createTime(scheduleOgAmbiente, true, 7, 15, 0, MIN30, true); + createTime(scheduleOgAmbiente, true, 9, 30, 0, MIN30, false); + createSunset(scheduleOgAmbiente, true, Zenith.OFFICIAL, MIN30, true); + createSunset(scheduleOgAmbiente, true, Zenith.ASTRONOMICAL, MIN30, false); + scheduleRepository.save(scheduleOgAmbiente); + + final Schedule scheduleWohnzimmerRollladen = createSchedule(true, "Rollläden Wohnzimmer", wohnzimmer_rollladen); + createSunrise(scheduleWohnzimmerRollladen, true, BETWEEN_OFFICIAL_AND_CIVIL, 0, 0); + createSunset(scheduleWohnzimmerRollladen, true, BETWEEN_OFFICIAL_AND_CIVIL, 0, 100); + scheduleRepository.save(scheduleWohnzimmerRollladen); + + final Schedule scheduleSchlafzimmerRollladen = createSchedule(true, "Rollläden Schlafzimmer", schlafzimmer_rollladen); + createTime(scheduleSchlafzimmerRollladen, true, 7, 0, 0, 0, 0); + createSunset(scheduleSchlafzimmerRollladen, true, BETWEEN_OFFICIAL_AND_CIVIL, 0, 100); + scheduleRepository.save(scheduleSchlafzimmerRollladen); + + final Schedule scheduleFlurRollladen = createSchedule(true, "Rollladen Flur", flur_og_rollladen); + createSunrise(scheduleFlurRollladen, true, BETWEEN_OFFICIAL_AND_CIVIL, 0, 0); + createSunset(scheduleFlurRollladen, true, BETWEEN_OFFICIAL_AND_CIVIL, 0, 100); + scheduleRepository.save(scheduleFlurRollladen); + + final Schedule scheduleSzeneHaus = createSchedule(true, "Dekoration", szene_haus); + createTime(scheduleSzeneHaus, true, 6, 0, 0, 0, 31); + createTime(scheduleSzeneHaus, true, 8, 30, 0, 0, 30); + createSunset(scheduleSzeneHaus, true, Zenith.OFFICIAL, 0, 31); + createTime(scheduleSzeneHaus, true, 22, 0, 0, 0, 30); + scheduleRepository.save(scheduleSzeneHaus); + + final Property propertyBadLicht = createProperty("Bad Licht", PropertyType.BOOLEAN, knx(0, 5, 19), knx(0, 3, 73)); + final DeviceDto deviceBadLicht = deviceWriteService.createDeviceSwitch(propertyBadLicht); // final Logic logicStatusOg = getOrCreateLogic("Status OG", LogicOperator.OR, propertyBadLicht); // final Property propertyStatusOg = createProperty(logicStatusOg.getName(), PropertyType.BOOLEAN, logicStatusOg, null); // final DeviceDto deviceStatusOg = deviceWriteService.createDeviceSwitch(propertyStatusOg); diff --git a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupImportService.java b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupImportService.java index a2e4491..ba610ec 100644 --- a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupImportService.java +++ b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupImportService.java @@ -32,9 +32,15 @@ public class KnxGroupImportService { private void importGroup(final Element ga) { final GroupAddress address = new GroupAddress(Integer.parseInt(ga.attr("Address"))); + final String name = ga.attr("Name"); + final String datapointType = ga.attr("DatapointType"); + if (datapointType.isEmpty()) { + log.warn("Cannot import Group without DPT: {} \"{}\"", address, name); + return; + } final KnxGroup knxGroup = knxGroupRepository.findByAddressRaw(address.getRawAddress()).orElseGet(() -> knxGroupRepository.save(new KnxGroup(address))); - setDpt(knxGroup, ga.attr("DatapointType")); - knxGroup.setName(ga.attr("Name")); + setDpt(knxGroup, datapointType); + knxGroup.setName(name); knxGroup.setDescription(ga.attr("Description")); knxGroup.setPuid(Integer.parseInt(ga.attr("Puid"))); knxGroup.setEts(true);