Alex Mikhalev
7 years ago
17 changed files with 451 additions and 231 deletions
@ -1,224 +0,0 @@ |
|||||||
import { IObservableArray, observable } from "mobx"; |
|
||||||
|
|
||||||
export abstract class Section { |
|
||||||
device: SprinklersDevice; |
|
||||||
|
|
||||||
@observable |
|
||||||
name: string = ""; |
|
||||||
|
|
||||||
@observable |
|
||||||
state: boolean = false; |
|
||||||
|
|
||||||
constructor(device: SprinklersDevice) { |
|
||||||
this.device = device; |
|
||||||
} |
|
||||||
|
|
||||||
run(duration: Duration) { |
|
||||||
return this.device.runSection(this, duration); |
|
||||||
} |
|
||||||
|
|
||||||
toString(): string { |
|
||||||
return `Section{name="${this.name}", state=${this.state}}`; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export class TimeOfDay { |
|
||||||
hour: number; |
|
||||||
minute: number; |
|
||||||
second: number; |
|
||||||
millisecond: number; |
|
||||||
|
|
||||||
constructor(hour: number, minute: number = 0, second: number = 0, millisecond: number = 0) { |
|
||||||
this.hour = hour; |
|
||||||
this.minute = minute; |
|
||||||
this.second = second; |
|
||||||
this.millisecond = millisecond; |
|
||||||
} |
|
||||||
|
|
||||||
static fromDate(date: Date): TimeOfDay { |
|
||||||
return new TimeOfDay(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export enum Weekday { |
|
||||||
Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, |
|
||||||
} |
|
||||||
|
|
||||||
export class Schedule { |
|
||||||
times: TimeOfDay[] = []; |
|
||||||
weekdays: Weekday[] = []; |
|
||||||
from: Date | null = null; |
|
||||||
to: Date | null = null; |
|
||||||
} |
|
||||||
|
|
||||||
export class Duration { |
|
||||||
minutes: number = 0; |
|
||||||
seconds: number = 0; |
|
||||||
|
|
||||||
constructor(minutes: number = 0, seconds: number = 0) { |
|
||||||
this.minutes = minutes; |
|
||||||
this.seconds = seconds; |
|
||||||
} |
|
||||||
|
|
||||||
static fromSeconds(seconds: number): Duration { |
|
||||||
return new Duration(Math.floor(seconds / 60), seconds % 60); |
|
||||||
} |
|
||||||
|
|
||||||
toSeconds(): number { |
|
||||||
return this.minutes * 60 + this.seconds; |
|
||||||
} |
|
||||||
|
|
||||||
withSeconds(newSeconds: number): Duration { |
|
||||||
let newMinutes = this.minutes; |
|
||||||
if (newSeconds >= 60) { |
|
||||||
newMinutes++; |
|
||||||
newSeconds = 0; |
|
||||||
} |
|
||||||
if (newSeconds < 0) { |
|
||||||
newMinutes = Math.max(0, newMinutes - 1); |
|
||||||
newSeconds = 59; |
|
||||||
} |
|
||||||
return new Duration(newMinutes, newSeconds); |
|
||||||
} |
|
||||||
|
|
||||||
withMinutes(newMinutes: number): Duration { |
|
||||||
if (newMinutes < 0) { |
|
||||||
newMinutes = 0; |
|
||||||
} |
|
||||||
return new Duration(newMinutes, this.seconds); |
|
||||||
} |
|
||||||
|
|
||||||
toString(): string { |
|
||||||
return `${this.minutes}M ${this.seconds}S`; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export class ProgramItem { |
|
||||||
// the section number
|
|
||||||
section: number; |
|
||||||
// duration of the run
|
|
||||||
duration: Duration; |
|
||||||
|
|
||||||
constructor(section: number, duration: Duration) { |
|
||||||
this.section = section; |
|
||||||
this.duration = duration; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export class Program { |
|
||||||
device: SprinklersDevice; |
|
||||||
|
|
||||||
@observable |
|
||||||
name: string = ""; |
|
||||||
@observable |
|
||||||
enabled: boolean = false; |
|
||||||
|
|
||||||
@observable |
|
||||||
schedule: Schedule = new Schedule(); |
|
||||||
|
|
||||||
@observable |
|
||||||
sequence: ProgramItem[] = []; |
|
||||||
|
|
||||||
@observable |
|
||||||
running: boolean = false; |
|
||||||
|
|
||||||
constructor(device: SprinklersDevice) { |
|
||||||
this.device = device; |
|
||||||
} |
|
||||||
|
|
||||||
run() { |
|
||||||
return this.device.runProgram(this); |
|
||||||
} |
|
||||||
|
|
||||||
toString(): string { |
|
||||||
return `Program{name="${this.name}", enabled=${this.enabled}, schedule=${this.schedule},
|
|
||||||
sequence=${this.sequence}, running=${this.running}}`;
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export class SectionRun { |
|
||||||
id: number; |
|
||||||
section: number; |
|
||||||
duration: Duration; |
|
||||||
startTime: Date | null; |
|
||||||
pauseTime: Date | null; |
|
||||||
|
|
||||||
constructor(id: number = 0, section: number = 0, duration: Duration = new Duration()) { |
|
||||||
this.id = id; |
|
||||||
this.section = section; |
|
||||||
this.duration = duration; |
|
||||||
this.startTime = null; |
|
||||||
this.pauseTime = null; |
|
||||||
} |
|
||||||
|
|
||||||
toString() { |
|
||||||
return `SectionRun{id=${this.id}, section=${this.section}, duration=${this.duration},` + |
|
||||||
` startTime=${this.startTime}, pauseTime=${this.pauseTime}}`; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export class SectionRunner { |
|
||||||
device: SprinklersDevice; |
|
||||||
|
|
||||||
@observable |
|
||||||
queue: IObservableArray<SectionRun> = observable([]); |
|
||||||
|
|
||||||
@observable |
|
||||||
current: SectionRun | null = null; |
|
||||||
|
|
||||||
@observable |
|
||||||
paused: boolean = false; |
|
||||||
|
|
||||||
constructor(device: SprinklersDevice) { |
|
||||||
this.device = device; |
|
||||||
} |
|
||||||
|
|
||||||
cancelRunById(id: number): Promise<{}> { |
|
||||||
return this.device.cancelSectionRunById(id); |
|
||||||
} |
|
||||||
|
|
||||||
toString(): string { |
|
||||||
return `SectionRunner{queue="${this.queue}", current="${this.current}", paused=${this.paused}}`; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export abstract class SprinklersDevice { |
|
||||||
@observable |
|
||||||
connected: boolean = false; |
|
||||||
|
|
||||||
@observable |
|
||||||
sections: IObservableArray<Section> = observable.array<Section>(); |
|
||||||
|
|
||||||
@observable |
|
||||||
programs: IObservableArray<Program> = observable.array<Program>(); |
|
||||||
|
|
||||||
@observable |
|
||||||
sectionRunner: SectionRunner; |
|
||||||
|
|
||||||
abstract get id(): string; |
|
||||||
|
|
||||||
abstract runSection(section: number | Section, duration: Duration): Promise<{}>; |
|
||||||
|
|
||||||
abstract runProgram(program: number | Program): Promise<{}>; |
|
||||||
|
|
||||||
abstract cancelSectionRunById(id: number): Promise<{}>; |
|
||||||
|
|
||||||
abstract pauseSectionRunner(): Promise<{}>; |
|
||||||
|
|
||||||
abstract unpauseSectionRunner(): Promise<{}>; |
|
||||||
|
|
||||||
toString(): string { |
|
||||||
return `SprinklersDevice{id="${this.id}", connected=${this.connected},
|
|
||||||
sections=${this.sections}, |
|
||||||
programs=${this.programs}, |
|
||||||
sectionRunner=${this.sectionRunner} }`;
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export interface ISprinklersApi { |
|
||||||
start(): void; |
|
||||||
|
|
||||||
getDevice(id: string): SprinklersDevice; |
|
||||||
|
|
||||||
removeDevice(id: string): void; |
|
||||||
} |
|
@ -0,0 +1,41 @@ |
|||||||
|
export class Duration { |
||||||
|
minutes: number = 0; |
||||||
|
seconds: number = 0; |
||||||
|
|
||||||
|
constructor(minutes: number = 0, seconds: number = 0) { |
||||||
|
this.minutes = minutes; |
||||||
|
this.seconds = seconds; |
||||||
|
} |
||||||
|
|
||||||
|
static fromSeconds(seconds: number): Duration { |
||||||
|
return new Duration(Math.floor(seconds / 60), seconds % 60); |
||||||
|
} |
||||||
|
|
||||||
|
toSeconds(): number { |
||||||
|
return this.minutes * 60 + this.seconds; |
||||||
|
} |
||||||
|
|
||||||
|
withSeconds(newSeconds: number): Duration { |
||||||
|
let newMinutes = this.minutes; |
||||||
|
if (newSeconds >= 60) { |
||||||
|
newMinutes++; |
||||||
|
newSeconds = 0; |
||||||
|
} |
||||||
|
if (newSeconds < 0) { |
||||||
|
newMinutes = Math.max(0, newMinutes - 1); |
||||||
|
newSeconds = 59; |
||||||
|
} |
||||||
|
return new Duration(newMinutes, newSeconds); |
||||||
|
} |
||||||
|
|
||||||
|
withMinutes(newMinutes: number): Duration { |
||||||
|
if (newMinutes < 0) { |
||||||
|
newMinutes = 0; |
||||||
|
} |
||||||
|
return new Duration(newMinutes, this.seconds); |
||||||
|
} |
||||||
|
|
||||||
|
toString(): string { |
||||||
|
return `${this.minutes}M ${this.seconds}S`; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
import { SprinklersDevice } from "./SprinklersDevice"; |
||||||
|
|
||||||
|
export interface ISprinklersApi { |
||||||
|
start(): void; |
||||||
|
|
||||||
|
getDevice(id: string): SprinklersDevice; |
||||||
|
|
||||||
|
removeDevice(id: string): void; |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
import { observable } from "mobx"; |
||||||
|
import { Duration } from "./Duration"; |
||||||
|
import { Schedule } from "./schedule"; |
||||||
|
import { SprinklersDevice } from "./SprinklersDevice"; |
||||||
|
|
||||||
|
export class ProgramItem { |
||||||
|
// the section number
|
||||||
|
section: number; |
||||||
|
// duration of the run
|
||||||
|
duration: Duration; |
||||||
|
|
||||||
|
constructor(section: number, duration: Duration) { |
||||||
|
this.section = section; |
||||||
|
this.duration = duration; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export class Program { |
||||||
|
device: SprinklersDevice; |
||||||
|
|
||||||
|
@observable |
||||||
|
name: string = ""; |
||||||
|
@observable |
||||||
|
enabled: boolean = false; |
||||||
|
|
||||||
|
@observable |
||||||
|
schedule: Schedule = new Schedule(); |
||||||
|
|
||||||
|
@observable |
||||||
|
sequence: ProgramItem[] = []; |
||||||
|
|
||||||
|
@observable |
||||||
|
running: boolean = false; |
||||||
|
|
||||||
|
constructor(device: SprinklersDevice) { |
||||||
|
this.device = device; |
||||||
|
} |
||||||
|
|
||||||
|
run() { |
||||||
|
return this.device.runProgram(this); |
||||||
|
} |
||||||
|
|
||||||
|
toString(): string { |
||||||
|
return `Program{name="${this.name}", enabled=${this.enabled}, schedule=${this.schedule},
|
||||||
|
sequence=${this.sequence}, running=${this.running}}`;
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
import { observable } from "mobx"; |
||||||
|
import { Duration } from "./Duration"; |
||||||
|
import { SprinklersDevice } from "./SprinklersDevice"; |
||||||
|
|
||||||
|
export class Section { |
||||||
|
device: SprinklersDevice; |
||||||
|
|
||||||
|
@observable |
||||||
|
name: string = ""; |
||||||
|
|
||||||
|
@observable |
||||||
|
state: boolean = false; |
||||||
|
|
||||||
|
constructor(device: SprinklersDevice) { |
||||||
|
this.device = device; |
||||||
|
} |
||||||
|
|
||||||
|
run(duration: Duration) { |
||||||
|
return this.device.runSection(this, duration); |
||||||
|
} |
||||||
|
|
||||||
|
toString(): string { |
||||||
|
return `Section{name="${this.name}", state=${this.state}}`; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
import { IObservableArray, observable } from "mobx"; |
||||||
|
import { Duration } from "./Duration"; |
||||||
|
import { SprinklersDevice } from "./SprinklersDevice"; |
||||||
|
|
||||||
|
export class SectionRun { |
||||||
|
id: number; |
||||||
|
section: number; |
||||||
|
duration: Duration; |
||||||
|
startTime: Date | null; |
||||||
|
pauseTime: Date | null; |
||||||
|
|
||||||
|
constructor(id: number = 0, section: number = 0, duration: Duration = new Duration()) { |
||||||
|
this.id = id; |
||||||
|
this.section = section; |
||||||
|
this.duration = duration; |
||||||
|
this.startTime = null; |
||||||
|
this.pauseTime = null; |
||||||
|
} |
||||||
|
|
||||||
|
toString() { |
||||||
|
return `SectionRun{id=${this.id}, section=${this.section}, duration=${this.duration},` + |
||||||
|
` startTime=${this.startTime}, pauseTime=${this.pauseTime}}`; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export class SectionRunner { |
||||||
|
device: SprinklersDevice; |
||||||
|
|
||||||
|
@observable |
||||||
|
queue: IObservableArray<SectionRun> = observable([]); |
||||||
|
|
||||||
|
@observable |
||||||
|
current: SectionRun | null = null; |
||||||
|
|
||||||
|
@observable |
||||||
|
paused: boolean = false; |
||||||
|
|
||||||
|
constructor(device: SprinklersDevice) { |
||||||
|
this.device = device; |
||||||
|
} |
||||||
|
|
||||||
|
cancelRunById(id: number): Promise<{}> { |
||||||
|
return this.device.cancelSectionRunById(id); |
||||||
|
} |
||||||
|
|
||||||
|
toString(): string { |
||||||
|
return `SectionRunner{queue="${this.queue}", current="${this.current}", paused=${this.paused}}`; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
import { IObservableArray, observable } from "mobx"; |
||||||
|
import { Duration } from "./Duration"; |
||||||
|
import { Program } from "./Program"; |
||||||
|
import { Section } from "./Section"; |
||||||
|
import { SectionRunner } from "./SectionRunner"; |
||||||
|
|
||||||
|
export abstract class SprinklersDevice { |
||||||
|
@observable |
||||||
|
connected: boolean = false; |
||||||
|
|
||||||
|
@observable |
||||||
|
sections: IObservableArray<Section> = observable.array<Section>(); |
||||||
|
|
||||||
|
@observable |
||||||
|
programs: IObservableArray<Program> = observable.array<Program>(); |
||||||
|
|
||||||
|
@observable |
||||||
|
sectionRunner: SectionRunner; |
||||||
|
|
||||||
|
abstract get id(): string; |
||||||
|
|
||||||
|
abstract runSection(section: number | Section, duration: Duration): Promise<{}>; |
||||||
|
|
||||||
|
abstract runProgram(program: number | Program): Promise<{}>; |
||||||
|
|
||||||
|
abstract cancelSectionRunById(id: number): Promise<{}>; |
||||||
|
|
||||||
|
abstract pauseSectionRunner(): Promise<{}>; |
||||||
|
|
||||||
|
abstract unpauseSectionRunner(): Promise<{}>; |
||||||
|
|
||||||
|
toString(): string { |
||||||
|
return `SprinklersDevice{id="${this.id}", connected=${this.connected},
|
||||||
|
sections=${this.sections}, |
||||||
|
programs=${this.programs}, |
||||||
|
sectionRunner=${this.sectionRunner} }`;
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
import { IObservableArray, observable } from "mobx"; |
||||||
|
export * from "./Duration"; |
||||||
|
export * from "./ISprinklersApi"; |
||||||
|
export * from "./Program"; |
||||||
|
export * from "./schedule"; |
||||||
|
export * from "./Section"; |
||||||
|
export * from "./SectionRunner"; |
||||||
|
export * from "./SprinklersDevice"; |
@ -0,0 +1,172 @@ |
|||||||
|
import { assign, pick } from "lodash"; |
||||||
|
import * as s from ".."; |
||||||
|
|
||||||
|
export interface ISectionJSON { |
||||||
|
name: string; |
||||||
|
state: boolean; |
||||||
|
} |
||||||
|
const sectionProps = ["name", "state"]; |
||||||
|
|
||||||
|
export function sectionToJSON(sec: s.Section): ISectionJSON { |
||||||
|
return pick(sec, sectionProps); |
||||||
|
} |
||||||
|
|
||||||
|
export function sectionFromJSON(sec: s.Section, json: ISectionJSON) { |
||||||
|
assign(sec, pick(json, sectionProps)); |
||||||
|
} |
||||||
|
|
||||||
|
export interface ITimeOfDayJSON { |
||||||
|
hour: number; |
||||||
|
minute: number; |
||||||
|
second: number; |
||||||
|
millisecond: number; |
||||||
|
} |
||||||
|
const timeOfDayProps = ["hour", "minute", "second", "millisecond"]; |
||||||
|
|
||||||
|
export function timeOfDayToJSON(timeOfDay: s.TimeOfDay): ITimeOfDayJSON { |
||||||
|
return pick(timeOfDay, timeOfDayProps); |
||||||
|
} |
||||||
|
|
||||||
|
export function timeOfDayFromJSON(timeOfDay: s.TimeOfDay, json: ITimeOfDayJSON) { |
||||||
|
assign(timeOfDay, pick(json, timeOfDayProps)); |
||||||
|
} |
||||||
|
|
||||||
|
export interface IScheduleJSON { |
||||||
|
times: ITimeOfDayJSON[]; |
||||||
|
weekdays: number[]; |
||||||
|
from?: string; |
||||||
|
to?: string; |
||||||
|
} |
||||||
|
const scheduleProps = ["weekdays", "from", "to"]; |
||||||
|
|
||||||
|
export function scheduleToJSON(schedule: s.Schedule): IScheduleJSON { |
||||||
|
return { |
||||||
|
...pick(schedule, scheduleProps), |
||||||
|
times: schedule.times.map(timeOfDayToJSON), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function scheduleFromJSON(schedule: s.Schedule, json: IScheduleJSON) { |
||||||
|
assign(schedule, pick(json, scheduleProps)); |
||||||
|
schedule.times.length = json.times.length; |
||||||
|
schedule.times.forEach((timeOfDay, i) => |
||||||
|
timeOfDayFromJSON(timeOfDay, json.times[i])); |
||||||
|
} |
||||||
|
|
||||||
|
export interface IProgramItemJSON { |
||||||
|
section: number; |
||||||
|
duration: number; |
||||||
|
} |
||||||
|
const programItemProps = ["section"]; |
||||||
|
|
||||||
|
export function programItemToJSON(programItem: s.ProgramItem): IProgramItemJSON { |
||||||
|
return { |
||||||
|
...pick(programItem, programItemProps), |
||||||
|
duration: programItem.duration.toSeconds(), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function programItemFromJSON(programItem: s.ProgramItem, json: IProgramItemJSON) { |
||||||
|
assign(programItem, pick(json, programItemProps)); |
||||||
|
programItem.duration = s.Duration.fromSeconds(json.duration); |
||||||
|
} |
||||||
|
|
||||||
|
export interface IProgramJSON { |
||||||
|
name: string; |
||||||
|
enabled: boolean; |
||||||
|
sequence: IProgramItemJSON[]; |
||||||
|
schedule: IScheduleJSON; |
||||||
|
running: boolean; |
||||||
|
} |
||||||
|
const programProps = ["name", "enabled", "running"]; |
||||||
|
|
||||||
|
export function programToJSON(program: s.Program): IProgramJSON { |
||||||
|
return { |
||||||
|
...pick(program, programProps), |
||||||
|
sequence: program.sequence.map(programItemToJSON), |
||||||
|
schedule: scheduleToJSON(program.schedule), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function programFromJSON(program: s.Program, json: IProgramJSON) { |
||||||
|
assign(program, pick(json, programProps)); |
||||||
|
program.sequence.length = json.sequence.length; |
||||||
|
program.sequence.forEach((programItem, i) => |
||||||
|
programItemFromJSON(programItem, json.sequence[i])); |
||||||
|
scheduleFromJSON(program.schedule, json.schedule); |
||||||
|
} |
||||||
|
|
||||||
|
export interface ISectionRunJSON { |
||||||
|
id: number; |
||||||
|
section: number; |
||||||
|
duration: number; |
||||||
|
startTime?: number; |
||||||
|
pauseTime?: number; |
||||||
|
} |
||||||
|
const sectionRunProps = ["id", "section", "duration", "startTime", "pauseTime"]; |
||||||
|
|
||||||
|
export function sectionRunToJSON(sectionRun: s.SectionRun): ISectionRunJSON { |
||||||
|
return pick(sectionRun, sectionRunProps); |
||||||
|
} |
||||||
|
|
||||||
|
export function sectionRunFromJSON(sectionRun: s.SectionRun, json: ISectionRunJSON) { |
||||||
|
assign(sectionRun, pick(json, sectionRunProps)); |
||||||
|
} |
||||||
|
|
||||||
|
interface ISectionRunnerJSON { |
||||||
|
queue: ISectionRunJSON[]; |
||||||
|
current: ISectionRunJSON | null; |
||||||
|
paused: boolean; |
||||||
|
} |
||||||
|
const sectionRunnerProps = ["paused"]; |
||||||
|
|
||||||
|
export function sectionRunnerToJSON(sectionRunner: s.SectionRunner): ISectionRunnerJSON { |
||||||
|
return { |
||||||
|
...pick(sectionRunner, sectionRunnerProps), |
||||||
|
queue: sectionRunner.queue.map(sectionRunToJSON), |
||||||
|
current: sectionRunner.current ? sectionRunToJSON(sectionRunner.current) : null, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function sectionRunnerFromJSON(sectionRunner: s.SectionRunner, json: ISectionRunnerJSON) { |
||||||
|
assign(sectionRunner, pick(json, sectionRunnerProps)); |
||||||
|
sectionRunner.queue.length = json.queue.length; |
||||||
|
sectionRunner.queue.forEach((sectionRun, i) => |
||||||
|
sectionRunFromJSON(sectionRun, json.queue[i])); |
||||||
|
if (json.current == null) { |
||||||
|
sectionRunner.current = null; |
||||||
|
} else { |
||||||
|
if (sectionRunner.current == null) { |
||||||
|
sectionRunner.current = new s.SectionRun(); |
||||||
|
} |
||||||
|
sectionRunFromJSON(sectionRunner.current, json.current); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
interface ISprinklersDeviceJSON { |
||||||
|
connected: boolean; |
||||||
|
sections: ISectionJSON[]; |
||||||
|
sectionRunner: ISectionRunnerJSON; |
||||||
|
programs: IProgramJSON[]; |
||||||
|
} |
||||||
|
const sprinklersDeviceProps = ["connected"]; |
||||||
|
|
||||||
|
export function sprinklersDeviceToJSON(sprinklersDevice: s.SprinklersDevice): ISprinklersDeviceJSON { |
||||||
|
return { |
||||||
|
...pick(sprinklersDevice, sprinklersDeviceProps), |
||||||
|
sections: sprinklersDevice.sections.map(sectionToJSON), |
||||||
|
sectionRunner: sectionRunnerToJSON(sprinklersDevice.sectionRunner), |
||||||
|
programs: sprinklersDevice.programs.map(programToJSON), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function sprinklersDeviceFromJSON(sprinklersDevice: s.SprinklersDevice, json: ISprinklersDeviceJSON) { |
||||||
|
assign(sprinklersDevice, pick(json, sprinklersDeviceProps)); |
||||||
|
sprinklersDevice.sections.length = json.sections.length; |
||||||
|
sprinklersDevice.sections.forEach((section, i) => |
||||||
|
sectionFromJSON(section, json.sections[i])); |
||||||
|
sectionRunnerFromJSON(sprinklersDevice.sectionRunner, json.sectionRunner); |
||||||
|
sprinklersDevice.programs.length = json.programs.length; |
||||||
|
sprinklersDevice.programs.forEach((program, i) => |
||||||
|
programFromJSON(program, json.programs[i])); |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
export class TimeOfDay { |
||||||
|
hour: number; |
||||||
|
minute: number; |
||||||
|
second: number; |
||||||
|
millisecond: number; |
||||||
|
|
||||||
|
constructor(hour: number, minute: number = 0, second: number = 0, millisecond: number = 0) { |
||||||
|
this.hour = hour; |
||||||
|
this.minute = minute; |
||||||
|
this.second = second; |
||||||
|
this.millisecond = millisecond; |
||||||
|
} |
||||||
|
|
||||||
|
static fromDate(date: Date): TimeOfDay { |
||||||
|
return new TimeOfDay(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export enum Weekday { |
||||||
|
Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, |
||||||
|
} |
||||||
|
|
||||||
|
export class Schedule { |
||||||
|
times: TimeOfDay[] = []; |
||||||
|
weekdays: Weekday[] = []; |
||||||
|
from: Date | null = null; |
||||||
|
to: Date | null = null; |
||||||
|
} |
Loading…
Reference in new issue