Bladeren bron

v1.0.0: Rewrite + Added local API binding

Martijn Dierckx 5 jaren geleden
bovenliggende
commit
de326a8b2b
11 gewijzigde bestanden met toevoegingen van 986 en 172 verwijderingen
  1. 0 12
      .editorconfig
  2. 0 1
      .npmignore
  3. 0 3
      .travis.yml
  4. 21 0
      HydrawiseCommandException.js
  5. 25 0
      HydrawiseController.js
  6. 63 0
      HydrawiseZone.js
  7. 70 40
      README.md
  8. 421 37
      index.js
  9. 373 0
      package-lock.json
  10. 13 24
      package.json
  11. 0 55
      test/index.js

+ 0 - 12
.editorconfig

@@ -1,12 +0,0 @@
-root = true
-
-[*]
-indent_style = space
-indent_size = 2
-end_of_line = lf
-charset = utf-8
-trim_trailing_whitespace = true
-insert_final_newline = true
-
-[.md]
-insert_final_newline = false

+ 0 - 1
.npmignore

@@ -1 +0,0 @@
-src

+ 0 - 3
.travis.yml

@@ -1,3 +0,0 @@
-language: node_js
-node_js:
-  - 'node'

+ 21 - 0
HydrawiseCommandException.js

@@ -0,0 +1,21 @@
+'use strict';
+/**
+ * @author Martijn Dierckx
+ */
+
+/** 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();
+	}
+}
+
+module.exports = (message, ...params) => {
+	return new HydrawiseCommandException(message, ...params);
+};

+ 25 - 0
HydrawiseController.js

@@ -0,0 +1,25 @@
+'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);
+};

+ 63 - 0
HydrawiseZone.js

@@ -0,0 +1,63 @@
+'use strict';
+/**
+ * @author Martijn Dierckx
+ */
+
+/** 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);
+	}
+}
+
+module.exports = options => {
+	return new HydrawiseZone(options);
+};

+ 70 - 40
README.md

@@ -2,78 +2,108 @@
 
 [![Build Status](https://travis-ci.org/paulmolluzzo/hydrawise-api.svg?branch=master)](https://travis-ci.org/paulmolluzzo/hydrawise-api)
 
-This is a client for the [Hydrawise API](https://hydrawise.com/support/using-api/). [Hydrawise](https://hydrawise.com) is an internet-controlled home irrigation system.
+This is a client for the [Hydrawise API](https://support.hydrawise.com/hc/en-us/articles/360008965753-Hydrawise-API-Information). [Hydrawise](https://hydrawise.com) is an internet-controlled home irrigation system.
 
-It provides access to the following endpoints:
-* [Customer Details](#customer-details)
-* [Status Schedule](#status-schedule)
-* [Set Controller](#set-controller)
-* [Set Zone](#set-zone)
+On a very basic level, it allows you to do:
+* [Get zones](#get-zones)
+* [Run a command on a zone](#run-a-command-on-a-zone) (run/stop/suspend)
+* [Command all zones at once](#command-all-zones-at-once)
 
-## Usage
+For all possibilities, have a look at the inline code documentation
 
-### Initial Setup
+## Getting started
+
+When possible use a local connection to your controller since it's not rate limited (HTTP error 429) and suffers no delays when trying to run commands on zones.
+
+### Setup for a cloud connection
 
 ```js
 const Hydrawise = require('hydrawise-api');
-const myHydrawise = Hydrawise(YOUR_API_KEY);
+const myHydrawise = Hydrawise({ type:'CLOUD', key:'YOUR_API_KEY' });
 ```
 
-### Customer Details
+You can obtain your API key from the "Account Details" screen on the [Hydrawise platform](https://app.hydrawise.com/config/account/details)
 
-Get cusetomer info.
+### Setup for a local connection
 
 ```js
-myHydrawise.customerdetails()
-  .then(data => console.log(data))
-  .catch(error => console.log(error));
+const Hydrawise = require('hydrawise-api');
+const myHydrawise = Hydrawise({ type:'LOCAL', host:'HOSTNAME_OR_IP_ADDRESS', password:'YOUR_CONTROLLER_PASSWORD' });
 ```
 
-### Status Schedule
+You can also provide a *user* parameter, but this should be 'admin' in most cases.
+
+## Basic usage
 
-Get the status of a controller. You can pass the param `hydrawise_all` or a specific tag or leave empty for the current controller. The second parameter is how far in advance (in hours) you want to get the schedule, and it will default to the maximum of 168.
+### Get Zones
+
+Get all zones and see their status.
 
 ```js
-myHydrawise.statusschedule()
-  .then(data => console.log(data))
+myHydrawise.getZones()
+  .then(zones => console.log(zones))
   .catch(error => console.log(error));
 ```
 
-### Set Controller
+This will return an array of HydrawiseZone objects containing the following info:
+
+```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
+`{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
+```
+
+By default only the active zones are returned, you can change this behaviour by calling getZones(false) instead.
 
-Set a controller for controller-specific commands.
+### Run a command on a zone
 
-**_Note: This endpoint seems to not respond with any data, so a non-error is a "pass" I guess?_**
+You can execute a couple of basic commands on each zone: `run()`, `suspend()` or `stop()`
 
 ```js
-myHydrawise.setcontroller(controller_id)
-  .then()
-  .catch(error => console.log(error));
+myHydrawise.getZones()
+  .then(zones => {
+    zone[0].run().then((info) => {
+      console.log('success');
+    }).catch(error => console.log(error));
+  }).catch(error => console.log(error));
 ```
 
-### Set Zone
+For the run & suspend commands you are able to provide a custom duration in seconds: `run(600)` (for 10 mins).
+If no custom duration was provided, the default run time configured for the zone will be used. 
 
-This is how you set a zone to run, suspend, or stop. The params are an action and additional params `period_id`, `custom` for a duration in seconds, and `relay_id` for a specific zone.
+Zones can also be commanded directly from the Hydrawise object:
 
 ```js
-// run all for 10 minutes
-myHydrawise.setzone('runall', {period_id: '666', custom: '600'})
-  .then(data => console.log(data))
-  .catch(error => console.log(error));
+`myHydrawise.runZone(1)` - Run by local zone number (only. for local bindings)
+`myHydrawise.runZone(123123)` - Run by unique relay ID (only. for cloud bindings)
+`myHydrawise.runZone(myHydrawiseZoneObject)` - Run by the HydrawiseZone object returned by `getZones()`
+```
 
-// stop all
-myHydrawise.setzone('stopall')
-  .then(data => console.log(data))
-  .catch(error => console.log(error));
+### Command all zones at once
 
-// run zone for 5 minutes
-myHydrawise.setzone('run', {period_id: '123', custom: '300', relay_id: your_relay_id})
-  .then(data => console.log(data))
-  .catch(error => console.log(error));
+It's also possible to command all zones at the same time:
+
+```js
+myHydrawise.runAllZones()
+  .then(info => {
+     console.log('success');
+  }).catch(error => console.log(error));
 ```
 
+Here as well, you are able to provide a custom duration: `runAllZones(600)` (for 10 mins).
+
 ------
 
-MIT
+## Contributors
+
+* Martijn Dierckx - Complete rewrite to service both the cloud & local API 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 :-)
 
-©2016 Paul Molluzzo
+MIT license

+ 421 - 37
index.js

@@ -1,43 +1,427 @@
 'use strict';
+/**
+ * @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
+ */
 
