1
0
martijndierckx 5 жил өмнө
parent
commit
47f1d2a8a5

+ 2 - 0
.gitignore

@@ -5,6 +5,8 @@ logs
 *.log
 *.log
 npm-debug.log*
 npm-debug.log*
 
 
+TESTDATA.md
+
 node_modules
 node_modules
 
 
 # Optional npm cache directory
 # Optional npm cache directory

+ 0 - 25
HydrawiseController.js

@@ -1,25 +0,0 @@
-'use strict';
-/**
- * @author Martijn Dierckx
- */
-
-/** Class representing a Hydrawise controller */
-class HydrawiseController {
-
-	/**
-	 * Create a new instance of a HydrawiseController
-	 * @param {object} options - Options object containing all parameters
-	 * @param {Hydrawise} options.apiBinding - The API binding which can be used to execute commands on the zone
-	 */
-	constructor(options) {
-		this.id = options.id;
-		this.name = options.name;
-		this.serialNumber = options.serialNumber;
-		this.lastContactWithCloud = options.lastContactWithCloud;
-		this.status = options.status;
-	}
-}
-
-module.exports = options => {
-	return new HydrawiseController(options);
-};

+ 12 - 12
README.md

@@ -18,8 +18,8 @@ When possible use a local connection to your controller since it's not rate limi
 ### Setup for a cloud connection
 ### Setup for a cloud connection
 
 
 ```js
 ```js
