Added tslint and fixed all lint issues
This commit is contained in:
parent
6ed4099786
commit
ba4ee33792
@ -6,30 +6,41 @@ import FontAwesome = require("react-fontawesome");
|
||||
import * as classNames from "classnames";
|
||||
|
||||
import "semantic-ui-css/semantic.css";
|
||||
import "font-awesome/css/font-awesome.css"
|
||||
import "font-awesome/css/font-awesome.css";
|
||||
import "app/style/app.css";
|
||||
|
||||
/* tslint:disable:object-literal-sort-keys */
|
||||
|
||||
@observer
|
||||
class SectionTable extends React.PureComponent<{ sections: Section[] }, void> {
|
||||
static renderRow(section: Section, index: number) {
|
||||
private static renderRow(section: Section, index: number) {
|
||||
const { name, state } = section;
|
||||
return (
|
||||
<Table.Row key={index}>
|
||||
<Table.Cell className="section--name">Section {name}</Table.Cell>
|
||||
<Table.Cell className="section--state">State: {state + ""}</Table.Cell>
|
||||
<Table.Cell className="section--number">{"" + (index + 1)}</Table.Cell>
|
||||
<Table.Cell className="section--name">{name}</Table.Cell>
|
||||
<Table.Cell className={classNames({
|
||||
"section--state": true,
|
||||
"section--state-true": state,
|
||||
"section--state-false": !state,
|
||||
})}>{state ?
|
||||
(<span><FontAwesome name="tint" /> Irrigating</span>)
|
||||
: "Not irrigating"}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
public render() {
|
||||
return (<Table celled striped>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell colSpan="3">Sections</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>Name</Table.HeaderCell>
|
||||
<Table.HeaderCell>State</Table.HeaderCell>
|
||||
<Table.HeaderCell className="section--number">#</Table.HeaderCell>
|
||||
<Table.HeaderCell className="section--name">Name</Table.HeaderCell>
|
||||
<Table.HeaderCell className="section--state">State</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
@ -44,26 +55,28 @@ class SectionTable extends React.PureComponent<{ sections: Section[] }, void> {
|
||||
|
||||
@observer
|
||||
class ProgramTable extends React.PureComponent<{ programs: Program[] }, void> {
|
||||
static renderRow(program: Program, i: number) {
|
||||
private static renderRow(program: Program, i: number) {
|
||||
const { name, running } = program;
|
||||
return (
|
||||
<Table.Row key={i}>
|
||||
<Table.Cell className="program--name">Program {name}</Table.Cell>
|
||||
<Table.Cell className="program--running">running: {running + ""}</Table.Cell>
|
||||
<Table.Cell className="program--number">{"" + (i + 1)}</Table.Cell>
|
||||
<Table.Cell className="program--name">{name}</Table.Cell>
|
||||
<Table.Cell className="program--running">{running ? "Running" : "Not running"}</Table.Cell>
|
||||
</Table.Row>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
public render() {
|
||||
return (
|
||||
<Table celled striped>
|
||||
<Table celled>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell colSpan="3">Programs</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>Name</Table.HeaderCell>
|
||||
<Table.HeaderCell>Running</Table.HeaderCell>
|
||||
<Table.HeaderCell className="program--number">#</Table.HeaderCell>
|
||||
<Table.HeaderCell className="program--name">Name</Table.HeaderCell>
|
||||
<Table.HeaderCell className="program--running">Running</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
@ -76,9 +89,20 @@ class ProgramTable extends React.PureComponent<{ programs: Program[] }, void> {
|
||||
}
|
||||
}
|
||||
|
||||
const ConnectionState = ({ connected }: { connected: boolean }) =>
|
||||
<span className={classNames({
|
||||
"device--connectionState": true,
|
||||
"device--connectionState-connected": connected,
|
||||
"device--connectionState-disconnected": !connected,
|
||||
})}>
|
||||
<FontAwesome name={connected ? "plug" : "chain-broken"} />
|
||||
|
||||
{connected ? "Connected" : "Disconnected"}
|
||||
</span>;
|
||||
|
||||
@observer
|
||||
class DeviceView extends React.PureComponent<{ device: SprinklersDevice }, void> {
|
||||
render() {
|
||||
public render() {
|
||||
const { id, connected, sections, programs } = this.props.device;
|
||||
return (
|
||||
<Item>
|
||||
@ -86,15 +110,7 @@ class DeviceView extends React.PureComponent<{ device: SprinklersDevice }, void>
|
||||
<Item.Content>
|
||||
<Header as="h1">
|
||||
<span>Device </span><kbd>{id}</kbd>
|
||||
<small className={classNames({
|
||||
"device--connectedState": true,
|
||||
"device--connectedState-connected": connected,
|
||||
"device--connectedState-disconnected": !connected
|
||||
})}>
|
||||
<FontAwesome name={connected ? "plug" : "chain-broken"} />
|
||||
|
||||
{connected ? "Connected" : "Disconnected"}
|
||||
</small>
|
||||
<ConnectionState connected={connected} />
|
||||
</Header>
|
||||
<Item.Meta>
|
||||
|
||||
@ -109,7 +125,7 @@ class DeviceView extends React.PureComponent<{ device: SprinklersDevice }, void>
|
||||
|
||||
@observer
|
||||
export default class App extends React.PureComponent<{ device: SprinklersDevice }, any> {
|
||||
render() {
|
||||
return <Item.Group divided><DeviceView device={this.props.device} /></Item.Group>
|
||||
public render() {
|
||||
return <Item.Group divided><DeviceView device={this.props.device} /></Item.Group>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,5 +21,5 @@ if (module.hot) {
|
||||
ReactDOM.render(<AppContainer>
|
||||
<NextApp device={device} />
|
||||
</AppContainer>, rootElem);
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,47 +1,48 @@
|
||||
/// <reference path="./paho-mqtt.d.ts" />
|
||||
import "paho-mqtt/mqttws31";
|
||||
import MQTT = Paho.MQTT;
|
||||
|
||||
import { EventEmitter } from "events";
|
||||
import { SprinklersDevice, SprinklersApi, Section, Program } from "./sprinklers";
|
||||
|
||||
import * as objectAssign from "object-assign";
|
||||
import {
|
||||
SprinklersDevice, SprinklersApi, Section, Program, ProgramItem, Schedule, TimeOfDay, Weekday,
|
||||
} from "./sprinklers";
|
||||
|
||||
export class MqttApiClient extends EventEmitter implements SprinklersApi {
|
||||
client: MQTT.Client
|
||||
private static newClientId() {
|
||||
return "sprinklers3-MqttApiClient-" + Math.round(Math.random() * 1000);
|
||||
}
|
||||
|
||||
connected: boolean
|
||||
public client: MQTT.Client;
|
||||
|
||||
devices: { [prefix: string]: MqttSprinklersDevice } = {};
|
||||
public connected: boolean;
|
||||
|
||||
public devices: { [prefix: string]: MqttSprinklersDevice } = {};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.client = new MQTT.Client(location.hostname, 1884, MqttApiClient.newClientId());
|
||||
this.client.onMessageArrived = m => this.onMessageArrived(m);
|
||||
this.client.onConnectionLost = e => this.onConnectionLost(e);
|
||||
this.client.onMessageArrived = (m) => this.onMessageArrived(m);
|
||||
this.client.onConnectionLost = (e) => this.onConnectionLost(e);
|
||||
}
|
||||
|
||||
static newClientId() {
|
||||
return "sprinklers3-MqttApiClient-" + Math.round(Math.random() * 1000);
|
||||
}
|
||||
|
||||
start() {
|
||||
public start() {
|
||||
console.log("connecting to mqtt with client id %s", this.client.clientId);
|
||||
this.client.connect({
|
||||
onFailure: (e) => {
|
||||
console.log("mqtt error: ", e.errorMessage);
|
||||
},
|
||||
onSuccess: () => {
|
||||
console.log("mqtt connected")
|
||||
console.log("mqtt connected");
|
||||
this.connected = true;
|
||||
for (const prefix in this.devices) {
|
||||
for (const prefix of Object.keys(this.devices)) {
|
||||
const device = this.devices[prefix];
|
||||
device.doSubscribe();
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getDevice(prefix: string): SprinklersDevice {
|
||||
public getDevice(prefix: string): SprinklersDevice {
|
||||
if (/\//.test(prefix)) {
|
||||
throw new Error("Prefix cannot contain a /");
|
||||
}
|
||||
@ -54,16 +55,18 @@ export class MqttApiClient extends EventEmitter implements SprinklersApi {
|
||||
return this.devices[prefix];
|
||||
}
|
||||
|
||||
removeDevice(prefix: string) {
|
||||
public removeDevice(prefix: string) {
|
||||
const device = this.devices[prefix];
|
||||
if (!device) return;
|
||||
if (!device) {
|
||||
return;
|
||||
}
|
||||
device.doUnsubscribe();
|
||||
delete this.devices[prefix];
|
||||
}
|
||||
|
||||
private onMessageArrived(m: MQTT.Message) {
|
||||
// console.log("message arrived: ", m)
|
||||
const topicIdx = m.destinationName.indexOf('/'); // find the first /
|
||||
const topicIdx = m.destinationName.indexOf("/"); // find the first /
|
||||
const prefix = m.destinationName.substr(0, topicIdx); // assume prefix does not contain a /
|
||||
const topic = m.destinationName.substr(topicIdx + 1);
|
||||
const device = this.devices[prefix];
|
||||
@ -80,8 +83,8 @@ export class MqttApiClient extends EventEmitter implements SprinklersApi {
|
||||
}
|
||||
|
||||
class MqttSprinklersDevice extends SprinklersDevice {
|
||||
readonly apiClient: MqttApiClient;
|
||||
readonly prefix: string;
|
||||
public readonly apiClient: MqttApiClient;
|
||||
public readonly prefix: string;
|
||||
|
||||
constructor(apiClient: MqttApiClient, prefix: string) {
|
||||
super();
|
||||
@ -89,106 +92,136 @@ class MqttSprinklersDevice extends SprinklersDevice {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public doSubscribe() {
|
||||
const c = this.apiClient.client;
|
||||
this.getSubscriptions()
|
||||
.forEach((filter) => c.subscribe(filter, { qos: 1 }));
|
||||
}
|
||||
|
||||
public doUnsubscribe() {
|
||||
const c = this.apiClient.client;
|
||||
this.getSubscriptions()
|
||||
.forEach((filter) => c.unsubscribe(filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this device with the specified message
|
||||
* @param topic The topic, with prefix removed
|
||||
* @param payload The payload string
|
||||
*/
|
||||
public onMessage(topic: string, payload: string) {
|
||||
if (topic === "connected") {
|
||||
this.connected = (payload === "true");
|
||||
// console.log(`MqttSprinklersDevice with prefix ${this.prefix}: ${this.connected}`)
|
||||
return;
|
||||
}
|
||||
let matches = topic.match(/^sections(?:\/(\d+)(?:\/?(.+))?)?$/);
|
||||
if (matches != null) {
|
||||
const [_topic, secStr, subTopic] = matches;
|
||||
// console.log(`section: ${secStr}, topic: ${subTopic}, payload: ${payload}`);
|
||||
if (!secStr) { // new number of sections
|
||||
this.sections = new Array(Number(payload));
|
||||
} else {
|
||||
const secNum = Number(secStr);
|
||||
let section = this.sections[secNum];
|
||||
if (!section) {
|
||||
this.sections[secNum] = section = new MqttSection();
|
||||
}
|
||||
(section as MqttSection).onMessage(subTopic, payload);
|
||||
}
|
||||
return;
|
||||
}
|
||||
matches = topic.match(/^programs(?:\/(\d+)(?:\/?(.+))?)?$/);
|
||||
if (matches != null) {
|
||||
const [_topic, progStr, subTopic] = matches;
|
||||
// console.log(`program: ${progStr}, topic: ${subTopic}, payload: ${payload}`);
|
||||
if (!progStr) { // new number of programs
|
||||
this.programs = new Array(Number(payload));
|
||||
} else {
|
||||
const progNum = Number(progStr);
|
||||
let program = this.programs[progNum];
|
||||
if (!program) {
|
||||
this.programs[progNum] = program = new MqttProgram();
|
||||
}
|
||||
(program as MqttProgram).onMessage(subTopic, payload);
|
||||
}
|
||||
} else {
|
||||
console.warn(`MqttSprinklersDevice recieved invalid topic: ${topic}`);
|
||||
}
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
return this.prefix;
|
||||
}
|
||||
|
||||
private getSubscriptions() {
|
||||
return [
|
||||
`${this.prefix}/connected`,
|
||||
`${this.prefix}/sections`,
|
||||
`${this.prefix}/sections/+/#`,
|
||||
`${this.prefix}/programs`,
|
||||
`${this.prefix}/programs/+/#`
|
||||
`${this.prefix}/programs/+/#`,
|
||||
];
|
||||
}
|
||||
|
||||
doSubscribe() {
|
||||
const c = this.apiClient.client;
|
||||
this.getSubscriptions()
|
||||
.forEach(filter => c.subscribe(filter, { qos: 1 }));
|
||||
|
||||
}
|
||||
|
||||
doUnsubscribe() {
|
||||
const c = this.apiClient.client;
|
||||
this.getSubscriptions()
|
||||
.forEach(filter => c.unsubscribe(filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this device with the specified message
|
||||
* @param topic The topic, with prefix removed
|
||||
* @param payload The payload string
|
||||
*/
|
||||
onMessage(topic: string, payload: string) {
|
||||
var matches;
|
||||
if (topic == "connected") {
|
||||
this.connected = (payload == "true");
|
||||
// console.log(`MqttSprinklersDevice with prefix ${this.prefix}: ${this.connected}`)
|
||||
} else if ((matches = topic.match(/^sections(?:\/(\d+)(?:\/?(.+))?)?$/)) != null) {
|
||||
const [topic, secStr, subTopic] = matches;
|
||||
// console.log(`section: ${secStr}, topic: ${subTopic}, payload: ${payload}`);
|
||||
if (!secStr) { // new number of sections
|
||||
this.sections = new Array(Number(payload));
|
||||
} else {
|
||||
const secNum = Number(secStr);
|
||||
var section = this.sections[secNum];
|
||||
if (!section) {
|
||||
this.sections[secNum] = section = new MqttSection();
|
||||
}
|
||||
(section as MqttSection).onMessage(subTopic, payload);
|
||||
}
|
||||
} else if ((matches = topic.match(/^programs(?:\/(\d+)(?:\/?(.+))?)?$/)) != null) {
|
||||
const [topic, progStr, subTopic] = matches;
|
||||
// console.log(`program: ${progStr}, topic: ${subTopic}, payload: ${payload}`);
|
||||
if (!progStr) { // new number of programs
|
||||
this.programs = new Array(Number(payload));
|
||||
} else {
|
||||
const progNum = Number(progStr);
|
||||
var program = this.programs[progNum];
|
||||
if (!program) {
|
||||
this.programs[progNum] = program = new MqttProgram();
|
||||
}
|
||||
(program as MqttProgram).onMessage(subTopic, payload);
|
||||
}
|
||||
} else {
|
||||
console.warn(`MqttSprinklersDevice recieved invalid topic: ${topic}`)
|
||||
}
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
return this.prefix;
|
||||
}
|
||||
}
|
||||
|
||||
interface SectionJSON {
|
||||
interface ISectionJSON {
|
||||
name: string;
|
||||
pin: number;
|
||||
}
|
||||
|
||||
class MqttSection extends Section {
|
||||
onMessage(topic: string, payload: string) {
|
||||
if (topic == "state") {
|
||||
this.state = (payload == "true");
|
||||
public onMessage(topic: string, payload: string) {
|
||||
if (topic === "state") {
|
||||
this.state = (payload === "true");
|
||||
} else if (topic == null) {
|
||||
const json = JSON.parse(payload) as SectionJSON;
|
||||
const json = JSON.parse(payload) as ISectionJSON;
|
||||
this.name = json.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface ProgramJSON {
|
||||
interface IScheduleJSON {
|
||||
times: TimeOfDay[];
|
||||
weekdays: number[];
|
||||
from?: string;
|
||||
to?: string;
|
||||
}
|
||||
|
||||
function scheduleFromJSON(json: IScheduleJSON): Schedule {
|
||||
const sched = new Schedule();
|
||||
sched.times = json.times;
|
||||
sched.weekdays = json.weekdays;
|
||||
sched.from = json.from == null ? null : new Date(json.from);
|
||||
sched.to = json.to == null ? null : new Date(json.to);
|
||||
return sched;
|
||||
}
|
||||
|
||||
interface IProgramJSON {
|
||||
name: string;
|
||||
enabled: boolean;
|
||||
// sequence: Array<ProgramItem>;
|
||||
// sched: Schedule;
|
||||
sequence: ProgramItem[];
|
||||
sched: IScheduleJSON;
|
||||
}
|
||||
|
||||
class MqttProgram extends Program {
|
||||
onMessage(topic: string, payload: string) {
|
||||
if (topic == "running") {
|
||||
this.running = (payload == "true");
|
||||
public onMessage(topic: string, payload: string) {
|
||||
if (topic === "running") {
|
||||
this.running = (payload === "true");
|
||||
} else if (topic == null) {
|
||||
const json = JSON.parse(payload) as Partial<ProgramJSON>;
|
||||
this.name = json.name;
|
||||
this.enabled = json.enabled;
|
||||
const json = JSON.parse(payload) as Partial<IProgramJSON>;
|
||||
if (json.name != null) {
|
||||
this.name = json.name;
|
||||
}
|
||||
if (json.enabled != null) {
|
||||
this.enabled = json.enabled;
|
||||
}
|
||||
if (json.sequence != null) {
|
||||
this.sequence = json.sequence;
|
||||
}
|
||||
if (json.sched != null) {
|
||||
this.schedule = scheduleFromJSON(json.sched);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
60
app/script/paho-mqtt.d.ts
vendored
60
app/script/paho-mqtt.d.ts
vendored
@ -1,9 +1,11 @@
|
||||
/* tslint:disable:interface-name */
|
||||
|
||||
declare namespace Paho {
|
||||
namespace MQTT {
|
||||
interface MQTTError { errorCode: string, errorMessage: string }
|
||||
interface WithInvocationContext { invocationContext: object }
|
||||
interface MQTTError { errorCode: string; errorMessage: string; }
|
||||
interface WithInvocationContext { invocationContext: object; }
|
||||
interface ErrorWithInvocationContext extends MQTTError, WithInvocationContext {}
|
||||
interface OnSubscribeSuccessParams extends WithInvocationContext { grantedQos: number }
|
||||
interface OnSubscribeSuccessParams extends WithInvocationContext { grantedQos: number; }
|
||||
type OnConnectionLostHandler = (error: MQTTError) => void;
|
||||
type OnMessageHandler = (message: Message) => void;
|
||||
interface ConnectionOptions {
|
||||
@ -18,8 +20,8 @@ declare namespace Paho {
|
||||
onSuccess?: (o: WithInvocationContext) => void;
|
||||
mqttVersion?: number;
|
||||
onFailure?: (e: ErrorWithInvocationContext) => void;
|
||||
hosts?: Array<string>;
|
||||
ports?: Array<number>;
|
||||
hosts?: string[];
|
||||
ports?: number[];
|
||||
}
|
||||
interface SubscribeOptions {
|
||||
qos?: number;
|
||||
@ -35,41 +37,41 @@ declare namespace Paho {
|
||||
timeout?: number;
|
||||
}
|
||||
class Client {
|
||||
public readonly clientId: string;
|
||||
public readonly host: string;
|
||||
public readonly path: string;
|
||||
public readonly port: number;
|
||||
|
||||
public onConnectionLost: OnConnectionLostHandler;
|
||||
public onMessageArrived: OnMessageHandler;
|
||||
public onMessageDelivered: OnMessageHandler;
|
||||
|
||||
// tslint:disable unified-signatures
|
||||
constructor(host: string, port: number, path: string, clientId: string);
|
||||
constructor(host: string, port: number, clientId: string);
|
||||
constructor(hostUri: string, clientId: string);
|
||||
|
||||
readonly clientId: string;
|
||||
readonly host: string;
|
||||
readonly path: string;
|
||||
readonly port: number;
|
||||
public connect(connectionOptions?: ConnectionOptions);
|
||||
public disconnect();
|
||||
|
||||
onConnectionLost: OnConnectionLostHandler;
|
||||
onMessageArrived: OnMessageHandler;
|
||||
onMessageDelivered: OnMessageHandler;
|
||||
public getTraceLog(): object[];
|
||||
public startTrace();
|
||||
public stopTrace();
|
||||
|
||||
connect(connectionOptions?: ConnectionOptions);
|
||||
disconnect();
|
||||
|
||||
getTraceLog(): Object[];
|
||||
startTrace();
|
||||
stopTrace();
|
||||
|
||||
send(message: Message);
|
||||
subscribe(filter: string, subcribeOptions?: SubscribeOptions);
|
||||
unsubscribe(filter: string, unsubcribeOptions?: UnsubscribeOptions);
|
||||
public send(message: Message);
|
||||
public subscribe(filter: string, subcribeOptions?: SubscribeOptions);
|
||||
public unsubscribe(filter: string, unsubcribeOptions?: UnsubscribeOptions);
|
||||
}
|
||||
|
||||
class Message {
|
||||
constructor(payload: String | ArrayBuffer);
|
||||
public destinationName: string;
|
||||
public readonly duplicate: boolean;
|
||||
public readonly payloadBytes: ArrayBuffer;
|
||||
public readonly payloadString: string;
|
||||
public qos: number;
|
||||
public retained: boolean;
|
||||
|
||||
destinationName: string;
|
||||
readonly duplicate: boolean;
|
||||
readonly payloadBytes: ArrayBuffer;
|
||||
readonly payloadString: string;
|
||||
qos: number;
|
||||
retained: boolean;
|
||||
constructor(payload: string | ArrayBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,69 +2,69 @@ import { observable } from "mobx";
|
||||
|
||||
export class Section {
|
||||
@observable
|
||||
name: string = ""
|
||||
public name: string = "";
|
||||
|
||||
@observable
|
||||
state: boolean = false
|
||||
public state: boolean = false;
|
||||
}
|
||||
|
||||
class TimeOfDay {
|
||||
hour: number
|
||||
minute: number
|
||||
second: number
|
||||
millisecond: number
|
||||
|
||||
export interface ITimeOfDay {
|
||||
hour: number;
|
||||
minute: number;
|
||||
second: number;
|
||||
millisecond: number;
|
||||
}
|
||||
|
||||
enum Weekday {
|
||||
Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
|
||||
export enum Weekday {
|
||||
Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday,
|
||||
}
|
||||
|
||||
class Schedule {
|
||||
times: TimeOfDay[] = [];
|
||||
weekdays: Weekday[] = [];
|
||||
from?: Date = null;
|
||||
to?: Date = null;
|
||||
export class Schedule {
|
||||
public times: ITimeOfDay[] = [];
|
||||
public weekdays: Weekday[] = [];
|
||||
public from?: Date = null;
|
||||
public to?: Date = null;
|
||||
}
|
||||
|
||||
class ProgramItem {
|
||||
section: number = -1;
|
||||
// duration in milliseconds
|
||||
duration: number = 0;
|
||||
export interface IProgramItem {
|
||||
// the section number
|
||||
section: number;
|
||||
// duration in seconds
|
||||
duration: number;
|
||||
}
|
||||
|
||||
export class Program {
|
||||
@observable
|
||||
name: string = ""
|
||||
public name: string = "";
|
||||
@observable
|
||||
enabled: boolean = false
|
||||
public enabled: boolean = false;
|
||||
|
||||
@observable
|
||||
schedule: Schedule = new Schedule()
|
||||
public schedule: Schedule = new Schedule();
|
||||
|
||||
@observable
|
||||
sequence: Array<ProgramItem> = [];
|
||||
public sequence: IProgramItem[] = [];
|
||||
|
||||
@observable
|
||||
running: boolean = false;
|
||||
public running: boolean = false;
|
||||
}
|
||||
|
||||
export abstract class SprinklersDevice {
|
||||
@observable
|
||||
connected: boolean = false;
|
||||
public connected: boolean = false;
|
||||
|
||||
@observable
|
||||
sections: Array<Section> = [];
|
||||
public sections: Section[] = [];
|
||||
|
||||
@observable
|
||||
programs: Array<Program> = [];
|
||||
public programs: Program[] = [];
|
||||
|
||||
abstract get id(): string;
|
||||
}
|
||||
|
||||
export interface SprinklersApi {
|
||||
export interface ISprinklersApi {
|
||||
start();
|
||||
getDevice(id: string) : SprinklersDevice;
|
||||
getDevice(id: string): SprinklersDevice;
|
||||
|
||||
removeDevice(id: string)
|
||||
}
|
||||
removeDevice(id: string);
|
||||
}
|
||||
|
@ -1,19 +1,36 @@
|
||||
.device--connectedState-connected {
|
||||
.device--connectionState {
|
||||
margin-left: 10px;
|
||||
font-size: 18px;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
.device--connectionState-connected {
|
||||
color: #13D213;
|
||||
}
|
||||
|
||||
.device--connectedState-disconnected {
|
||||
.device--connectionState-disconnected {
|
||||
color: #D20000;
|
||||
}
|
||||
|
||||
.section--name {
|
||||
width: 200px;
|
||||
.section--number,
|
||||
.program--number {
|
||||
width: 20px
|
||||
}
|
||||
|
||||
.section--name,
|
||||
.program--name {
|
||||
width: 150px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.section--state {
|
||||
|
||||
}
|
||||
|
||||
.program--name {
|
||||
width: 200px;
|
||||
.section--state-true {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.section--state-false {
|
||||
|
||||
}
|
@ -8,7 +8,8 @@
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"clean": "rm -rf ./dist ./build",
|
||||
"build": "webpack --config ./webpack/prod.config.js",
|
||||
"start:dev": "webpack-dev-server --config ./webpack/dev.config.js"
|
||||
"start:dev": "webpack-dev-server --config ./webpack/dev.config.js",
|
||||
"lint": "tslint app/script/**/* || :"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -23,6 +24,7 @@
|
||||
"dependencies": {
|
||||
"@types/classnames": "0.0.32",
|
||||
"@types/node": "^7.0.13",
|
||||
"@types/object-assign": "^4.0.30",
|
||||
"@types/react": "^15.0.23",
|
||||
"@types/react-dom": "^15.5.0",
|
||||
"@types/react-fontawesome": "^1.5.0",
|
||||
@ -30,12 +32,13 @@
|
||||
"font-awesome": "^4.7.0",
|
||||
"mobx": "^3.1.9",
|
||||
"mobx-react": "^4.1.8",
|
||||
"object-assign": "^4.1.1",
|
||||
"paho-mqtt": "^1.0.3",
|
||||
"react": "^15.5.4",
|
||||
"react-dom": "^15.5.4",
|
||||
"react-fontawesome": "^1.6.1",
|
||||
"semantic-ui-css": "^2.2.10",
|
||||
"semantic-ui-react": "^0.67.0"
|
||||
"semantic-ui-react": "^0.67.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/webpack-env": "^1.13.0",
|
||||
|
@ -8,6 +8,7 @@
|
||||
},
|
||||
"files": [
|
||||
"./node_modules/@types/webpack-env/index.d.ts",
|
||||
"./app/script/paho-mqtt.d.ts",
|
||||
"./app/script/index.tsx"
|
||||
]
|
||||
}
|
25
tslint.json
Normal file
25
tslint.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"no-console": [
|
||||
false
|
||||
],
|
||||
"max-classes-per-file": [
|
||||
false
|
||||
],
|
||||
"ordered-imports": [
|
||||
false
|
||||
],
|
||||
"variable-name": [
|
||||
"allow-leading-underscore"
|
||||
],
|
||||
"no-namespace": [
|
||||
"allow-declarations"
|
||||
]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user