Skip to content

Commit

Permalink
Merge pull request #945 from Feilner/master
Browse files Browse the repository at this point in the history
Add UI Accessory support for Door and Window
  • Loading branch information
oznu committed Nov 10, 2020
2 parents 9a28be2 + c22d083 commit 3e439f7
Show file tree
Hide file tree
Showing 17 changed files with 358 additions and 0 deletions.
14 changes: 14 additions & 0 deletions ui/src/app/core/accessories/accessories.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ import { HumiditysensorComponent } from './types/humiditysensor/humiditysensor.c
import { AirqualitysensorComponent } from './types/airqualitysensor/airqualitysensor.component';
import { WindowcoveringComponent } from './types/windowcovering/windowcovering.component';
import { WindowcoveringManageComponent } from './types/windowcovering/windowcovering.manage.component';
import { WindowComponent } from './types/window/window.component';
import { WindowManageComponent } from './types/window/window.manage.component';
import { DoorComponent } from './types/door/door.component';
import { DoorManageComponent } from './types/door/door.manage.component';
import { TelevisionComponent } from './types/television/television.component';
import { ContactsensorComponent } from './types/contactsensor/contactsensor.component';
import { BatteryserviceComponent } from './types/batteryservice/batteryservice.component';
Expand All @@ -57,6 +61,8 @@ import { InfoModalComponent } from './info-modal/info-modal.component';
FanManageComponent,
Fanv2ManageComponent,
WindowcoveringManageComponent,
WindowManageComponent,
DoorManageComponent,
SpeakerManageComponent,
SecuritysystemManageComponent,
ValveManageComponent,
Expand Down Expand Up @@ -86,6 +92,10 @@ import { InfoModalComponent } from './info-modal/info-modal.component';
AirqualitysensorComponent,
WindowcoveringComponent,
WindowcoveringManageComponent,
WindowComponent,
WindowManageComponent,
DoorComponent,
DoorManageComponent,
TelevisionComponent,
ContactsensorComponent,
BatteryserviceComponent,
Expand Down Expand Up @@ -135,6 +145,10 @@ import { InfoModalComponent } from './info-modal/info-modal.component';
AirqualitysensorComponent,
WindowcoveringComponent,
WindowcoveringManageComponent,
WindowComponent,
WindowManageComponent,
DoorComponent,
DoorManageComponent,
TelevisionComponent,
ContactsensorComponent,
BatteryserviceComponent,
Expand Down
24 changes: 24 additions & 0 deletions ui/src/app/core/accessories/types/door/door.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<div class="accessory-box" [ngClass]="{'switch-on': service.values.TargetPosition}" appLongclick
(longclick)="onLongClick()" (shortclick)="onClick()">
<div class="d-flex flex-column h-100">
<div *ngIf="!service.values.TargetPosition" [inlineSVG]="'/assets/hap-icons/door-closed.svg'"
aria-label="Door " class="accessory-svg"></div>
<div *ngIf="service.values.TargetPosition" [inlineSVG]="'/assets/hap-icons/door-open.svg'"
aria-label="Door " class="accessory-svg"></div>
<div class="accessory-label mt-auto">{{ service.customName || service.serviceName }}</div>
<div class="accessory-label grey-text" *ngIf="service.values.PositionState === 2">
<span *ngIf="service.values.CurrentPosition === 0">{{ 'accessories.control.label_closed' | translate }}</span>
<span *ngIf="service.values.CurrentPosition > 0 && service.values.CurrentPosition < 100">
{{ service.values.CurrentPosition }}% {{ 'accessories.control.label_open' | translate }}
</span>
<span *ngIf="service.values.CurrentPosition === 100">{{ 'accessories.control.label_open' | translate }}</span>
</div>
<div class="accessory-label red-text" *ngIf="service.values.PositionState === 1">
{{ 'accessories.control.label_opening' | translate }}...
</div>
<div class="accessory-label red-text" *ngIf="service.values.PositionState === 0">
{{ 'accessories.control.label_closing' | translate }}...
</div>
</div>
</div>

7 changes: 7 additions & 0 deletions ui/src/app/core/accessories/types/door/door.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.door-mode-control {
.btn {
font-size: 1.4rem;
text-transform: initial;
}
}

36 changes: 36 additions & 0 deletions ui/src/app/core/accessories/types/door/door.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Component, OnInit, Input } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ServiceTypeX } from '../../accessories.interfaces';

import { DoorManageComponent } from './door.manage.component';