-const Hydrawise = require('hydrawise-api');
-const myHydrawise = Hydrawise({ type:'CLOUD', key:'YOUR_API_KEY' });
+const Hydrawise = require('hydrawise-api').Hydrawise;
+const myHydrawise = new Hydrawise({ type:'CLOUD', key:'YOUR_API_KEY' });
 ```
 ```
 
 
 You can obtain your API key from the "Account Details" screen on the [Hydrawise platform](https://app.hydrawise.com/config/account/details)
 You can obtain your API key from the "Account Details" screen on the [Hydrawise platform](https://app.hydrawise.com/config/account/details)
@@ -27,8 +27,8 @@ You can obtain your API key from the "Account Details" screen on the [Hydrawise
 ### Setup for a local connection
 ### Setup for a local connection
 
 
 ```js
 ```js
-const Hydrawise = require('hydrawise-api');
-const myHydrawise = Hydrawise({ type:'LOCAL', host:'HOSTNAME_OR_IP_ADDRESS', password:'YOUR_CONTROLLER_PASSWORD' });
+const Hydrawise = require('hydrawise-api').Hydrawise;
+const myHydrawise = new Hydrawise({ type:'LOCAL', host:'HOSTNAME_OR_IP_ADDRESS', password:'YOUR_CONTROLLER_PASSWORD' });
 ```
 ```
 
 
 You can also provide a *user* parameter, but this should be 'admin' in most cases.
 You can also provide a *user* parameter, but this should be 'admin' in most cases.
@@ -48,14 +48,14 @@ myHydrawise.getZones()
 This will return an array of HydrawiseZone objects containing the following info:
 This will return an array of HydrawiseZone objects containing the following info:
 
 
 ```js
 ```js
-{Number} relayID - The unique relay number known to the Hydrawise cloud
-{Number} zone - The local zone/relay number
-{String} name - The name of the zone
+{number} relayID - The unique relay number known to the Hydrawise cloud
+{number} zone - The local zone/relay number
+{string} name - The name of the zone
 {Date} nextRunAt - The date & time of the next scheduled run 
 {Date} nextRunAt - The date & time of the next scheduled run 
-{Number} nextRunDuration - Run time in seconds of the next run defined by nextRunAt
-{Boolean} isSuspended - Returns true when the zoneis currently suspended
-{Boolean} isRunning - Returns true when the zone is actively running
-{Number} remainingRunningTime - Remaining run time in seconds when isRunning = true
+{number} nextRunDuration - Run time in seconds of the next run defined by nextRunAt
+{boolean} isSuspended - Returns true when the zoneis currently suspended
+{boolean} isRunning - Returns true when the zone is actively running
+{number} remainingRunningTime - Remaining run time in seconds when isRunning = true
 ```
 ```
 
 
 By default only the active zones are returned, you can change this behaviour by calling getZones(false) instead.
 By default only the active zones are returned, you can change this behaviour by calling getZones(false) instead.
@@ -101,7 +101,7 @@ Here as well, you are able to provide a custom duration: `runAllZones(600)` (for
 
 
 ## Contributors
 ## Contributors
 
 
-* Martijn Dierckx - Complete rewrite to service both the cloud & local API binding
+* Martijn Dierckx - Complete rewrite to service both the cloud & local API binding in TypeScript
 * [Paul Molluzzo](https://paul.molluzzo.com) - Initial 0.1.0 version containing the cloud binding
 * [Paul Molluzzo](https://paul.molluzzo.com) - Initial 0.1.0 version containing the cloud binding
 
 
 Tested on a configuration with a single HC6 controller. If you have multiple controllers in your configuration and you run into problems, you're free to create an issue or contribute yourself :-)
 Tested on a configuration with a single HC6 controller. If you have multiple controllers in your configuration and you run into problems, you're free to create an issue or contribute yourself :-)

+ 150 - 0
dist/Hydrawise.d.ts

@@ -0,0 +1,150 @@
+/**
+ * @author Martijn Dierckx - Complete rewrite to service both the cloud & local API binding
+ * @author Paul Molluzzo (https://paulmolluzzo.com) - Initial 0.1.0 version containing the cloud binding
+ */
+import { HydrawiseConnectionType } from './HydrawiseConnectionType';
+import { HydrawiseZone } from './HydrawiseZone';
+import { HydrawiseController } from './HydrawiseController';
+interface HydrawiseConfiguration {
+    type: HydrawiseConnectionType;
+    host?: string;
+    user?: string;
+    password?: string;
+    key?: string;
+}
+/** Class representing a Hydrawise local or cloud based API binding */
+export declare class Hydrawise {
+    private readonly cloudUrl;
+    type: HydrawiseConnectionType;
+    url: string;
+    localAuthUsername: string;
+    localAuthPassword: string;
+    cloudAuthAPIkey: string;
+    /**
+     * Create a new instance of the Hydrawise API binding
+     * @param {object} options - Options object containing all parameters
+     * @param {string} options.type - The type of binding you wish to make: 'CLOUD' or 'LOCAL'
+     * @param {string} [options.host] - The hostname or ip address of the local host you wish to connect to. Only needed for local bindings.
+     * @param {string} [options.user = admin] - The username of the local Hydrawise controller. Only needed for local bindings (falls back to the default 'admin' user).
+     * @param {string} [options.password] - The password of the local Hydrawise controller. Only needed for local bindings.
+     * @param {string} [options.key] - The API key of your Hydrawise cloud account. Only needed for cloud bindings.
+     */
+    constructor(options: HydrawiseConfiguration);
+    /**
+     * Private function that makes a GET request to the local or cloud Hydrawise server
+     * @param {string} path - The path of the API endpoint
+     * @param {object} [params] - Parameters to be added to the URL path
+     * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
+     */
+    private request;
+    /**
+     * Sends a command to a single zone/relay
+     * @param {string} action - The required command to be executed for the given zone/relay: run, suspend, stop
+     * @param {(HydrawiseZone|number|number)} zoneOrRelay - The zone/relay you are targetting. Can be a zone object returned by getZones, a relay number (zone.zone) for local bindings or a relayID (zone.relayID) for cloud bindings
+     * @param {number} [duration] - How long should the command be executed (only applicable for run & suspend)
+     * @todo Check whether controller_id needs to sent when the account contains multiple zones
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    commandZone(action: string, zoneOrRelay: number | HydrawiseZone, duration?: number): Promise<any>;
+    /**
+     * Sends a command to all zones/relays
+     * @param {string} action - The required command to be executed: runall, suspendall, stopall
+     * @param {number} [duration] - How long should the given command be executed (only applicable for runall & suspendall)
+     * @todo Check whether controller_id needs to sent when the account contains multiple zones
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    commandAllZones(action: string, duration?: number): Promise<any>;
+    /**
+     * Sends the run command to a single zone/relay
+     * @param {(HydrawiseZone|number|number)} zoneOrRelay - The zone/relay you are targetting. Can be a zone object returned by getZones, a relay number (zone.zone) for local bindings or a relayID (zone.relayID) for cloud bindings
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    runZone(zoneOrRelay: number | HydrawiseZone, duration?: number): Promise<any>;
+    /**
+     * Sends the run command to all zones/relays
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    runAllZones(duration?: number): Promise<any>;
+    /**
+     * Sends the suspend command to a single zone/relay
+     * @param {(HydrawiseZone|number|number)} zoneOrRelay - The zone/relay you are targetting. Can be a zone object returned by getZones, a relay number (zone.zone) for local bindings or a relayID (zone.relayID) for cloud bindings
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    suspendZone(zoneOrRelay: number | HydrawiseZone, duration?: number): Promise<any>;
+    /**
+     * Sends the suspend command to all zones/relays
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    suspendAllZones(duration?: number): Promise<any>;
+    /**
+     * Sends the stop command to a single zone/relay
+     * @param {(HydrawiseZone|number|number)} zoneOrRelay - The zone/relay you are targetting. Can be a zone object returned by getZones, a relay number (zone.zone) for local bindings or a relayID (zone.relayID) for cloud bindings
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    stopZone(zoneOrRelay: number | HydrawiseZone): Promise<any>;
+    /**
+     * Sends the stop command to all zones/relays
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    stopAllZones(): Promise<any>;
+    /**
+     * Retrieves all zones/relays known to the server
+     * @param {boolean} [onlyConfigured = true] - Only return zones/relays which have been configured
+     * @return {Promise} A Promise which will be resolved when all zones have been retrieved
+     */
+    getZones(onlyConfigured?: boolean): Promise<HydrawiseZone[]>;
+    /**
+     * Retrieves all controllers known to the Hydrawise cloud
+     * @return {Promise} A Promise which will be resolved when all controllers have been retrieved
+     */
+    getControllers(): Promise<HydrawiseController[]>;
+    /**
+     * Gets the customer ID & list of available controllers configured in the Hydrawise cloud. Only available in cloud binding.
+     * @param {string} type - Defines the type of customer details to be retrieved alongside the customer ID
+     * @return {Promise} A Promise which will be resolved when the request has returned from the cloud server.
+     */
+    getCustomerDetails(type: string): Promise<any>;
+    /**
+     * Gets the status and schedule of the locally connected controller or all controllers in the cloud
+     * @param {string} type - Defines the type of customer details to be retrieved alongside the customer ID
+     * @todo Check whether controller_id needs to sent when the account contains multiple zones
+     * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
+     */
+    getStatusAndSchedule(tag?: string, hours?: string): Promise<any>;
+    /**
+     * Sends an action request to a specific or all zones
+     * @param {object} params - Parameters object containing all parameters to be sent along with the request
+     * @param {string} params.action - The action to be executed: run, stop, suspend, runall, suspendall, stopall
+     * @todo Complete params documentation
+     * @todo Check whether controller_id needs to sent when the account contains multiple zones
+     * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
+     */
+    setZone(this: Hydrawise, params?: any): Promise<any>;
+    /**
+     * Does the same as getCustomerDetails, and is only kept to be backwards compatible with version 0.1.0 of this module
+     * @param {string} [type = controllers] - Defines the type of customer details to be retrieved alongside the customer ID
+     * @alias getCustomerDetails
+     * @return {Promise} A Promise which will be resolved when the request has returned from the cloud server.
+     */
+    customerdetails(type?: string): Promise<any>;
+    /**
+     * Does the same as getCustomerDetails, and is only kept to be backwards compatible with version 0.1.0 of this module
+     * @alias getStatusAndSchedule
+     * @deprecated since version 1.0.0. Please use getZones()
+     * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
+     */
+    statusschedule(tag?: string, hours?: string): Promise<any>;
+    /**
+     * Does the same as setZone, and is only kept to be backwards compatible with version 0.1.0 of this module
+     * @alias setZone
+     * @deprecated since version 1.0.0. Please use runZone(), suspendZone(), stopZone(), runAllZones(), suspendAllZones(), stopAllZones() or the run(), suspend(), stop() commands on a HydrawiseZone object.
+     * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
+     */
+    setzone(params?: any): Promise<any>;
+}
+export {};
+//# sourceMappingURL=Hydrawise.d.ts.map

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
dist/Hydrawise.d.ts.map


+ 351 - 0
dist/Hydrawise.js

@@ -0,0 +1,351 @@
+"use strict";
+/**
+ * @author Martijn Dierckx - Complete rewrite to service both the cloud & local API binding
+ * @author Paul Molluzzo (https://paulmolluzzo.com) - Initial 0.1.0 version containing the cloud binding
+ */
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const HydrawiseConnectionType_1 = require("./HydrawiseConnectionType");
+const HydrawiseZone_1 = require("./HydrawiseZone");
+const HydrawiseController_1 = require("./HydrawiseController");
+const HydrawiseCommandException_1 = require("./HydrawiseCommandException");
+const axios_1 = __importDefault(require("axios"));
+/** Class representing a Hydrawise local or cloud based API binding */
+class Hydrawise {
+    /**
+     * Create a new instance of the Hydrawise API binding
+     * @param {object} options - Options object containing all parameters
+     * @param {string} options.type - The type of binding you wish to make: 'CLOUD' or 'LOCAL'
+     * @param {string} [options.host] - The hostname or ip address of the local host you wish to connect to. Only needed for local bindings.
+     * @param {string} [options.user = admin] - The username of the local Hydrawise controller. Only needed for local bindings (falls back to the default 'admin' user).
+     * @param {string} [options.password] - The password of the local Hydrawise controller. Only needed for local bindings.
+     * @param {string} [options.key] - The API key of your Hydrawise cloud account. Only needed for cloud bindings.
+     */
+    constructor(options) {
+        this.cloudUrl = 'https://app.hydrawise.com/api/v1/';
+        this.type = options.type || HydrawiseConnectionType_1.HydrawiseConnectionType.CLOUD; // CLOUD or LOCAL 
+        this.url = options.host ? 'http://' + options.host + '/' : this.cloudUrl;
+        // Local Auth
+        this.localAuthUsername = options.user || 'admin';
+        this.localAuthPassword = options.password || '';
+        // Cloud Auth
+        this.cloudAuthAPIkey = options.key || '';
+    }
+    /**
+     * Private function that makes a GET request to the local or cloud Hydrawise server
+     * @param {string} path - The path of the API endpoint
+     * @param {object} [params] - Parameters to be added to the URL path
+     * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
+     */
+    request(path = '', params = {}) {
+        let promise = new Promise((resolve, reject) => {
+            // setup basic request
+            let options = {
+                method: 'get',
+                url: this.url + path,
+                params: params,
+                json: true
+            };
+            // Basic auth for local binding
+            if (this.type == HydrawiseConnectionType_1.HydrawiseConnectionType.LOCAL) {
+                let authBuffer = Buffer.from(this.localAuthUsername + ':' + this.localAuthPassword);
+                options.headers = {
+                    'Authorization': 'Basic ' + authBuffer.toString('base64')
+                };
+            }
+            // API key auth for cloud binding
+            else {
+                options.qs.api_key = this.cloudAuthAPIkey;
+            }
+            // Send request
+            axios_1.default(options).then((response) => {
+                //Check for errors
+                if (response.data.messageType == 'error') {
+                    reject(new HydrawiseCommandException_1.HydrawiseCommandException(response.data.message));
+                }
+                resolve(response.data);
+            }).catch((err) => {
+                reject(err);
+            });
+        });
+        // return request
+        return promise;
+    }
+    /**
+     * Sends a command to a single zone/relay
+     * @param {string} action - The required command to be executed for the given zone/relay: run, suspend, stop
+     * @param {(HydrawiseZone|number|number)} zoneOrRelay - The zone/relay you are targetting. Can be a zone object returned by getZones, a relay number (zone.zone) for local bindings or a relayID (zone.relayID) for cloud bindings
+     * @param {number} [duration] - How long should the command be executed (only applicable for run & suspend)
+     * @todo Check whether controller_id needs to sent when the account contains multiple zones
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    commandZone(action, zoneOrRelay, duration) {
+        let that = this;
+        // Get started
+        let promise = new Promise((resolve, reject) => {
+            let opts = {
+                period_id: 998,
+                action: action,
+            };
+            // Set Relay number for local binding
+            if (that.type == HydrawiseConnectionType_1.HydrawiseConnectionType.LOCAL) {
+                opts.relay = typeof zoneOrRelay == 'object' ? zoneOrRelay.zone : zoneOrRelay; // A zone object, as returned by getZones, or just the relayID can be sent
+            }
+            // Set Relay ID for cloud binding
+            else {
+                opts.relay_id = typeof zoneOrRelay == 'object' ? zoneOrRelay.relayID : zoneOrRelay; // A zone object, as returned by getZones, or just the relayID can be sent
+            }
+            // Custom duration?
+            if (duration !== undefined) {
+                opts.custom = duration;
+            }
+            // Execute command
+            that.setZone(opts).then((data) => {
+                resolve(data);
+            }).catch((err) => {
+                reject(err);
+            });
+        });
+        return promise;
+    }
+    /**
+     * Sends a command to all zones/relays
+     * @param {string} action - The required command to be executed: runall, suspendall, stopall
+     * @param {number} [duration] - How long should the given command be executed (only applicable for runall & suspendall)
+     * @todo Check whether controller_id needs to sent when the account contains multiple zones
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    commandAllZones(action, duration) {
+        let that = this;
+        // Get started
+        let promise = new Promise((resolve, reject) => {
+            let opts = {
+                period_id: 998,
+                action: action
+            };
+            // Custom duration?
+            if (duration !== undefined) {
+                opts.custom = duration;
+            }
+            that.setZone(opts).then(data => {
+                resolve(data);
+            }).catch((err) => {
+                reject(err);
+            });
+        });
+        return promise;
+    }
+    /**
+     * Sends the run command to a single zone/relay
+     * @param {(HydrawiseZone|number|number)} zoneOrRelay - The zone/relay you are targetting. Can be a zone object returned by getZones, a relay number (zone.zone) for local bindings or a relayID (zone.relayID) for cloud bindings
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    runZone(zoneOrRelay, duration) {
+        return this.commandZone('run', zoneOrRelay, duration);
+    }
+    /**
+     * Sends the run command to all zones/relays
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    runAllZones(duration) {
+        return this.commandAllZones('runall', duration);
+    }
+    /**
+     * Sends the suspend command to a single zone/relay
+     * @param {(HydrawiseZone|number|number)} zoneOrRelay - The zone/relay you are targetting. Can be a zone object returned by getZones, a relay number (zone.zone) for local bindings or a relayID (zone.relayID) for cloud bindings
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    suspendZone(zoneOrRelay, duration) {
+        return this.commandZone('suspend', zoneOrRelay, duration);
+    }
+    /**
+     * Sends the suspend command to all zones/relays
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    suspendAllZones(duration) {
+        return this.commandAllZones('suspendall', duration);
+    }
+    /**
+     * Sends the stop command to a single zone/relay
+     * @param {(HydrawiseZone|number|number)} zoneOrRelay - The zone/relay you are targetting. Can be a zone object returned by getZones, a relay number (zone.zone) for local bindings or a relayID (zone.relayID) for cloud bindings
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    stopZone(zoneOrRelay) {
+        return this.commandZone('stop', zoneOrRelay);
+    }
+    /**
+     * Sends the stop command to all zones/relays
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    stopAllZones() {
+        return this.commandAllZones('stopall');
+    }
+    /**
+     * Retrieves all zones/relays known to the server
+     * @param {boolean} [onlyConfigured = true] - Only return zones/relays which have been configured
+     * @return {Promise} A Promise which will be resolved when all zones have been retrieved
+     */
+    getZones(onlyConfigured = true) {
+        let that = this;
+        // Get started
+        let promise = new Promise((resolve, reject) => {
+            // Get relays
+            that.getStatusAndSchedule().then((data) => {
+                let zones = [];
+                // Check every returned relay
+                data.relays.map((z) => {
+                    // Only configured zones
+                    if (onlyConfigured && z.type != 110) {
+                        // Zone
+                        let zone = {
+                            apiBinding: that,
+                            relayID: z.relay_id,
+                            zone: z.relay,
+                            name: z.name,
+                            nextRunAt: new Date((data.time + z.time) * 1000),
+                            nextRunDuration: z.run || z.run_seconds,
+                            isSuspended: z.suspended !== undefined && z.suspended == 1,
+                            isRunning: false,
+                            remainingRunningTime: 0,
+                        };
+                        // Only available data for local connections
+                        if (that.type == HydrawiseConnectionType_1.HydrawiseConnectionType.LOCAL) {
+                            zone.defaultRunDuration = z.normalRuntime * 60;
+                        }
+                        // Running?
+                        if (data.running !== undefined) {
+                            let runningZone = data.running.find((x) => {
+                                return x.relay_id == z.relay_id;
+                            });
+                            if (runningZone != undefined && runningZone != null) {
+                                zone.isRunning = true;
+                                zone.remainingRunningTime = runningZone.time_left;
+                            }
+                        }
+                        zones.push(new HydrawiseZone_1.HydrawiseZone(zone));
+                    }
+                });
+                resolve(zones);
+            }).catch((err) => {
+                reject(err);
+            });
+        });
+        return promise;
+    }
+    /**
+     * Retrieves all controllers known to the Hydrawise cloud
+     * @return {Promise} A Promise which will be resolved when all controllers have been retrieved
+     */
+    getControllers() {
+        let that = this;
+        // Get started
+        let promise = new Promise((resolve, reject) => {
+            // Get Controllers
+            this.getCustomerDetails('controllers').then(data => {
+                let controllers = [];
+                // Check every returned relay
+                data.controllers.map((c) => {
+                    // Zone
+                    let controller = {
+                        id: c.controller_id,
+                        name: c.name,
+                        serialNumber: c.serial_number,
+                        lastContactWithCloud: new Date(c.last_contact * 1000),
+                        status: c.status
+                    };
+                    controllers.push(new HydrawiseController_1.HydrawiseController(controller));
+                });
+                resolve(controllers);
+            }).catch((err) => {
+                reject(err);
+            });
+        });
+        return promise;
+    }
+    /* -------- Raw API calls -------- */
+    /**
+     * Gets the customer ID & list of available controllers configured in the Hydrawise cloud. Only available in cloud binding.
+     * @param {string} type - Defines the type of customer details to be retrieved alongside the customer ID
+     * @return {Promise} A Promise which will be resolved when the request has returned from the cloud server.
+     */
+    getCustomerDetails(type) {
+        // Cloud only API
+        if (this.type == HydrawiseConnectionType_1.HydrawiseConnectionType.LOCAL) {
+            return new Promise((resolve, reject) => {
+                reject(new HydrawiseCommandException_1.HydrawiseCommandException('Calling Cloud API function on a Local Binding'));
+            });
+        }
+        return this.request('customerdetails.php', { type: type });
+    }
+    /**
+     * Gets the status and schedule of the locally connected controller or all controllers in the cloud
+     * @param {string} type - Defines the type of customer details to be retrieved alongside the customer ID
+     * @todo Check whether controller_id needs to sent when the account contains multiple zones
+     * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
+     */
+    getStatusAndSchedule(tag = '', hours = '168') {
+        let uri = (this.type == HydrawiseConnectionType_1.HydrawiseConnectionType.LOCAL ? 'get_sched_json.php' : 'statusschedule.php');
+        return this.request(uri, { tag, hours });
+    }
+    /*setController(controllerID: number): Promise<any> {
+        // Cloud only API
+        if (this.type  == HydrawiseConnectionType.LOCAL) {
+            return new Promise((resolve, reject) => {
+                reject(new HydrawiseCommandException('Calling Cloud API function on a Local Binding'));
+            });
+        }
+        
+        return this.request('setcontroller.php', { controllerID, json: true });
+    }*/
+    /**
+     * Sends an action request to a specific or all zones
+     * @param {object} params - Parameters object containing all parameters to be sent along with the request
+     * @param {string} params.action - The action to be executed: run, stop, suspend, runall, suspendall, stopall
+     * @todo Complete params documentation
+     * @todo Check whether controller_id needs to sent when the account contains multiple zones
+     * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
+     */
+    setZone(params = {}) {
+        let uri = (this.type == HydrawiseConnectionType_1.HydrawiseConnectionType.LOCAL ? 'set_manual_data.php' : 'setzone.php');
+        return this.request(uri, params);
+    }
+    /* -------- Original 0.1.0 function names for backwards compatibility -------- */
+    /**
+     * Does the same as getCustomerDetails, and is only kept to be backwards compatible with version 0.1.0 of this module
+     * @param {string} [type = controllers] - Defines the type of customer details to be retrieved alongside the customer ID
+     * @alias getCustomerDetails
+     * @return {Promise} A Promise which will be resolved when the request has returned from the cloud server.
+     */
+    customerdetails(type = 'controllers') {
+        return this.getCustomerDetails(type);
+    }
+    /**
+     * Does the same as getCustomerDetails, and is only kept to be backwards compatible with version 0.1.0 of this module
+     * @alias getStatusAndSchedule
+     * @deprecated since version 1.0.0. Please use getZones()
+     * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
+     */
+    statusschedule(tag = '', hours = '168') {
+        return this.getStatusAndSchedule(tag, hours);
+    }
+    /*setcontroller(controllerID) {
+        return this.setController(controllerID);
+    }*/
+    /**
+     * Does the same as setZone, and is only kept to be backwards compatible with version 0.1.0 of this module
+     * @alias setZone
+     * @deprecated since version 1.0.0. Please use runZone(), suspendZone(), stopZone(), runAllZones(), suspendAllZones(), stopAllZones() or the run(), suspend(), stop() commands on a HydrawiseZone object.
+     * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
+     */
+    setzone(params = {}) {
+        return this.setZone(params);
+    }
+}
+exports.Hydrawise = Hydrawise;
+//# sourceMappingURL=Hydrawise.js.map

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
dist/Hydrawise.js.map


+ 9 - 0
dist/HydrawiseCommandException.d.ts

@@ -0,0 +1,9 @@
+/**
+ * @author Martijn Dierckx
+ */
+/** Class representing a specifc error triggered by the Hydrawise API binding */
+export declare class HydrawiseCommandException extends Error {
+    date: Date;
+    constructor(message: string, ...params: any);
+}
+//# sourceMappingURL=HydrawiseCommandException.d.ts.map

+ 1 - 0
dist/HydrawiseCommandException.d.ts.map

@@ -0,0 +1 @@
+{"version":3,"file":"HydrawiseCommandException.d.ts","sourceRoot":"","sources":["../src/HydrawiseCommandException.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,gFAAgF;AAChF,qBAAa,yBAA0B,SAAQ,KAAK;IAE5C,IAAI,EAAE,IAAI,CAAC;gBAEN,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAC,GAAG;CAS1C"}

+ 17 - 0
dist/HydrawiseCommandException.js

@@ -0,0 +1,17 @@
+"use strict";
+/**
+ * @author Martijn Dierckx
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+/** Class representing a specifc error triggered by the Hydrawise API binding */
+class HydrawiseCommandException extends Error {
+    constructor(message, ...params) {
+        super(...params);
+        Error.captureStackTrace(this, HydrawiseCommandException);
+        this.name = 'HydrawiseCommandException';
+        this.message = message;
+        this.date = new Date();
+    }
+}
+exports.HydrawiseCommandException = HydrawiseCommandException;
+//# sourceMappingURL=HydrawiseCommandException.js.map

+ 1 - 0
dist/HydrawiseCommandException.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"HydrawiseCommandException.js","sourceRoot":"","sources":["../src/HydrawiseCommandException.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAEH,gFAAgF;AAChF,MAAa,yBAA0B,SAAQ,KAAK;IAInD,YAAY,OAAe,EAAE,GAAG,MAAU;QACzC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC;QAEjB,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAAC;QAEzD,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IACxB,CAAC;CACD;AAbD,8DAaC"}

+ 10 - 0
dist/HydrawiseConnectionType.d.ts

@@ -0,0 +1,10 @@
+/**
+ * Enumeration for the different types of Hydrawise API bindings: Cloud or Local
+ * @readonly
+ * @enum {string}
+ */
+export declare enum HydrawiseConnectionType {
+    LOCAL = "LOCAL",
+    CLOUD = "CLOUD"
+}
+//# sourceMappingURL=HydrawiseConnectionType.d.ts.map

+ 1 - 0
dist/HydrawiseConnectionType.d.ts.map

@@ -0,0 +1 @@
+{"version":3,"file":"HydrawiseConnectionType.d.ts","sourceRoot":"","sources":["../src/HydrawiseConnectionType.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,oBAAY,uBAAuB;IAClC,KAAK,UAAU;IACf,KAAK,UAAU;CACf"}

+ 13 - 0
dist/HydrawiseConnectionType.js

@@ -0,0 +1,13 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+/**
+ * Enumeration for the different types of Hydrawise API bindings: Cloud or Local
+ * @readonly
+ * @enum {string}
+ */
+var HydrawiseConnectionType;
+(function (HydrawiseConnectionType) {
+    HydrawiseConnectionType["LOCAL"] = "LOCAL";
+    HydrawiseConnectionType["CLOUD"] = "CLOUD";
+})(HydrawiseConnectionType = exports.HydrawiseConnectionType || (exports.HydrawiseConnectionType = {}));
+//# sourceMappingURL=HydrawiseConnectionType.js.map

+ 1 - 0
dist/HydrawiseConnectionType.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"HydrawiseConnectionType.js","sourceRoot":"","sources":["../src/HydrawiseConnectionType.ts"],"names":[],"mappings":";;AAAA;;;;GAIG;AACH,IAAY,uBAGX;AAHD,WAAY,uBAAuB;IAClC,0CAAe,CAAA;IACf,0CAAe,CAAA;AAChB,CAAC,EAHW,uBAAuB,GAAvB,+BAAuB,KAAvB,+BAAuB,QAGlC"}

+ 22 - 0
dist/HydrawiseController.d.ts

@@ -0,0 +1,22 @@
+/**
+ * @author Martijn Dierckx
+ */
+/** Class representing a Hydrawise controller */
+export declare class HydrawiseController {
+    id: number;
+    name: string;
+    serialNumber: string;
+    lastContactWithCloud: Date;
+    status: string;
+    /**
+     * Create a new instance of a HydrawiseController
+     * @param {object} options - Options object containing all parameters
+     * @param {number} options.id - The unique identifier of the controller
+     * @param {string} options.name - The name of the controller
+     * @param {string} options.serialNumber - The serial number of the controller
+     * @param {Date} options.lastContactWithCloud - The last date time the controller was able to contact/sync with the cloud
+     * @param {string} options.status - The status as returned by the Hydrawise cloud
+     */
+    constructor(options: any);
+}
+//# sourceMappingURL=HydrawiseController.d.ts.map

+ 1 - 0
dist/HydrawiseController.d.ts.map

@@ -0,0 +1 @@
+{"version":3,"file":"HydrawiseController.d.ts","sourceRoot":"","sources":["../src/HydrawiseController.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,gDAAgD;AAChD,qBAAa,mBAAmB;IAExB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IAEtB;;;;;;;;OAQG;gBACS,OAAO,EAAE,GAAG;CAOxB"}

+ 26 - 0
dist/HydrawiseController.js

@@ -0,0 +1,26 @@
+"use strict";
+/**
+ * @author Martijn Dierckx
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+/** Class representing a Hydrawise controller */
+class HydrawiseController {
+    /**
+     * Create a new instance of a HydrawiseController
+     * @param {object} options - Options object containing all parameters
+     * @param {number} options.id - The unique identifier of the controller
+     * @param {string} options.name - The name of the controller
+     * @param {string} options.serialNumber - The serial number of the controller
+     * @param {Date} options.lastContactWithCloud - The last date time the controller was able to contact/sync with the cloud
+     * @param {string} options.status - The status as returned by the Hydrawise cloud
+     */
+    constructor(options) {
+        this.id = options.id;
+        this.name = options.name;
+        this.serialNumber = options.serialNumber;
+        this.lastContactWithCloud = options.lastContactWithCloud;
+        this.status = options.status;
+    }
+}
+exports.HydrawiseController = HydrawiseController;
+//# sourceMappingURL=HydrawiseController.js.map

+ 1 - 0
dist/HydrawiseController.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"HydrawiseController.js","sourceRoot":"","sources":["../src/HydrawiseController.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAEH,gDAAgD;AAChD,MAAa,mBAAmB;IAQ/B;;;;;;;;OAQG;IACH,YAAY,OAAY;QACvB,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QACzD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,CAAC;CACD;AAxBD,kDAwBC"}

+ 48 - 0
dist/HydrawiseZone.d.ts

@@ -0,0 +1,48 @@
+/**
+ * @author Martijn Dierckx
+ */
+import { Hydrawise } from "./Hydrawise";
+/** Class representing a Hydrawise zone */
+export declare class HydrawiseZone {
+    apiBinding: Hydrawise;
+    relayID: number;
+    zone: number;
+    name: string;
+    nextRunAt: Date;
+    nextRunDuration: number;
+    isSuspended: boolean;
+    isRunning: boolean;
+    remainingRunningTime: number;
+    /**
+     * Create a new instance of a HydrawiseZone
+     * @param {object} options - Options object containing all parameters
+     * @param {Hydrawise} options.apiBinding - The API binding which can be used to execute commands on the zone
+     * @param {number} options.relayID - The unique relay number known to the Hydrawise cloud
+     * @param {number} options.zone - The local zone/relay number
+     * @param {string} options.name - The name of the zone
+     * @param {Date} options.nextRunAt - The date & time of the next scheduled run
+     * @param {number} options.nextRunDuration - Run time in seconds of the next run defined by nextRunAt
+     * @param {boolean} options.isSuspended - Returns true when the zoneis currently suspended
+     * @param {boolean} options.isRunning - Returns true when the zone is actively running
+     * @param {number} options.remainingRunningTime - Remaining run time in seconds when isRunning = true
+     */
+    constructor(options: any);
+    /**
+     * Sends the run command to the zone/relay
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    run(duration: number): Promise<any>;
+    /**
+     * Sends the stop command to the zone/relay
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    stop(): Promise<any>;
+    /**
+     * Sends the suspend command to the zone/relay
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    suspend(duration: number): Promise<any>;
+}
+//# sourceMappingURL=HydrawiseZone.d.ts.map

+ 1 - 0
dist/HydrawiseZone.d.ts.map

@@ -0,0 +1 @@
+{"version":3,"file":"HydrawiseZone.d.ts","sourceRoot":"","sources":["../src/HydrawiseZone.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,0CAA0C;AAC1C,qBAAa,aAAa;IAElB,UAAU,EAAE,SAAS,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;IAEpC;;;;;;;;;;;;OAYG;gBACS,OAAO,EAAE,GAAG;IAYxB;;;;OAIG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAInC;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC;IAIpB;;;;OAIG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CAGvC"}

+ 57 - 0
dist/HydrawiseZone.js

@@ -0,0 +1,57 @@
+"use strict";
+/**
+ * @author Martijn Dierckx
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+/** Class representing a Hydrawise zone */
+class HydrawiseZone {
+    /**
+     * Create a new instance of a HydrawiseZone
+     * @param {object} options - Options object containing all parameters
+     * @param {Hydrawise} options.apiBinding - The API binding which can be used to execute commands on the zone
+     * @param {number} options.relayID - The unique relay number known to the Hydrawise cloud
+     * @param {number} options.zone - The local zone/relay number
+     * @param {string} options.name - The name of the zone
+     * @param {Date} options.nextRunAt - The date & time of the next scheduled run
+     * @param {number} options.nextRunDuration - Run time in seconds of the next run defined by nextRunAt
+     * @param {boolean} options.isSuspended - Returns true when the zoneis currently suspended
+     * @param {boolean} options.isRunning - Returns true when the zone is actively running
+     * @param {number} options.remainingRunningTime - Remaining run time in seconds when isRunning = true
+     */
+    constructor(options) {
+        this.apiBinding = options.apiBinding;
+        this.relayID = options.relayID;
+        this.zone = options.zone;
+        this.name = options.name;
+        this.nextRunAt = options.nextRunAt;
+        this.nextRunDuration = options.nextRunDuration;
+        this.isSuspended = options.isSuspended;
+        this.isRunning = options.isRunning;
+        this.remainingRunningTime = options.remainingRunningTime;
+    }
+    /**
+     * Sends the run command to the zone/relay
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    run(duration) {
+        return this.apiBinding.commandZone('run', this, duration);
+    }
+    /**
+     * Sends the stop command to the zone/relay
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    stop() {
+        return this.apiBinding.commandZone('stop', this);
+    }
+    /**
+     * Sends the suspend command to the zone/relay
+     * @param {number} [duration] - How long should the command be executed
+     * @return {Promise} A Promise which will be resolved when the command has been executed.
+     */
+    suspend(duration) {
+        return this.apiBinding.commandZone('suspend', this, duration);
+    }
+}
+exports.HydrawiseZone = HydrawiseZone;
+//# sourceMappingURL=HydrawiseZone.js.map

+ 1 - 0
dist/HydrawiseZone.js.map

@@ -0,0 +1 @@
+{"version":3,"file":"HydrawiseZone.js","sourceRoot":"","sources":["../src/HydrawiseZone.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAIH,0CAA0C;AAC1C,MAAa,aAAa;IAYzB;;;;;;;;;;;;OAYG;IACH,YAAY,OAAY;QACvB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAC1D,CAAC;IAED;;;;OAIG;IACH,GAAG,CAAC,QAAgB;QACnB,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC;IAED;;;OAGG;IACH,IAAI;QACH,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,QAAgB;QACvB,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC;CACD;AA9DD,sCA8DC"}

+ 101 - 328
package-lock.json

@@ -1,373 +1,146 @@
 {
 {
   "name": "hydrawise-api",
   "name": "hydrawise-api",
-  "version": "0.2.0",
+  "version": "1.0.0",
   "lockfileVersion": 1,
   "lockfileVersion": 1,
   "requires": true,
   "requires": true,
   "dependencies": {
   "dependencies": {
-    "ajv": {
-      "version": "6.12.2",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
-      "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
-      "requires": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      }
-    },
-    "asn1": {
-      "version": "0.2.4",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
-      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
-      "requires": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
-    },
-    "asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
-    },
-    "aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
-    },
-    "aws4": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
-      "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
-    },
-    "bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "requires": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
-    "bluebird": {
-      "version": "3.7.2",
-      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
-      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
-    },
-    "caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+    "@types/node": {
+      "version": "10.17.19",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.19.tgz",
+      "integrity": "sha512-46/xThm3zvvc9t9/7M3AaLEqtOpqlYYYcCZbpYVAQHG20+oMZBkae/VMrn4BTi6AJ8cpack0mEXhGiKmDNbLrQ==",
+      "dev": true
     },
     },
-    "combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+    "axios": {
+      "version": "0.19.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
+      "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
       "requires": {
       "requires": {
-        "delayed-stream": "~1.0.0"
+        "follow-redirects": "1.5.10"
       }
       }
     },
     },
-    "core-util-is": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
-    },
-    "dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "requires": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "delayed-stream": {
+    "balanced-match": {
       "version": "1.0.0",
       "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
-    },
-    "ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
-      "requires": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
-    "extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
-    },
-    "extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
-    },
-    "fast-deep-equal": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
-      "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
-    },
-    "fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
-    },
-    "forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
-    },
-    "form-data": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
-      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
-      "requires": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
-        "mime-types": "^2.1.12"
-      }
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
     },
     },
