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