@Component({
selector: 'app-door',
templateUrl: './door.component.html',
styleUrls: ['./door.component.scss'],
})
export class DoorComponent implements OnInit {
@Input() public service: ServiceTypeX;

constructor(
private modalService: NgbModal,
) { }

ngOnInit() { }

onClick() {
if (this.service.values.TargetPosition) {
this.service.getCharacteristic('TargetPosition').setValue(0);
} else {
this.service.getCharacteristic('TargetPosition').setValue(100);
}
}

onLongClick() {
const ref = this.modalService.open(DoorManageComponent, {
size: 'sm',
});
ref.componentInstance.service = this.service;
}

}
36 changes: 36 additions & 0 deletions ui/src/app/core/accessories/types/door/door.manage.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" [innerText]="service.customName || service.serviceName"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"
(click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body text-center">

<h5>
<strong>
<div *ngIf="service.values.PositionState === 2">
<span *ngIf="service.values.CurrentPosition === 0">{{ 'accessories.control.label_closed' | translate }}</span>
<span *ngIf="service.values.CurrentPosition > 0 && service.values.CurrentPosition < 100">
{{ service.values.CurrentPosition }}% {{ 'accessories.control.label_open' | translate }}
</span>
<span *ngIf="service.values.CurrentPosition === 100">Open</span>
</div>
<div class="red-text" *ngIf="service.values.PositionState === 1">
{{ 'accessories.control.label_opening' | translate }}...
</div>
<div class="red-text" *ngIf="service.values.PositionState === 0">
{{ 'accessories.control.label_closing' | translate }}...
</div>
</strong>
</h5>

<p>{{ 'accessories.control.label_target' | translate }}: {{ targetPosition.value }}%</p>
<nouislider [min]="targetPosition.min" [max]="targetPosition.max" [step]="targetPosition.step"
[(ngModel)]="targetPosition.value" (ngModelChange)="onTargetPositionChange()">
</nouislider>

</div>
</div>

59 changes: 59 additions & 0 deletions ui/src/app/core/accessories/types/door/door.manage.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Component, OnInit, Input } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { ServiceTypeX } from '../../accessories.interfaces';

import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';

@Component({
selector: 'app-door-manage',
templateUrl: './door.manage.component.html',
styleUrls: ['./door.component.scss'],
})
export class DoorManageComponent implements OnInit {
@Input() public service: ServiceTypeX;
public targetMode: any;
public targetPosition: any;
public targetPositionChanged: Subject<string> = new Subject<string>();

constructor(
public activeModal: NgbActiveModal,
) {
this.targetPositionChanged
.pipe(
debounceTime(300),
distinctUntilChanged(),
)
.subscribe((value) => {
if (this.service.getCharacteristic('CurrentPosition').value < this.targetPosition.value) {
this.service.values.PositionState = 1;
} else if (this.service.getCharacteristic('CurrentPosition').value > this.targetPosition.value) {
this.service.values.PositionState = 0;
}
this.service.getCharacteristic('TargetPosition').setValue(this.targetPosition.value);
});
}

ngOnInit() {
this.targetMode = this.service.values.On;
this.loadTargetPosition();
}

loadTargetPosition() {
const TargetPosition = this.service.getCharacteristic('TargetPosition');

if (TargetPosition) {
this.targetPosition = {
value: TargetPosition.value,
min: TargetPosition.minValue,
max: TargetPosition.maxValue,
step: TargetPosition.minStep,
};
}
}

onTargetPositionChange() {
this.targetPositionChanged.next(this.targetPosition.value);
}

}
24 changes: 24 additions & 0 deletions ui/src/app/core/accessories/types/window/window.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<div class="accessory-box" [ngClass]="{'switch-on': service.values.TargetPosition}" appLongclick
(longclick)="onLongClick()" (shortclick)="onClick()">
<div class="d-flex flex-column h-100">
<div *ngIf="!service.values.TargetPosition" [inlineSVG]="'/assets/hap-icons/window-closed.svg'"
aria-label="Window " class="accessory-svg"></div>
<div *ngIf="service.values.TargetPosition" [inlineSVG]="'/assets/hap-icons/window-open.svg'"
aria-label="Window " class="accessory-svg"></div>
<div class="accessory-label mt-auto">{{ service.customName || service.serviceName }}</div>
<div class="accessory-label grey-text" *ngIf="service.values.PositionState === 2">
<span *ngIf="service.values.CurrentPosition === 0">{{ 'accessories.control.label_closed' | translate }}</span>
<span *ngIf="service.values.CurrentPosition > 0 && service.values.CurrentPosition < 100">
{{ service.values.CurrentPosition }}% {{ 'accessories.control.label_open' | translate }}
</span>
<span *ngIf="service.values.CurrentPosition === 100">{{ 'accessories.control.label_open' | translate }}</span>
</div>
<div class="accessory-label red-text" *ngIf="service.values.PositionState === 1">
{{ 'accessories.control.label_opening' | translate }}...
</div>
<div class="accessory-label red-text" *ngIf="service.values.PositionState === 0">
{{ 'accessories.control.label_closing' | translate }}...
</div>
</div>
</div>

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.window-mode-control {
.btn {
font-size: 1.4rem;
text-transform: initial;
}
}