-    "getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
       "requires": {
       "requires": {
-        "assert-plus": "^1.0.0"
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
       }
       }
     },
     },
-    "har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
     },
     },
-    "har-validator": {
-      "version": "5.1.3",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
-      "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+    "debug": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
       "requires": {
       "requires": {
-        "ajv": "^6.5.5",
-        "har-schema": "^2.0.0"
+        "ms": "2.0.0"
       }
       }
     },
     },
-    "http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+    "follow-redirects": {
+      "version": "1.5.10",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+      "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
       "requires": {
       "requires": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^1.2.2",
-        "sshpk": "^1.7.0"
+        "debug": "=3.1.0"
       }
       }
     },
     },
-    "is-typedarray": {
+    "fs.realpath": {
       "version": "1.0.0",
       "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
-    },
-    "isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
-    },
-    "jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
-    },
-    "json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
-    },
-    "json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
-    },
-    "json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
-    },
-    "jsprim": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-      "requires": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.2.3",
-        "verror": "1.10.0"
-      }
-    },
-    "lodash": {
-      "version": "4.17.15",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
-    },
-    "mime-db": {
-      "version": "1.44.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
-      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
-    },
-    "mime-types": {
-      "version": "2.1.27",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
-      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
-      "requires": {
-        "mime-db": "1.44.0"
-      }
-    },
-    "oauth-sign": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
-      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
     },
     },