-const rp = require('request-promise');
+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';
+}
+
+/** Class representing a Hydrawise local or cloud based API binding */
 class Hydrawise {
-  constructor(key) {
-    this.url = 'https://hydrawise.com/api/v1/';
-    this.api_key = key;
-  }
-
-  request(method = 'GET', url = '', params = {}) {
-    const options = {
-      method,
-      uri: `${this.url}${url}.php`,
-      json: true
-    };
-
-    options.qs = params;
-    options.qs.api_key = this.api_key;
-    return rp(options);
-  }
-
-  customerdetails() {
-    return this.request('GET', 'customerdetails', {type: 'controllers'});
-  }
-
-  statusschedule(tag = '', hours = '168') {
-    return this.request('GET', 'statusschedule', {tag, hours});
-  }
-
-  setcontroller(controllerid) {
-    return this.request('GET', 'setcontroller', {controllerid, json: true});
-  }
-
-  setzone(action, params = {}) {
-    params.action = action;
-    return this.request('GET', 'setzone', params);
-  }
+	
+	#cloudUrl = 'https://app.hydrawise.com/api/v1/';
+	
+	/**
+	 * 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.type = options.type || HydrawiseConnectionType.CLOUD; // CLOUD or LOCAL 
+		this.url = options.host ? 'http://'+options.host+'/' : this.#cloudUrl;
+		
+		// Local Auth
+		this.localauth = {
+			user: options.user || 'admin',
+			password: options.password
+		}
+
+		// Cloud Auth
+		this.api_key = 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',
+				uri : this.url + path,
+				json : true,
+				qs : params
+			};
+			
+			// Basic auth for local binding
+			if(this.type == HydrawiseConnectionType.LOCAL) {
+				let authBuffer = Buffer.from(this.localauth.user+':'+this.localauth.password);
+				options.headers = {
+					'Authorization': 'Basic '+ authBuffer.toString('base64')
+				};
+			}
+			// API key auth for cloud binding
+			else {
+				options.qs.api_key = this.api_key;
+			}
+
+			// Send request
+			Request(options).then((data) => {
+				
+				//Check for errors
+				if(data.messageType == 'error') {
+					reject(HydrawiseCommandException(data.message));
+				}
+
+				resolve(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.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;
+			}
+
+			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.commandZone('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.commandZone('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, duration);
+	}
+
+	/**
+	 * 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.commandZone('stopall', duration);
+	}
+
+	/**
+	 * 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.statusschedule().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.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(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(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.LOCAL) { 
+			return new Promise((resolve, reject) => {
+				reject(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.LOCAL ? 'get_sched_json.php' : 'statusschedule.php';
+	
+		return this.#request(uri, { tag, hours });
+	}
+
+	/*setController(controllerID) {
+		// Cloud only API
+		if (this.type  == HydrawiseConnectionType.LOCAL) { 
+			return new Promise((resolve, reject) => {
+				reject(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.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);
+	}
 }
 
-module.exports = apiKey => {
-  return new Hydrawise(apiKey);
-};
+module.exports = options => {
+	return new Hydrawise(options); // { type: 'CLOUD', key: 'APIKEY' } or { type: 'LOCAL', host: 'LOCAL IP ADDRESS', user: 'USERNAME', password: 'PASSWORD' }
+};

+ 373 - 0
package-lock.json

@@ -0,0 +1,373 @@
+{
+  "name": "hydrawise-api",
+  "version": "0.2.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "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="
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "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": {
+      "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"
+      }
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+    },
+    "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==",
+      "requires": {
+        "ajv": "^6.5.5",
+        "har-schema": "^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=",
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "is-typedarray": {
+      "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=="
+    },
+    "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==",
+      "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"
+      }
+    },
+    "request-promise": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz",
+      "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==",
+      "requires": {
+        "bluebird": "^3.5.0",
+        "request-promise-core": "1.1.3",
+        "stealthy-require": "^1.1.1",
+        "tough-cookie": "^2.3.3"
+      }
+    },
+    "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=="
+    },
+    "sshpk": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+      "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"
+      }
+    },
+    "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"
+      }
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+    },
+    "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==",
+      "requires": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+    },
+    "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"
+      }
+    }
+  }
+}

+ 13 - 24
package.json

@@ -1,42 +1,31 @@
 {
   "name": "hydrawise-api",
-  "version": "0.1.0",
-  "description": "Library for accessing the Hydrawise API",
+  "version": "1.0.0",
+  "description": "Library for accessing the Hydrawise API via the cloud or directly on the local network",
   "repository": {
     "type": "git",
     "url": "https://github.com/paulmolluzzo/hydrawise-api.git"
   },
   "main": "index.js",
-  "scripts": {
-    "test": "xo && ava"
-  },
   "keywords": [
     "hydrawise",
     "api",
-    "iot"
+    "iot",
+    "sprinklers",
+    "hunter",
+    "hunter industries"
+  ],
+  "contributors": [
+    "Martijn Dierckx",
+    "Paul Molluzzo (https://paul.molluzzo.com)"
   ],
-  "author": "Paul Molluzzo (https://paul.molluzzo.com)",
   "license": "MIT",
-  "devDependencies": {
-    "ava": "^0.14.0",
-    "xo": "^0.15.0"
-  },
-  "xo": {
-    "esnext": true,
-    "envs": [
-      "browser"
-    ],
-    "rules": {
-      "new-cap": 0,
-      "camelcase": [0, {"properties": "always"}]
-    },
-    "space": true
-  },
   "engines": {
     "node": ">=6.0.0",
-    "npm": "3.8.0"
+    "npm": ">=3.8.0"
   },
   "dependencies": {
-    "request-promise": "^3.0.0"
+    "request": "^2.88.2",
+    "request-promise": "^4.2.5"
   }
 }

+ 0 - 55
test/index.js

@@ -1,55 +0,0 @@
-const test = require('ava');
-const hydrawise = require('../index');
-
-const h = hydrawise('53DC-7E24-07E8-CD7D');
-
-test('Customer Details', t => {
-  return h.customerdetails().then(data => {
-    if (data.error_msg) {
-      t.fail(`Error: ${data.error_msg}`);
-    }
-    t.pass();
-  });
-});
-
-test('Status Schedule', t => {
-  return h.statusschedule().then(data => {
-    if (data.error_msg) {
-      t.fail(`Error: ${data.error_msg}`);
-    }
-    t.pass();
-  });
-});
-
-test('Status Schedule All', t => {
-  return h.statusschedule('hydrawise_all').then(data => {
-    if (data.error_msg) {
-      t.fail(`Error: ${data.error_msg}`);
-    }
-    t.pass();
-  });
-});
-
-test('Set Controller', t => {
-  return h.setcontroller('11774').then(() => {
-    t.pass();
-  });
-});
-
-test('Stop Zones', t => {
-  return h.setzone('stopall').then(data => {
-    if (data.message_type === 'error') {
-      t.fail(`Error: ${data.message}`);
-    }
-    t.pass();
-  });
-});
-
-test('Run All Zones', t => {
-  return h.setzone('runall', {period_id: '999', custom: '60'}).then(data => {
-    if (data.message_type === 'error') {
-      t.fail(`Error: ${data.message}`);
-    }
-    t.pass();
-  });
-});