Skip to content

Commit

Permalink
Merge pull request #141 from casanet/development
Browse files Browse the repository at this point in the history
Add "SHABBAT-MODE"
  • Loading branch information
haimkastner authored Jun 1, 2020
2 parents a399478 + 0a2d346 commit 5ae9636
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 45 deletions.
8 changes: 6 additions & 2 deletions backend/src/business-layer/calibrateBl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class CalibrateBl {
if (
this.lastCalibrateMap[minion.minionId] &&
now.getTime() - this.lastCalibrateMap[minion.minionId].getTime() <
moment.duration(minion.calibration.calibrationCycleMinutes, 'minutes').asMilliseconds()
moment.duration(minion.calibration.calibrationCycleMinutes, 'minutes').asMilliseconds()
) {
continue;
}
Expand All @@ -59,7 +59,7 @@ export class CalibrateBl {
}

private async calibrateMinion(minion: Minion) {
// In case that minion dont have any status
// In case that minion don't have any status
const emptyStatus: MinionStatus = {};
emptyStatus[minion.minionType] = ({} as unknown) as any;
emptyStatus[minion.minionType].status = 'off';
Expand All @@ -76,6 +76,9 @@ export class CalibrateBl {
case 'LOCK_OFF':
minionStatus[minion.minionType].status = 'off';
break;
case 'SHABBAT':
minionStatus[minion.minionType].status = minionStatus[minion.minionType].status === 'off' ? 'on' : 'off';
break;
default:
break;
}
Expand Down Expand Up @@ -129,6 +132,7 @@ export class CalibrateBl {
legalStatus = 'off';
break;
case 'AUTO':
case 'SHABBAT':
legalStatus = minion.minionStatus[minion.minionType]?.status || 'on';
break;
default:
Expand Down
23 changes: 18 additions & 5 deletions backend/src/business-layer/operationsBl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class OperationsBl {
* @param operationsDal Inject operations dal.
* @param localNetworkReader Inject the reader function.
*/
constructor(private operationsDal: OperationsDal, private minionsBl: MinionsBl) {}
constructor(private operationsDal: OperationsDal, private minionsBl: MinionsBl) { }

/**
* API
Expand Down Expand Up @@ -131,11 +131,24 @@ export class OperationsBl {
}
}

if (options.lockStatus) {
// If need to set 'Sabbat' lock, set it.
if (options.shabbatMode) {
try {
await this.minionsBl.setMinionCalibrate(activity.minionId, {
calibrationCycleMinutes: Configuration.defaultLockCalibrationMinutes,
calibrationMode: activity.minionStatus[minion.minionType].status === 'on' ? 'LOCK_ON' : 'LOCK_OFF',
calibrationMode: 'SHABBAT',
});
} catch (error) {
logger.error(`[operation] Fail to set minion "${activity.minionId}" operation activity lock`);
}
// Else if need to set a 'lock', select the correct lock depend on the 'set status' value
} else if (options.lockStatus) {
try {
await this.minionsBl.setMinionCalibrate(activity.minionId, {
calibrationCycleMinutes: Configuration.defaultLockCalibrationMinutes,
calibrationMode: activity.minionStatus[minion.minionType].status === 'on'
? 'LOCK_ON'
: 'LOCK_OFF',
});
} catch (error) {
logger.error(`[operation] Fail to set minion "${activity.minionId}" operation activity lock`);
Expand All @@ -148,8 +161,8 @@ export class OperationsBl {
} catch (error) {
logger.warn(
`Setting minion ${activity.minionId} a new status by operation activity data: ` +
`${JSON.stringify(activity.minionStatus)} fail, ` +
`${JSON.stringify(error)}`,
`${JSON.stringify(activity.minionStatus)} fail, ` +
`${JSON.stringify(error)}`,
);
}

Expand Down
4 changes: 2 additions & 2 deletions backend/src/business-layer/timingsBl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ export class TimingsBl {
private async activeTiming(timing: Timing): Promise<void> {
logger.info(`Invoke ${timing.timingName} id: ${timing.timingId} timing starting...`);

const { overrideLock, lockStatus } = timing;
const { overrideLock, lockStatus, shabbatMode } = timing;
try {
const results = await this.operationBl.triggerOperation(timing.triggerOperationId, { overrideLock, lockStatus });
const results = await this.operationBl.triggerOperation(timing.triggerOperationId, { overrideLock, lockStatus, shabbatMode });
logger.info(`Invoke ${timing.timingName} id: ${timing.timingId} timing done`);

this.timingFeed.next({
Expand Down
1 change: 1 addition & 0 deletions backend/src/models/backendInterfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export declare type RunningMode = 'prod' | 'test' | 'debug';
export declare interface SetLockOptions {
lockStatus?: boolean;
overrideLock?: boolean;
shabbatMode?: boolean;
}

/** Config structure for all system */
Expand Down
6 changes: 6 additions & 0 deletions backend/src/models/sharedInterfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ export declare type CalibrationMode =
| 'LOCK_ON'
/** Lock device to 'off' mode even if its will changed by the physical interface */
| 'LOCK_OFF'
/** Shabbat mode used to turn off/on in interval, so the Sabbat keepers can wait to the wanted state */
| 'SHABBAT'
/**
* Just make sure that casanet and the physical device have the same status
* By sending the last casanet status to the device.
Expand Down Expand Up @@ -661,6 +663,10 @@ export declare interface Timing {
*/
lockStatus?: boolean;

/**
* Set minion lock to be Shabbat mode
*/
shabbatMode?: boolean;
/**
* Override lock, if exists (default false)
*/
Expand Down
3 changes: 2 additions & 1 deletion backend/src/routers/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const models: TsoaRoute.Models = {
"MinionCalibrate": {
"properties": {
"calibrationCycleMinutes": { "dataType": "integer", "required": true, "validators": { "minimum": { "value": 0 }, "isInt": { "errorMsg": "true" } } },
"calibrationMode": { "dataType": "enum", "enums": ["LOCK_ON", "LOCK_OFF", "AUTO"], "required": true },
"calibrationMode": { "dataType": "enum", "enums": ["LOCK_ON", "LOCK_OFF", "SHABBAT", "AUTO"], "required": true },
},
},
"Minion": {
Expand Down Expand Up @@ -181,6 +181,7 @@ const models: TsoaRoute.Models = {
"timingType": { "dataType": "enum", "enums": ["dailySunTrigger", "dailyTimeTrigger", "once", "timeout"], "required": true },
"timingProperties": { "ref": "TimingProperties", "required": true },
"lockStatus": { "dataType": "boolean" },
"shabbatMode": { "dataType": "boolean" },
"overrideLock": { "dataType": "boolean" },
},
},
Expand Down
5 changes: 5 additions & 0 deletions backend/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ definitions:
enum:
- LOCK_ON
- LOCK_OFF
- SHABBAT
- AUTO
description: 'The calibration mode to calibrate'
required:
Expand Down Expand Up @@ -511,6 +512,10 @@ definitions:
type: boolean
description: 'Lock the status that changed by the timing (default false)'
x-nullable: true
shabbatMode:
type: boolean
description: 'Set minion lock to be Shabbat mode'
x-nullable: true
overrideLock:
type: boolean
description: 'Override lock, if exists (default false)'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@
matTooltip="{{'CALIBRATION_MODE' | translate}}: '{{ minion.calibration.calibrationMode | translate}}', {{'CALIBRATE_EACH' | translate}} {{ minion.calibration.calibrationCycleMinutes }} {{'MINUTES' | translate}}" (mousedown)="minion.other_keyup = true"
mat-icon-button (click)="editCalibrate(minion)">
<mat-icon *ngIf="minion.calibration.calibrationMode === 'AUTO'">slow_motion_video</mat-icon>
<mat-icon *ngIf="minion.calibration.calibrationMode !== 'AUTO'">lock</mat-icon>
<mat-icon *ngIf="minion.calibration.calibrationMode === 'SHABBAT'">hourglass_full</mat-icon>
<mat-icon *ngIf="minion.calibration.calibrationMode === 'LOCK_ON'">lock</mat-icon>
<mat-icon *ngIf="minion.calibration.calibrationMode === 'LOCK_OFF'">lock</mat-icon>
</button>

<button (mouseleave)="minion.other_keyup = false" (mousedown)="minion.other_keyup = true"
Expand Down
52 changes: 29 additions & 23 deletions frontend/src/app/dashboard-crm/timings/timings.component.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<app-loader *ngIf="dataLoading"></app-loader>
<div *ngIf="!dataLoading" fxLayout="row wrap" fxFill>
<div fxFlex fxLayout="column" fxLayoutAlign="space-between"
*ngFor="let timing of timings" fxFlex.lt-sm="100" fxFlex.sm="50" fxFlex.md="25">
<div fxFlex fxLayout="column" fxLayoutAlign="space-between" *ngFor="let timing of timings" fxFlex.lt-sm="100"
fxFlex.sm="50" fxFlex.md="25">

<mat-card class="timing-text" style="max-width: 500px !important; background: #4f93a8">
<mat-card-header>
Expand All @@ -27,8 +27,8 @@

<mat-menu #timingMenu="matMenu">
<button mat-menu-item (click)=selectOtherOperation(timing)>
<mat-icon>play_circle_filled</mat-icon>
<span>{{ 'REPLACE_OPERATION' | translate}}</span>
<mat-icon>play_circle_filled</mat-icon>
<span>{{ 'REPLACE_OPERATION' | translate}}</span>
</button>
<button mat-menu-item (click)="renameTiming(timing)">
<mat-icon>format_italic</mat-icon>
Expand All @@ -50,13 +50,19 @@
</mat-expansion-panel-header>

<!-- Locks section -->
<mat-slide-toggle [color]="primary" [(checked)]="timing.lockStatus"
(change)="setLockStatus(timing, $event.checked)" style="margin: 10px; color: white">{{ 'LOCK_STATUSES' | translate }}
<mat-slide-toggle [color]="primary" [(checked)]="timing.lockStatus && !timing.shabbatMode" [disabled]="timing.shabbatMode"
(change)="setLockStatus(timing, $event.checked)" style="margin: 10px; color: white">
{{ 'LOCK_STATUSES' | translate }}
</mat-slide-toggle>
<mat-slide-toggle [color]="primary" [(checked)]="timing.overrideLock"
(change)="setOverrideLock(timing, $event.checked)" style="margin: 10px; color: white">{{ 'OVERRIDE_LOCKS' | translate }}
(change)="setOverrideLock(timing, $event.checked)" style="margin: 10px; color: white">
{{ 'OVERRIDE_LOCKS' | translate }}
</mat-slide-toggle>

<mat-slide-toggle [color]="primary" [(checked)]="timing.shabbatMode"
(change)="setShabbatMode(timing, $event.checked)" style="margin: 10px; color: white">
{{ 'SET_SHABBAT_MODE' | translate }}
</mat-slide-toggle>

<!-- dailySunTrigger -->
<ng-container *ngIf="timing.timingType === 'dailySunTrigger'"
[style.text-align]="('RIGHT_DIR' | translate)">
Expand All @@ -81,14 +87,14 @@
placeholder="{{ 'DURATION_IN_MINUTES' | translate}}">
</mat-form-field>

<mat-form-field>
<mat-label>{{ 'SUN_TRIGGER' | translate}}</mat-label>
<mat-select [disabled]="!timing.edit"
[(value)]="timing.timingProperties.dailySunTrigger.sunTrigger">
<mat-option value="sunrise">{{ 'SUNRISE' | translate}}</mat-option>
<mat-option value="sunset">{{ 'SUNSET' | translate}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'SUN_TRIGGER' | translate}}</mat-label>
<mat-select [disabled]="!timing.edit"
[(value)]="timing.timingProperties.dailySunTrigger.sunTrigger">
<mat-option value="sunrise">{{ 'SUNRISE' | translate}}</mat-option>
<mat-option value="sunset">{{ 'SUNSET' | translate}}</mat-option>
</mat-select>
</mat-form-field>

</ng-container>

Expand All @@ -115,8 +121,8 @@
[(ngModel)]="timing.timingProperties.dailyTimeTrigger.hour">
</mat-form-field>

<mat-form-field>
<input matInput [disabled]="!timing.edit" type="number" min="0" max="59" step="1"
<mat-form-field>
<input matInput [disabled]="!timing.edit" type="number" min="0" max="59" step="1"
placeholder="{{ 'MINUTES' | translate}}"
[(ngModel)]="timing.timingProperties.dailyTimeTrigger.minutes">
</mat-form-field>
Expand Down Expand Up @@ -149,8 +155,8 @@

<!-- Edit button -->
<div [style.text-align]="('RIGHT_DIR' | translate)" class="timing-text">
<button *ngIf="!timing.sync && !timing.edit" mat-icon-button (click)="timing.edit = true;" matTooltipPosition="below"
matTooltip="{{'EDIT_PROPERTIES' | translate}}">
<button *ngIf="!timing.sync && !timing.edit" mat-icon-button (click)="timing.edit = true;"
matTooltipPosition="below" matTooltip="{{'EDIT_PROPERTIES' | translate}}">
<mat-icon aria-label="Edit">edit</mat-icon>
</button>
<button *ngIf="!timing.sync && timing.edit" mat-icon-button (click)="editTiming(timing)">
Expand All @@ -176,10 +182,10 @@
</eco-fab-speed-dial-trigger>

<eco-fab-speed-dial-actions>
<button [color]="primary" mat-mini-fab matTooltipPosition="{{'RIGHT_DIR' | translate}}" (click)="refreshData()"
matTooltip="{{'REFRESH' | translate}}">
<button [color]="primary" mat-mini-fab matTooltipPosition="{{'RIGHT_DIR' | translate}}"
(click)="refreshData()" matTooltip="{{'REFRESH' | translate}}">
<mat-icon>refresh</mat-icon>
</button>
</button>
<button [color]="primary" mat-mini-fab matTooltipPosition="{{'RIGHT_DIR' | translate}}"
(click)="createTimings()" matTooltip="{{'CREATE_TIMING' | translate}}">
<mat-icon>add</mat-icon>
Expand Down
Loading

0 comments on commit 5ae9636

Please sign in to comment.