-    "performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
-    },
-    "psl": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
-      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
-    },
-    "punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
-    },
-    "qs": {
-      "version": "6.5.2",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
-      "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
-    },
-    "request": {
-      "version": "2.88.2",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
-      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+    "glob": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+      "dev": true,
       "requires": {
       "requires": {
-        "aws-sign2": "~0.7.0",
-        "aws4": "^1.8.0",
-        "caseless": "~0.12.0",
-        "combined-stream": "~1.0.6",
-        "extend": "~3.0.2",
-        "forever-agent": "~0.6.1",
-        "form-data": "~2.3.2",
-        "har-validator": "~5.1.3",
-        "http-signature": "~1.2.0",
-        "is-typedarray": "~1.0.0",
-        "isstream": "~0.1.2",
-        "json-stringify-safe": "~5.0.1",
-        "mime-types": "~2.1.19",
-        "oauth-sign": "~0.9.0",
-        "performance-now": "^2.1.0",
-        "qs": "~6.5.2",
-        "safe-buffer": "^5.1.2",
-        "tough-cookie": "~2.5.0",
-        "tunnel-agent": "^0.6.0",
-        "uuid": "^3.3.2"
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
       }
       }
     },
     },
-    "request-promise": {
-      "version": "4.2.5",
-      "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz",
-      "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==",
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
       "requires": {
       "requires": {
-        "bluebird": "^3.5.0",
-        "request-promise-core": "1.1.3",
-        "stealthy-require": "^1.1.1",
-        "tough-cookie": "^2.3.3"
+        "once": "^1.3.0",
+        "wrappy": "1"
       }
       }
     },
     },