36 changes: 36 additions & 0 deletions ui/src/app/core/accessories/types/window/window.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Component, OnInit, Input } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ServiceTypeX } from '../../accessories.interfaces';

import { WindowManageComponent } from './window.manage.component';

@Component({
selector: 'app-window',
templateUrl: './window.component.html',
styleUrls: ['./window.component.scss'],
})
export class WindowComponent implements OnInit {
@Input() public service: ServiceTypeX;

constructor(
private modalService: NgbModal,
) { }

ngOnInit() { }

onClick() {
if (this.service.values.TargetPosition) {
this.service.getCharacteristic('TargetPosition').setValue(0);
} else {
this.service.getCharacteristic('TargetPosition').setValue(100);
}
}

onLongClick() {
const ref = this.modalService.open(WindowManageComponent, {
size: 'sm',
});
ref.componentInstance.service = this.service;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" [innerText]="service.customName || service.serviceName"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"
(click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body text-center">

<h5>
<strong>
<div *ngIf="service.values.PositionState === 2">
<span *ngIf="service.values.CurrentPosition === 0">{{ 'accessories.control.label_closed' | translate }}</span>
<span *ngIf="service.values.CurrentPosition > 0 && service.values.CurrentPosition < 100">
{{ service.values.CurrentPosition }}% {{ 'accessories.control.label_open' | translate }}
</span>
<span *ngIf="service.values.CurrentPosition === 100">Open</span>
</div>
<div class="red-text" *ngIf="service.values.PositionState === 1">
{{ 'accessories.control.label_opening' | translate }}...
</div>
<div class="red-text" *ngIf="service.values.PositionState === 0">
{{ 'accessories.control.label_closing' | translate }}...
</div>
</strong>
</h5>

<p>{{ 'accessories.control.label_target' | translate }}: {{ targetPosition.value }}%</p>
<nouislider [min]="targetPosition.min" [max]="targetPosition.max" [step]="targetPosition.step"
[(ngModel)]="targetPosition.value" (ngModelChange)="onTargetPositionChange()">
</nouislider>

</div>
</div>

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Component, OnInit, Input } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { ServiceTypeX } from '../../accessories.interfaces';

import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';

@Component({
selector: 'app-window-manage',
templateUrl: './window.manage.component.html',
styleUrls: ['./window.component.scss'],
})
export class WindowManageComponent implements OnInit {
@Input() public service: ServiceTypeX;
public targetMode: any;
public targetPosition: any;
public targetPositionChanged: Subject<string> = new Subject<string>();

constructor(
public activeModal: NgbActiveModal,
) {
this.targetPositionChanged
.pipe(
debounceTime(300),
distinctUntilChanged(),
)
.subscribe((value) => {
if (this.service.getCharacteristic('CurrentPosition').value < this.targetPosition.value) {
this.service.values.PositionState = 1;
} else if (this.service.getCharacteristic('CurrentPosition').value > this.targetPosition.value) {
this.service.values.PositionState = 0;
}
this.service.getCharacteristic('TargetPosition').setValue(this.targetPosition.value);
});
}

ngOnInit() {
this.targetMode = this.service.values.On;
this.loadTargetPosition();
}

loadTargetPosition() {
const TargetPosition = this.service.getCharacteristic('TargetPosition');

if (TargetPosition) {
this.targetPosition = {
value: TargetPosition.value,
min: TargetPosition.minValue,
max: TargetPosition.maxValue,
step: TargetPosition.minStep,
};
}
}

onTargetPositionChange() {
this.targetPositionChanged.next(this.targetPosition.value);
}

}
4 changes: 4 additions & 0 deletions ui/src/app/modules/accessories/accessories.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ <h5 class="primary-text drag-handle room-title" [ngClass]="{'cursor-move': !isMo
</app-airqualitysensor>
<app-windowcovering *ngSwitchCase="'WindowCovering'" [service]="service">Window Covering
</app-windowcovering>
<app-window *ngSwitchCase="'Window'" [service]="service">Window
</app-window>
<app-door *ngSwitchCase="'Door'" [service]="service">Door
</app-door>
<app-television *ngSwitchCase="'Television'" [service]="service">Television
</app-television>
<app-batteryservice *ngSwitchCase="'BatteryService'" [service]="service">BatteryService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
</app-airqualitysensor>
<app-windowcovering *ngSwitchCase="'WindowCovering'" [service]="service">Window Covering
</app-windowcovering>
<app-window *ngSwitchCase="'Window'" [service]="service">Window
</app-window>
<app-door *ngSwitchCase="'Door'" [service]="service">Door
</app-door>
<app-television *ngSwitchCase="'Television'" [service]="service">Television
</app-television>
<app-securitysystem *ngSwitchCase="'SecuritySystem'" [service]="service">Security System
Expand Down
Loading

0 comments on commit 3e439f7

Please sign in to comment.