Hub Configuration API

This API can be optionally implemented on a server. (You don't need to implement it, if you just want to send data to the server.) You can not directly update a hub's settings, because they are sleeping most of the time. Instead you can indirectly update a hubs settings, using this server API. The server keeps a copy of the hubs settings, and when the hub logs in it will synchronize it's settings to the server, or update the server if its settings have changed, based hub configuration timestamps.

Jason Config Update API Version 1.0 (Current Version)

When the VegeHub contacts its reporting server, it sends all of its sensor readings, and checks the server's reply for JSON data. If the field "who_updated" is present in the JSON data of the server's reply, the HUB checks that field for a number from 0-2 to determine whether it should check for new configuration data.

Values for the who_updated field:

  • 0: The server is indicating that it has no record of this Hub (based on its MAC address) and that the Hub should send a full dump of all of its stored settings.
  • 1: Indicates that the server has settings stored for this Hub, and that they were last updated by the Hub itself. The Hub will only proceed with exchange of config information if it has new settings to send to the server.
  • 2: Indicates that the server has settings stored for this Hub, and that they were last updated on the server side. The Hub will now proceed to an exchange of config information.

Hub Request

If the Hub is proceeding with an exchange of config information, it will now request the individual pieces of the config from the server. It will send its MAC address, its API key, and an empty JSON object to indicate which piece of the config it is requesting. The JSON data will look something like this:

        
            {"mac": "ABCD1234","api_key": "qwertyuiop", "sensors":[]}
        
    

The empty "sensors" array indicates that the Hub wants the settings for the sensors. The possible objects the Hub may request are:

  • "hub":{} - The hub is requesting the general settings for the hub. The server will reply with an object.
  • "actuators":[] - Requesting an array of all actuator objects associated with this Hub. The server will reply with an array of objects.
  • "sensors":[] - Requesting an array of all sensor objects associated with this Hub. The server will reply with an array of objects.
  • "schedule_overrides":[] - Requesting an array of all schedule override objects associated with this Hub. The server will reply with an array of objects.

Once the Hub has sent a request for a specific part of the config, it will then wait for the reply from the server. The server's reply will be JSON data formatted as follows:

            
                {"mac": "ABCD1234","api_key": "qwertyuiop", "updated": 1977-05-25T12:00:00Z, "sensors":[...an array of sensor objects...]}
            
        
The Hub will check the provided API key against its own to make sure that this data was intended for it.

Timestamp Check

The hub will now do a timestamp check to see who has the more up-to-date settings. This is necessary in case settings have been changed on both the hub and the server before they've had a chance to synchronize. The Hub will take the settings of whichever source was changed more recently. It uses the "updated" field to get the server's timestamp. The timestamp is based on the UTC, and is in standard Javascript Datetime string formatting.

If the Hub determines that the server has the most recent settings for this piece of the config, it will proceed to processing the JSON object provided. The formatting for the individual objects is documented below in the Extended JSON structure. Note that the full structure should never be sent all at once, as the Hub's receive buffer is too small and it will be unable to process the data.

Once the Hub is done processing an object or array of objects that it has requested, it will request the next object or array of objects that it intends to check.

Wrapping Up

Once the Hub is done processing all objects that it requested, it will do a full dump of all of its settings to the server.

Whenever the server gets a settings dump, it should look for the "updated" field coming from the Hub and use the date provided as its new stored timestamp. Now when the Hub sends an update, the server should reply with a 1 in the "who_updated" field to indicate that its settings have come from the Hub.

If settings are changed on the server side, it should change its stored timestamp to indicate the current UTC time when the settings were changed, so that the next time the Hub checks in, the server's timestamp will reflect when changes were made to it. Whenever changes are made to the settings on the server side, the server should then reply with a 2 in the "who_updated" field when it gets updates from the Hub.




	{
		// Send these fields for the request
		"api_key": api_key_str[16],
		"mac": mac_address_str[16],
		"route_key": route_key_str[16],
		// When querying object arrays, create an empty object or array for each item you want filled. 
		// for example "hub":{}, "slots":[] would get the hub object and the slots array.  
		// The server will return the requested objects as the following json objects. 
		// The following request will get all fields: {"api_key": "XXXX","mac": "XXXX","hub":{},"slots":[],"actuators":[],"schedules":[]}
		"updated": updated_timedate_str,  // time of last configuration update to server db.  
		"who_updated": who_updated_int,   // 0: needs updating by hub, 1: hub did last update, 2: web interface did last update.
		"hub": {
			"model": model_str[32], // "VG-HUB1","VG-HUB4","VG-HUB4-RELAY,"VG-SPRINKLER4","VG-SPRINKLER4-LATCH"
			"firmware_version": firmware_version_str,
			"wifi_version": wifi_version_str,
			"utc_offset": utc_offset_int // in seconds. 
			"name": name_str[32], // name of hub
			"sample_period": sample_period_int, // in seconds  (optional)
			"update_period": update_period_int, // in seconds
			"blink_update": blink_update_int, // 0: don't blink, 1: blink
			"report_voltage": report_voltage_int, // 0: don't report, 1: report voltage
			"server_url": server_url_str,
			"static_ip_addr": static_ip_addr,
			"dns": dns,
			"subnet": subnet,
			"gateway": gateway,
			"current_ip_addr": current_ip_addr,	 // the currently assigned IP Address. Only the Hub can set or write this. 
			"power_mode": power_mode_int 	// Hub is connected to- 0: battery power, 1: wall power. 
		},
		"sensors": [ // sensor input channels 
			{
				"slot": slot_int,  // 0 based.
				"mode": mode_int, // 1: sensor, 0: edge
				"warm_up": warm_up_float,	// in seconds.
				"pull_up": pull_up_int,	// 0: no pull up, 1: use pull up.
				"always_power": always_power_int, // 0: power to sensor not always on, 1: always on.
				"update_on_trigger": update_on_trigger_int,  // 0: don't update, 1: update on trigger.
				"edge": edge_int,		// 0: raising, 1: falling, 2: both. 
			},
		],
		"actuators": [ // relays, valves, pumps, etc.
			{
				"name": name_str[32], 
				"slot": slot_int, // 0 based index of the physical actuator on the board. 
				"type": type_int, 0: undefined, 1: relay, 2: valve, 3: pump. 
				"enabled": enable_int, // 0: disabled, 1: enabled.
				"mode": mode_int, // 0: sensor conditional, 1: web conditional, 2: non-conditional (manual), 3: auto-generated web conditional.
				"url": url_str[256],
				"url_param": url_param_str[256],
				"turn_on": turn_on_int, // 0: OFF, 1: ON
				"time_dependent": time_dependent_int, // 0: not dependent, 1: dependent (optional)
				"start_time": start_time_str, (optional)
				"end_time": end_time_str, (optional)
				"days_of_week": days_of_week_mask_int, // 0: never, 1: sun, 2: mon, 4: tue, etc.  127 every day. (optional)
				"conditions": [
					{
						"sequence": sequence_int, // operand order. 0 based. 
						"slot": slot_int,	// sensor channel slot 
						"operator": operator_int, // 0: greater than, 1: less than, 2: inside, 3: outside, 4: true, 5: false
						"lower": lower_float,
						"upper": upper_float,
						"hysteresis": hysteresis_float,
						"chain": chain_int  // 0: none, 1: AND, 2: OR
					}
				]
			},
		],
		"schedules": [
			{
				"name": name_str[32], 
				"idx": idx_int, // 0 based. index of the schedule 
				"enabled": enabled_bool, // 0: disabled, 1: enabled.
				"mode": mode_int, // 0: calendar, 1: periodic.
				"days_of_week": days_of_week_mask_int, // 0: never, 1: sun, 2: mon, 4: tue, etc.  127 every day. 
				"period": period_int, // time between starts.
				"start_time": start_time_str,
				"actions": [
					{
						"enabled": enabled_bool, // 0: disabled, 1: enabled.
						"actuator_slot": actuator_slot_int, // index of the physical actuator on the board. 
						"duration": duration_int, // on time of actuator in minutes
					}
				]
			}
		],
		"web_conditions": [ // length could be less than the number of actuators. 
			{
				"actuator_slot": slot_int, // 0 based indicates the actuator it is tied to. 
				"name": name_str[32], 
				"condition_key": condition_key_str[16], // 0 based. index of the schedule 
			}
		],
		"schedule_overrides":[
			{
				"id": id_int,						// unique identifier
				"start_time": start_time_str,		// override start time. The zero time of "0000-00-00 00:00:00" means immediate.
				"duration": duration _int,			// (seconds) how long to run actuator
				"actuator_slot": actuator_slot_int, // 0 based index of the actuator. 
				"action_type": action_type_int 		// 1: on, 2: off, 3: cancel. 
			}
		]
	}

Jason Config Update API Version 0.1 Deprecated

This API version pertains to only the following hubs: VG-HUB1, VG-HUB4, and VG-HUB4-RELAY, with Hub Firmware Version 3.0.0


	{
		// Send these fields for the request
		// The following request will get all fields: {"api_key": "XXXX","mac": "XXXX"}
		"api_key": api_key_str[16],
		"mac": mac_address_str[16],
		// The response sends back these fields:
		"firmware_version": firmware_version_str,
		"wifi_version": wifi_version_str,
		"utc_offset": utc_offset_int // in seconds. 
		"hub_name": hub_name_str[32], // name of hub
		"sample_period": sample_period_int, // in seconds
		"update_period": update_period_int, // in seconds
		"blink_update": blink_update_int, // 0: don't blink, 1: blink
		"report_voltage": report_voltage_int, // 0: don't report, 1: report voltage
		"server_url": server_url_str,		
		"updated": updated_timedate_str,  // time of last configuration update to server db.  
		"who_updated": who_updated_int,   // 0: needs updating by hub, 1: hub did last update, 2: web interface did last update.
		"static_ip_addr": static_ip_addr,
		"dns": dns,
		"subnet": subnet,
		"gateway": gateway,
		"slots": [ // sensor input channels 
			{
				"slot": slot_int,  // 0 based.
				"mode": mode_int, // 1: sensor, 0: edge
				"warm_up": warm_up_float,	// in seconds.
				"pull_up": pull_up_int,	// 0: no pull up, 1: use pull up.
				"always_power": always_power_int, // 0: power to sensor not always on, 1: always on.
				"update_on_trigger": update_on_trigger_int,  // 0: don't update, 1: update on trigger.
				"edge": edge_int,		// 0: raising, 1: falling, 2: both. 
			}
		],
		"relays": [
			{
				"relay": relay_int, // index of the physical actuator on the board. 
				"enabled": enable_int, // 0: disabled, 1: enabled.
				"mode": mode_int, // 0: sensor, 1: web, 2: manual.
				"url": url_str[256],
				"param": param_str[256],
				"turn_on": turn_on_int, // 0: OFF, 1: ON
				"time_dependent": time_dependent_int, // 0: not dependent, 1: dependent
				"start_time": start_time_str, 
				"end_time": end_time_str, 
				"days_of_week": days_of_week_mask_int, // 0: never, 1: sun, 2: mon, 4: tue, etc.  127 every day. 
				"conditions": [
					{
						"sequence": sequence_int, // operand order. 0 based.
						"slot": slot_int,	// sensor channel slot
						"operator": operator_int, // 0: greater than, 1: less than, 2: inside, 3: outside, 4: true, 5: false
						"lower": lower_float,
						"upper": upper_float,
						"hysteresis": hysteresis_float,
						"chain": chain_int  // 0: none, 1: AND, 2: OR
					}
				]
			}
		]
	}