-    "request-promise-core": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
-      "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
-      "requires": {
-        "lodash": "^4.17.15"
-      }
-    },
-    "safe-buffer": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
-      "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
-    },
-    "safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    "inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
     },
     },
-    "sshpk": {
-      "version": "1.16.1",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
-      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
       "requires": {
       "requires": {
-        "asn1": "~0.2.3",
-        "assert-plus": "^1.0.0",
-        "bcrypt-pbkdf": "^1.0.0",
-        "dashdash": "^1.12.0",
-        "ecc-jsbn": "~0.1.1",
-        "getpass": "^0.1.1",
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.0.2",
-        "tweetnacl": "~0.14.0"
+        "brace-expansion": "^1.1.7"
       }
       }
     },
     },
-    "stealthy-require": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
-      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
-    },
-    "tough-cookie": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
-      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
-      "requires": {
-        "psl": "^1.1.28",
-        "punycode": "^2.1.1"
-      }
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
     },
     },
-    "tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
       "requires": {
       "requires": {
-        "safe-buffer": "^5.0.1"
+        "wrappy": "1"
       }
       }
     },
     },
-    "tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
     },
     },
-    "uri-js": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
-      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+    "rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "dev": true,
       "requires": {
       "requires": {
-        "punycode": "^2.1.0"
+        "glob": "^7.1.3"
       }
       }
     },
     },
-    "uuid": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+    "typescript": {
+      "version": "3.8.3",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
+      "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
+      "dev": true
     },
     },
-    "verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-      "requires": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      }
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
     }
     }
   }
   }
 }
 }

+ 18 - 5
package.json

@@ -6,7 +6,9 @@
     "type": "git",
     "type": "git",
     "url": "https://github.com/paulmolluzzo/hydrawise-api.git"
     "url": "https://github.com/paulmolluzzo/hydrawise-api.git"
   },
   },
-  "main": "index.js",
+  "main": "dist/Hydrawise.js",
+  "type": "commonjs",
+  "types": "./dist/Hydrawise.d.ts",
   "keywords": [
   "keywords": [
     "hydrawise",
     "hydrawise",
     "api",
     "api",
@@ -15,17 +17,28 @@
     "hunter",
     "hunter",
     "hunter industries"
     "hunter industries"
   ],
   ],
+  "scripts": {
+    "clean": "rimraf ./dist",
+    "build": "rimraf ./dist && tsc",
+    "prepublishOnly": "npm run build",
+    "postpublish": "npm run clean",
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
   "contributors": [
   "contributors": [
     "Martijn Dierckx",
     "Martijn Dierckx",
     "Paul Molluzzo (https://paul.molluzzo.com)"
     "Paul Molluzzo (https://paul.molluzzo.com)"
   ],
   ],
   "license": "MIT",
   "license": "MIT",
   "engines": {
   "engines": {
-    "node": ">=6.0.0",
-    "npm": ">=3.8.0"
+    "node": ">=11.0.0",
+    "npm": ">=6.9.0"
   },
   },
   "dependencies": {
   "dependencies": {
-    "request": "^2.88.2",
-    "request-promise": "^4.2.5"
+    "axios": "^0.19.2"
+  },
+  "devDependencies": {
+    "@types/node": "^10.17.19",
+    "rimraf": "^3.0.2",
+    "typescript": "^3.8.3"
   }
   }
 }
 }

+ 87 - 89
index.js → src/Hydrawise.ts

@@ -1,28 +1,31 @@
-'use strict';
 /**
 /**
  * @author Martijn Dierckx - Complete rewrite to service both the cloud & local API binding
  * @author Martijn Dierckx - Complete rewrite to service both the cloud & local API binding
- * @author Paul Molluzzo (https://paul.molluzzo.com) - Initial 0.1.0 version containing the cloud binding
+ * @author Paul Molluzzo (https://paulmolluzzo.com) - Initial 0.1.0 version containing the cloud binding
  */
  */
 
 
-const Request = require('request-promise');
-const HydrawiseZone = require('./HydrawiseZone');
-const HydrawiseController = require('./HydrawiseController');
-const HydrawiseCommandException = require('./HydrawiseCommandException');
-
-/**
- * Enumeration for the different types of Hydrawise API bindings: Cloud or Local
- * @readonly
- * @enum {string}
- */
-class HydrawiseConnectionType {
-	static LOCAL = 'LOCAL';
-	static CLOUD = 'CLOUD';
+import { HydrawiseConnectionType } from './HydrawiseConnectionType';
+import { HydrawiseZone } from './HydrawiseZone';
+import { HydrawiseController } from './HydrawiseController';
+import { HydrawiseCommandException } from './HydrawiseCommandException';
+import Axios from 'axios';
+
+interface HydrawiseConfiguration {
+	type : HydrawiseConnectionType,
+	host ?: string,
+	user ?: string,
+	password ?: string,
+	key ?: string
 }
 }
 
 
 /** Class representing a Hydrawise local or cloud based API binding */
 /** Class representing a Hydrawise local or cloud based API binding */
-class Hydrawise {
+export class Hydrawise {
 	
 	
-	#cloudUrl = 'https://app.hydrawise.com/api/v1/';
+	private readonly cloudUrl: string = 'https://app.hydrawise.com/api/v1/';
+	public type: HydrawiseConnectionType;
+	public url: string;
+	public localAuthUsername: string;
+	public localAuthPassword: string;
+	public cloudAuthAPIkey: string;
 	
 	
 	/**
 	/**
 	 * Create a new instance of the Hydrawise API binding
 	 * Create a new instance of the Hydrawise API binding
@@ -33,18 +36,16 @@ class Hydrawise {
 	 * @param {string} [options.password] - The password of the local Hydrawise controller. Only needed for local bindings.
 	 * @param {string} [options.password] - The password of the local Hydrawise controller. Only needed for local bindings.
 	 * @param {string} [options.key] - The API key of your Hydrawise cloud account. Only needed for cloud bindings.
 	 * @param {string} [options.key] - The API key of your Hydrawise cloud account. Only needed for cloud bindings.
 	 */
 	 */
-	constructor(options) {
+	constructor(options: HydrawiseConfiguration) {
 		this.type = options.type || HydrawiseConnectionType.CLOUD; // CLOUD or LOCAL 
 		this.type = options.type || HydrawiseConnectionType.CLOUD; // CLOUD or LOCAL 
-		this.url = options.host ? 'http://'+options.host+'/' : this.#cloudUrl;
+		this.url = options.host ? 'http://'+options.host+'/' : this.cloudUrl;
 		
 		
 		// Local Auth
 		// Local Auth
-		this.localauth = {
-			user: options.user || 'admin',
-			password: options.password
-		}
+		this.localAuthUsername = options.user || 'admin';
+		this.localAuthPassword = options.password || '';
 
 
 		// Cloud Auth
 		// Cloud Auth
-		this.api_key = options.key;
+		this.cloudAuthAPIkey = options.key || '';
 	}
 	}
 
 
 	/**
 	/**
@@ -53,40 +54,40 @@ class Hydrawise {
 	 * @param {object} [params] - Parameters to be added to the URL path
 	 * @param {object} [params] - Parameters to be added to the URL path
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
 	 */
 	 */
-	#request = (path = '', params = {}) => {
+	private request(path: string = '', params: any = {}): Promise<any> {
 		let promise = new Promise((resolve, reject) => {
 		let promise = new Promise((resolve, reject) => {
 
 
 			// setup basic request
 			// setup basic request
-			let options = {
-				method : 'GET',
-				uri : this.url + path,
-				json : true,
-				qs : params
+			let options: any = {
+				method : 'get',
+				url : this.url + path,
+				params : params,
+				json : true
 			};
 			};
 			
 			
 			// Basic auth for local binding
 			// Basic auth for local binding
 			if(this.type == HydrawiseConnectionType.LOCAL) {
 			if(this.type == HydrawiseConnectionType.LOCAL) {
-				let authBuffer = Buffer.from(this.localauth.user+':'+this.localauth.password);
+				let authBuffer = Buffer.from(this.localAuthUsername + ':' + this.localAuthPassword);
 				options.headers = {
 				options.headers = {
 					'Authorization': 'Basic '+ authBuffer.toString('base64')
 					'Authorization': 'Basic '+ authBuffer.toString('base64')
 				};
 				};
 			}
 			}
 			// API key auth for cloud binding
 			// API key auth for cloud binding
 			else {
 			else {
-				options.qs.api_key = this.api_key;
+				options.qs.api_key = this.cloudAuthAPIkey;
 			}
 			}
 
 
 			// Send request
 			// Send request
-			Request(options).then((data) => {
+			Axios(options).then((response: any) => {
 				
 				
 				//Check for errors
 				//Check for errors
-				if(data.messageType == 'error') {
-					reject(HydrawiseCommandException(data.message));
+				if(response.data.messageType == 'error') {
+					reject(new HydrawiseCommandException(response.data.message));
 				}
 				}
 
 
-				resolve(data);
+				resolve(response.data);
 
 
-			}).catch((err) => {
+			}).catch((err: Error) => {
 				reject(err);
 				reject(err);
 			});
 			});
 		});
 		});
@@ -103,15 +104,15 @@ class Hydrawise {
 	 * @todo Check whether controller_id needs to sent when the account contains multiple zones
 	 * @todo Check whether controller_id needs to sent when the account contains multiple zones
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	commandZone(action, zoneOrRelay, duration) {
-		let that = this;
+	public commandZone(action: string, zoneOrRelay: number | HydrawiseZone, duration?: number): Promise<any> {
+		let that:Hydrawise = this;
 
 
 		// Get started
 		// Get started
 		let promise = new Promise((resolve, reject) => {
 		let promise = new Promise((resolve, reject) => {
-			let opts = {
+			let opts: any = {
 				period_id : 998,
 				period_id : 998,
 				action: action,
 				action: action,
-			}
+			};
 
 
 			// Set Relay number for local binding
 			// Set Relay number for local binding
 			if(that.type == HydrawiseConnectionType.LOCAL) {
 			if(that.type == HydrawiseConnectionType.LOCAL) {
@@ -127,7 +128,8 @@ class Hydrawise {
 				opts.custom = duration;
 				opts.custom = duration;
 			}
 			}
 
 
-			that.setzone(opts).then(data => {
+			// Execute command
+			that.setZone(opts).then((data: any) => {
 				resolve(data);
 				resolve(data);
 			}).catch((err) => {
 			}).catch((err) => {
 				reject(err);
 				reject(err);
@@ -144,12 +146,12 @@ class Hydrawise {
 	 * @todo Check whether controller_id needs to sent when the account contains multiple zones
 	 * @todo Check whether controller_id needs to sent when the account contains multiple zones
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	commandAllZones(action, duration) {
+	public commandAllZones(action: string, duration?: number): Promise<any> {
 		let that = this;
 		let that = this;
 
 
 		// Get started
 		// Get started
 		let promise = new Promise((resolve, reject) => {
 		let promise = new Promise((resolve, reject) => {
-			let opts = {
+			let opts: any = {
 				period_id : 998,
 				period_id : 998,
 				action: action
 				action: action
 			}
 			}
@@ -159,7 +161,7 @@ class Hydrawise {
 				opts.custom = duration;
 				opts.custom = duration;
 			}
 			}
 
 
-			that.setzone(opts).then(data => {
+			that.setZone(opts).then(data => {
 				resolve(data);
 				resolve(data);
 			}).catch((err) => {
 			}).catch((err) => {
 				reject(err);
 				reject(err);
@@ -175,7 +177,7 @@ class Hydrawise {
 	 * @param {number} [duration] - How long should the command be executed
 	 * @param {number} [duration] - How long should the command be executed
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	runZone(zoneOrRelay, duration) {
+	public runZone(zoneOrRelay: number | HydrawiseZone, duration?: number): Promise<any> {
 		return this.commandZone('run', zoneOrRelay, duration);
 		return this.commandZone('run', zoneOrRelay, duration);
 	}
 	}
 
 
@@ -184,8 +186,8 @@ class Hydrawise {
 	 * @param {number} [duration] - How long should the command be executed
 	 * @param {number} [duration] - How long should the command be executed
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	runAllZones(duration) {
-		return this.commandZone('runall', duration);
+	public runAllZones(duration?: number): Promise<any> {
+		return this.commandAllZones('runall', duration);
 	}
 	}
 
 
 	/**
 	/**
@@ -194,7 +196,7 @@ class Hydrawise {
 	 * @param {number} [duration] - How long should the command be executed
 	 * @param {number} [duration] - How long should the command be executed
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	suspendZone(zoneOrRelay, duration) {
+	public suspendZone(zoneOrRelay: number | HydrawiseZone, duration?: number): Promise<any> {
 		return this.commandZone('suspend', zoneOrRelay, duration);
 		return this.commandZone('suspend', zoneOrRelay, duration);
 	}
 	}
 
 
@@ -203,8 +205,8 @@ class Hydrawise {
 	 * @param {number} [duration] - How long should the command be executed
 	 * @param {number} [duration] - How long should the command be executed
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	suspendAllZones(duration) {
-		return this.commandZone('suspendall', duration);
+	public suspendAllZones(duration?: number): Promise<any> {
+		return this.commandAllZones('suspendall', duration);
 	}
 	}
 
 
 	/**
 	/**
@@ -212,16 +214,16 @@ class Hydrawise {
 	 * @param {(HydrawiseZone|number|number)} zoneOrRelay - The zone/relay you are targetting. Can be a zone object returned by getZones, a relay number (zone.zone) for local bindings or a relayID (zone.relayID) for cloud bindings
 	 * @param {(HydrawiseZone|number|number)} zoneOrRelay - The zone/relay you are targetting. Can be a zone object returned by getZones, a relay number (zone.zone) for local bindings or a relayID (zone.relayID) for cloud bindings
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	stopZone(zoneOrRelay) {
-		return this.commandZone('stop', zoneOrRelay, duration);
+	public stopZone(zoneOrRelay: number | HydrawiseZone): Promise<any> {
+		return this.commandZone('stop', zoneOrRelay);
 	}
 	}
 
 
 	/**
 	/**
 	 * Sends the stop command to all zones/relays
 	 * Sends the stop command to all zones/relays
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	stopAllZones() {
-		return this.commandZone('stopall', duration);
+	public stopAllZones(): Promise<any> {
+		return this.commandAllZones('stopall');
 	}
 	}
 
 
 	/**
 	/**
@@ -229,24 +231,24 @@ class Hydrawise {
 	 * @param {boolean} [onlyConfigured = true] - Only return zones/relays which have been configured
 	 * @param {boolean} [onlyConfigured = true] - Only return zones/relays which have been configured
 	 * @return {Promise} A Promise which will be resolved when all zones have been retrieved
 	 * @return {Promise} A Promise which will be resolved when all zones have been retrieved
 	 */
 	 */
-	getZones(onlyConfigured = true) {
+	public getZones(onlyConfigured: boolean = true): Promise<HydrawiseZone[]> {
 		let that = this;
 		let that = this;
 	
 	
 		// Get started
 		// Get started
-		let promise = new Promise((resolve, reject) => {
+		let promise: Promise<HydrawiseZone[]> = new Promise((resolve, reject) => {
 			
 			
 			// Get relays
 			// Get relays
-			that.statusschedule().then(data => {
-				let zones = [];
+			that.getStatusAndSchedule().then((data: any) => {
+				let zones:HydrawiseZone[] = [];
 				
 				
 				// Check every returned relay
 				// Check every returned relay
-				data.relays.map(z => {
+				data.relays.map((z: any) => {
 					
 					
 					// Only configured zones
 					// Only configured zones
 					if(onlyConfigured && z.type != 110) {
 					if(onlyConfigured && z.type != 110) {
 					
 					
 						// Zone
 						// Zone
-						let zone = {
+						let zone: any = {
 							apiBinding: that,
 							apiBinding: that,
 							relayID: z.relay_id,
 							relayID: z.relay_id,
 							zone: z.relay,
 							zone: z.relay,
@@ -265,7 +267,7 @@ class Hydrawise {
 
 
 						// Running?
 						// Running?
 						if(data.running !== undefined) {
 						if(data.running !== undefined) {
-							let runningZone = data.running.find(x => {
+							let runningZone = data.running.find((x: any) => {
 								return x.relay_id == z.relay_id;
 								return x.relay_id == z.relay_id;
 							});
 							});
 							if(runningZone != undefined && runningZone != null) {
 							if(runningZone != undefined && runningZone != null) {
@@ -274,7 +276,7 @@ class Hydrawise {
 							}
 							}
 						}
 						}
 						
 						
-						zones.push(HydrawiseZone(zone));
+						zones.push(new HydrawiseZone(zone));
 					}
 					}
 				});
 				});
 
 
@@ -291,21 +293,21 @@ class Hydrawise {
 	 * Retrieves all controllers known to the Hydrawise cloud
 	 * Retrieves all controllers known to the Hydrawise cloud
 	 * @return {Promise} A Promise which will be resolved when all controllers have been retrieved
 	 * @return {Promise} A Promise which will be resolved when all controllers have been retrieved
 	 */
 	 */
-	getControllers() {
+	public getControllers(): Promise<HydrawiseController[]> {
 		let that = this;
 		let that = this;
 	
 	
 		// Get started
 		// Get started
-		let promise = new Promise((resolve, reject) => {
+		let promise: Promise<HydrawiseController[]> = new Promise((resolve, reject) => {
 			
 			
 			// Get Controllers
 			// Get Controllers
 			this.getCustomerDetails('controllers').then(data => {
 			this.getCustomerDetails('controllers').then(data => {
-				let controllers = [];
+				let controllers: HydrawiseController[] = [];
 				
 				
 				// Check every returned relay
 				// Check every returned relay
-				data.controllers.map(c => {
+				data.controllers.map((c: any) => {
 					
 					
 					// Zone
 					// Zone
-					let controller = {
+					let controller: any = {
 						id: c.controller_id,
 						id: c.controller_id,
 						name: c.name,
 						name: c.name,
 						serialNumber: c.serial_number,
 						serialNumber: c.serial_number,
@@ -313,7 +315,7 @@ class Hydrawise {
 						status: c.status
 						status: c.status
 					};
 					};
 					
 					
-					controllers.push(HydrawiseController(controller));
+					controllers.push(new HydrawiseController(controller));
 				});
 				});
 
 
 				resolve(controllers);
 				resolve(controllers);
@@ -335,15 +337,15 @@ class Hydrawise {
 	 * @param {string} type - Defines the type of customer details to be retrieved alongside the customer ID
 	 * @param {string} type - Defines the type of customer details to be retrieved alongside the customer ID
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the cloud server.
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the cloud server.
 	 */
 	 */
-	getCustomerDetails(type) {
+	public getCustomerDetails(type: string): Promise<any> {
 		// Cloud only API
 		// Cloud only API
 		if (this.type  == HydrawiseConnectionType.LOCAL) { 
 		if (this.type  == HydrawiseConnectionType.LOCAL) { 
 			return new Promise((resolve, reject) => {
 			return new Promise((resolve, reject) => {
-				reject(HydrawiseCommandException('Calling Cloud API function on a Local Binding'));
+				reject(new HydrawiseCommandException('Calling Cloud API function on a Local Binding'));
 			});
 			});
 		}
 		}
 		
 		
-		return this.#request('customerdetails.php', { type: type });
+		return this.request('customerdetails.php', { type: type });
 	}
 	}
 
 
 	/**
 	/**
@@ -352,21 +354,21 @@ class Hydrawise {
 	 * @todo Check whether controller_id needs to sent when the account contains multiple zones
 	 * @todo Check whether controller_id needs to sent when the account contains multiple zones
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
 	 */
 	 */
-	getStatusAndSchedule(tag = '', hours = '168') {
-		let uri = this.type == HydrawiseConnectionType.LOCAL ? 'get_sched_json.php' : 'statusschedule.php';
+	public getStatusAndSchedule(tag: string = '', hours: string = '168'): Promise<any> {
+		let uri = (this.type == HydrawiseConnectionType.LOCAL ? 'get_sched_json.php' : 'statusschedule.php');
 	
 	
-		return this.#request(uri, { tag, hours });
+		return this.request(uri, { tag, hours });
 	}
 	}
 
 
-	/*setController(controllerID) {
+	/*setController(controllerID: number): Promise<any> {
 		// Cloud only API
 		// Cloud only API
 		if (this.type  == HydrawiseConnectionType.LOCAL) { 
 		if (this.type  == HydrawiseConnectionType.LOCAL) { 
 			return new Promise((resolve, reject) => {
 			return new Promise((resolve, reject) => {
-				reject(HydrawiseCommandException('Calling Cloud API function on a Local Binding'));
+				reject(new HydrawiseCommandException('Calling Cloud API function on a Local Binding'));
 			});
 			});
 		}
 		}
 		
 		
-		return this.#request('setcontroller.php', { controllerID, json: true });
+		return this.request('setcontroller.php', { controllerID, json: true });
 	}*/
 	}*/
 
 
 	/**
 	/**
@@ -377,10 +379,10 @@ class Hydrawise {
 	 * @todo Check whether controller_id needs to sent when the account contains multiple zones
 	 * @todo Check whether controller_id needs to sent when the account contains multiple zones
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
 	 */
 	 */
-	setZone(params = {}) {
-		let uri = this.type == HydrawiseConnectionType.LOCAL ? 'set_manual_data.php' : 'setzone.php';
+	public setZone(this: Hydrawise, params: any = {}): Promise<any> {
+		let uri: string = (this.type == HydrawiseConnectionType.LOCAL ? 'set_manual_data.php' : 'setzone.php');
 		
 		
-		return this.#request(uri, params);
+		return this.request(uri, params);
 	}
 	}
 
 
 
 
@@ -393,7 +395,7 @@ class Hydrawise {
 	 * @alias getCustomerDetails
 	 * @alias getCustomerDetails
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the cloud server.
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the cloud server.
 	 */
 	 */
-	customerdetails(type = 'controllers') {
+	public customerdetails(type: string = 'controllers'): Promise<any> {
 		return this.getCustomerDetails(type);
 		return this.getCustomerDetails(type);
 	}
 	}
 
 
@@ -403,7 +405,7 @@ class Hydrawise {
 	 * @deprecated since version 1.0.0. Please use getZones()
 	 * @deprecated since version 1.0.0. Please use getZones()
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
 	 */
 	 */
-	statusschedule(tag = '', hours = '168') {
+	public statusschedule(tag: string = '', hours: string = '168'): Promise<any> {
 		return this.getStatusAndSchedule(tag, hours);
 		return this.getStatusAndSchedule(tag, hours);
 	}
 	}
 
 
@@ -417,11 +419,7 @@ class Hydrawise {
 	 * @deprecated since version 1.0.0. Please use runZone(), suspendZone(), stopZone(), runAllZones(), suspendAllZones(), stopAllZones() or the run(), suspend(), stop() commands on a HydrawiseZone object.
 	 * @deprecated since version 1.0.0. Please use runZone(), suspendZone(), stopZone(), runAllZones(), suspendAllZones(), stopAllZones() or the run(), suspend(), stop() commands on a HydrawiseZone object.
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
 	 * @return {Promise} A Promise which will be resolved when the request has returned from the local or cloud server.
 	 */
 	 */
-	setzone(params = {}) {
+	public setzone(params: any = {}): Promise<any> {
 		return this.setZone(params);
 		return this.setZone(params);
 	}
 	}
-}
-
-module.exports = options => {
-	return new Hydrawise(options); // { type: 'CLOUD', key: 'APIKEY' } or { type: 'LOCAL', host: 'LOCAL IP ADDRESS', user: 'USERNAME', password: 'PASSWORD' }
-};
+}

+ 6 - 8
HydrawiseCommandException.js → src/HydrawiseCommandException.ts

@@ -1,11 +1,13 @@
-'use strict';
 /**
 /**
  * @author Martijn Dierckx
  * @author Martijn Dierckx
  */
  */
 
 
 /** Class representing a specifc error triggered by the Hydrawise API binding */
 /** Class representing a specifc error triggered by the Hydrawise API binding */
-class HydrawiseCommandException extends Error {
-	constructor(message, ...params) {
+export class HydrawiseCommandException extends Error {
+	
+	public date: Date;
+
+	constructor(message: string, ...params:any) {
 		super(...params);
 		super(...params);
 
 
 		Error.captureStackTrace(this, HydrawiseCommandException);
 		Error.captureStackTrace(this, HydrawiseCommandException);
@@ -14,8 +16,4 @@ class HydrawiseCommandException extends Error {
 		this.message = message;
 		this.message = message;
 		this.date = new Date();
 		this.date = new Date();
 	}
 	}
-}
-
-module.exports = (message, ...params) => {
-	return new HydrawiseCommandException(message, ...params);
-};
+}

+ 9 - 0
src/HydrawiseConnectionType.ts

@@ -0,0 +1,9 @@
+/**
+ * Enumeration for the different types of Hydrawise API bindings: Cloud or Local
+ * @readonly
+ * @enum {string}
+ */
+export enum HydrawiseConnectionType {
+	LOCAL = 'LOCAL',
+	CLOUD = 'CLOUD'
+}

+ 30 - 0
src/HydrawiseController.ts

@@ -0,0 +1,30 @@
+/**
+ * @author Martijn Dierckx
+ */
+
+/** Class representing a Hydrawise controller */
+export class HydrawiseController {
+
+	public id: number;
+	public name: string;
+	public serialNumber: string;
+	public lastContactWithCloud: Date;
+	public status: string;
+
+	/**
+	 * Create a new instance of a HydrawiseController
+	 * @param {object} options - Options object containing all parameters
+	 * @param {number} options.id - The unique identifier of the controller
+	 * @param {string} options.name - The name of the controller
+	 * @param {string} options.serialNumber - The serial number of the controller
+	 * @param {Date} options.lastContactWithCloud - The last date time the controller was able to contact/sync with the cloud
+	 * @param {string} options.status - The status as returned by the Hydrawise cloud
+	 */
+	constructor(options: any) {
+		this.id = options.id;
+		this.name = options.name;
+		this.serialNumber = options.serialNumber;
+		this.lastContactWithCloud = options.lastContactWithCloud;
+		this.status = options.status;
+	}
+}

+ 18 - 11
HydrawiseZone.js → src/HydrawiseZone.ts

@@ -1,10 +1,21 @@
-'use strict';
 /**
 /**
  * @author Martijn Dierckx
  * @author Martijn Dierckx
  */
  */
 
 
+import { Hydrawise } from "./Hydrawise";
+
 /** Class representing a Hydrawise zone */
 /** Class representing a Hydrawise zone */
-class HydrawiseZone {
+export class HydrawiseZone {
+
+	public apiBinding: Hydrawise;
+	public relayID: number;
+	public zone: number;
+	public name: string;
+	public nextRunAt: Date;
+	public nextRunDuration: number;
+	public isSuspended: boolean;
+	public isRunning: boolean;
+	public remainingRunningTime: number;
 
 
 	/**
 	/**
 	 * Create a new instance of a HydrawiseZone
 	 * Create a new instance of a HydrawiseZone
@@ -19,7 +30,7 @@ class HydrawiseZone {
 	 * @param {boolean} options.isRunning - Returns true when the zone is actively running
 	 * @param {boolean} options.isRunning - Returns true when the zone is actively running
 	 * @param {number} options.remainingRunningTime - Remaining run time in seconds when isRunning = true
 	 * @param {number} options.remainingRunningTime - Remaining run time in seconds when isRunning = true
 	 */
 	 */
-	constructor(options) {
+	constructor(options: any) {
 		this.apiBinding = options.apiBinding;
 		this.apiBinding = options.apiBinding;
 		this.relayID = options.relayID;
 		this.relayID = options.relayID;
 		this.zone = options.zone;
 		this.zone = options.zone;
@@ -36,7 +47,7 @@ class HydrawiseZone {
 	 * @param {number} [duration] - How long should the command be executed
 	 * @param {number} [duration] - How long should the command be executed
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	run(duration) {
+	run(duration: number): Promise<any> {
 		return this.apiBinding.commandZone('run', this, duration);
 		return this.apiBinding.commandZone('run', this, duration);
 	}
 	}
 
 
@@ -44,7 +55,7 @@ class HydrawiseZone {
 	 * Sends the stop command to the zone/relay
 	 * Sends the stop command to the zone/relay
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	stop() {
+	stop(): Promise<any> {
 		return this.apiBinding.commandZone('stop', this);
 		return this.apiBinding.commandZone('stop', this);
 	}
 	}
 
 
@@ -53,11 +64,7 @@ class HydrawiseZone {
 	 * @param {number} [duration] - How long should the command be executed
 	 * @param {number} [duration] - How long should the command be executed
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 * @return {Promise} A Promise which will be resolved when the command has been executed.
 	 */
 	 */
-	suspend(duration) {
+	suspend(duration: number): Promise<any> {
 		return this.apiBinding.commandZone('suspend', this, duration);
 		return this.apiBinding.commandZone('suspend', this, duration);
 	}
 	}
-}
-
-module.exports = options => {
-	return new HydrawiseZone(options);
-};
+}

+ 49 - 0
test/test.js

@@ -0,0 +1,49 @@
+const Hydrawise = require('../dist/Hydrawise').Hydrawise;
+
+const hydrawise = new Hydrawise({ type: 'LOCAL', host: process.argv[2], password: process.argv[3] });
+//const hydrawise = new Hydrawise({ type: 'CLOUD', key: process.argv[2] });
+
+/* Get all zones -> run first zone -> get all zones -> stop first zone -> get all zones */
+hydrawise.getZones().then(function(data) {
+  console.log(data);
+  setTimeout(() => {
+
+    data[0].run().then(function(data) {
+      console.log(data);
+      setTimeout(() => {
+        
+        hydrawise.getZones().then(function(data) {
+          console.log(data);
+          setTimeout(() => {
+        
+            data[0].stop().then(function(data) {
+              console.log(data);
+              setTimeout(() => {
+        
+                hydrawise.getZones().then(function(data) {
+                  console.log(data);
+        
+                  
+                }).catch((err) => {
+                  console.log(err);
+                });
+        
+              }, 2000);
+            }).catch((err) => {
+              console.log(err);
+            });
+    
+          }, 2000);
+        }).catch((err) => {
+          console.log(err);
+        });
+
+      }, 2000);
+    }).catch((err) => {
+      console.log(err);
+    });
+
+  }, 2000);
+}).catch((err) => {
+	console.log(err);
+});

+ 69 - 0
tsconfig.json

@@ -0,0 +1,69 @@
+{
+  "include": [
+    "./src/**/*"
+  ],
+  "compilerOptions": {
+    /* Basic Options */
+    // "incremental": true,                   /* Enable incremental compilation */
+    "target": "ES2018",                       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
+    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
+    // "lib": [],                             /* Specify library files to be included in the compilation. */
+    // "allowJs": true,                       /* Allow javascript files to be compiled. */
+    // "checkJs": true,                       /* Report errors in .js files. */
+    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
+    "declaration": true,                      /* Generates corresponding '.d.ts' file. */
+    "declarationMap": true,                   /* Generates a sourcemap for each corresponding '.d.ts' file. */
+    "sourceMap": true,                        /* Generates corresponding '.map' file. */
+    // "outFile": "./",                       /* Concatenate and emit output to single file. */
+    "outDir": "./dist",                       /* Redirect output structure to the directory. */
+    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
+    // "composite": true,                     /* Enable project compilation */
+    // "tsBuildInfoFile": "./",               /* Specify file to store incremental compilation information */
+    // "removeComments": true,                /* Do not emit comments to output. */
+    // "noEmit": true,                        /* Do not emit outputs. */
+    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
+    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
+    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
+
+    /* Strict Type-Checking Options */
+    "strict": true,                           /* Enable all strict type-checking options. */
+    "noImplicitAny": true,                    /* Raise error on expressions and declarations with an implied 'any' type. */
+    // "strictNullChecks": true,              /* Enable strict null checks. */
+    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
+    // "strictBindCallApply": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
+    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
+    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
+    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */
+
+    /* Additional Checks */
+    // "noUnusedLocals": true,                /* Report errors on unused locals. */
+    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
+    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
+    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */
+
+    /* Module Resolution Options */
+    "moduleResolution": "node",               /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
+    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
+    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
+    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
+    // "typeRoots": [],                       /* List of folders to include type definitions from. */
+    // "types": [],                           /* Type declaration files to be included in compilation. */
+    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
+    "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
+    // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */
+    // "allowUmdGlobalAccess": true,          /* Allow accessing UMD globals from modules. */
+
+    /* Source Map Options */
+    // "sourceRoot": "",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */
+    // "mapRoot": "",                         /* Specify the location where debugger should locate map files instead of generated locations. */
+    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
+    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
+
+    /* Experimental Options */
+    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
+    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
+
+    /* Advanced Options */
+    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
+  }
+}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно