Index: include.js
===================================================================
--- include.js	(revision 18b334175a50d4277e8b097d135fa82f13bc86ea)
+++ include.js	(revision 8971868f8273c59683e92cd79c747691e784ebd0)
@@ -1,5 +1,8 @@
 var orgs;
+var nets;
 var number_of_orgs;
+var number_of_nets;
 var orgs_completed=0;
+var nets_completed=0;
 var current_org=-1;
 var key="";
@@ -387,4 +390,173 @@
 }
 
+
+//GET INVENTORY
+
+function get_inv_orgs() {
+	
+	status_update("Fetching organisations...");
+	$(".meraki_form").hide();
+	set_key();
+	get_organisations(on_get_organisations_success_inventory, on_get_organisations_error);	
+}
+
+function on_get_organisations_success_inventory(data) {
+	status_update('Sorting and generating output...');
+
+	orgs = data;
+	sorted = orgs.sort(function(a, b) { return (a.name < b.name)?-1:((b.name < a.name)?1:0); });
+	
+	
+	$('#meraki_orgs_output').html('<select id="meraki_org" name="meraki_org"></select>');
+	
+	$.each ( orgs, function (j) {
+		$('#meraki_org').append('<option value="'+this.id+'">'+this.name+'</option>');
+	});
+	
+	$('#meraki_orgs_output').append('\
+		<div class="meraki_row">\
+			<input type="button" class="meraki_button" name="meraki_go" id="meraki_go" value="Get Inventory" onclick="get_inventory();">\
+		</div>\
+	');
+	status_update('Waiting for user input...');
+}
+
+function get_inventory() {
+	status_update("Fetching networks...");
+	$('#meraki_orgs_output').hide();
+	var orgid=$('#meraki_org').val();
+	$.ajax({
+		dataType: "json",
+		url: "api.php",
+		method: "post",
+		data: {
+			action:	"get_org_networks",
+			orgid:	orgid,
+			key:	key
+		},
+		success: function (r) {on_get_network_success(r, orgid);},
+		error: function (x, s, e) {on_get_network_error(e, orgid);}
+	});
+}
+
+function on_get_network_success(r, orgid) {
+	nets = r;
+	number_of_nets = nets.length;
+	status_update("Found " + number_of_nets + " networks - fetching device details...");
+	
+    $.each(r, function(network) {
+        $.ajax({
+            dataType: "json",
+            url: "api.php",
+			method: "post",
+			data: {
+				action:	"get_network_devices",
+				orgid:	orgid,
+				networkid: this.id,
+				key:	key
+			},
+            success: function (r) {on_get_devices_success(r, network);},
+            error: function (x, s, e) {on_get_devices_error(e, network);}
+        });
+	});
+}
+
+function on_get_devices_success(devices, net_index) {
+	nets[net_index].devices = devices;
+	nets_completed++;
+    if(check_nets_complete()) {
+        print_inventory_output();
+	}
+}
+
+function on_get_network_error(e, net_index) {
+	status_update("Error fetching networks: " + e);
+}
+
+function on_get_devices_error(e, net_index) {
+	status_update("Error fetching devices: " + e);
+	nets[net_index].devices = ["ERROR"];
+	nets_completed++;
+    if(check_nets_complete()) {
+        print_inventory_output();
+    }
+}
+
+function  print_inventory_output() {
+	status_update('Sorting and generating output...');
+	
+	var csv="Network Name,Network Type,Device Name,Device Serial,Device Model,Device IP,Device MAC\r\n";
+	
+	sorted = nets; //.sort(function(a, b) { return a.name - b.name; });
+	$("#meraki_inventory_output").html('\
+		<table class="meraki_output_table" id="meraki_inventory_output_table">\
+			<tr>\
+				<td class="meraki_output_header_group"><b>Network Name</b></td>\
+				<td class="meraki_output_header_group"><b>Network Type</b></td>\
+				<td class="meraki_output_header"><b>Device Name</b></td>\
+				<td class="meraki_output_header"><b>Device Serial</b></td>\
+				<td class="meraki_output_header"><b>Device Model</b></td>\
+				<td class="meraki_output_header"><b>Device IP</b></td>\
+				<td class="meraki_output_header"><b>Device MAC</b></td>\
+			</tr>\
+		</table>\
+	');
+	$.each(sorted, function(j) {
+		devices = sorted[j].devices;
+		number_of_devices = devices.length;
+		if ( number_of_devices > 0 ) {
+			$("#meraki_inventory_output_table").append('\
+				<tr>\
+					<td rowspan="'+number_of_devices+'" class="meraki_output_group">' + this.name + '</td>\
+					<td rowspan="'+number_of_devices+'" class="meraki_output_group">' + this.type + '</td>\
+					<td>' + devices[0].name + '</td>\
+					<td>' + devices[0].serial + '</td>\
+					<td>' + devices[0].model + '</td>\
+					<td>' + devices[0].lanIp + '</td>\
+					<td>' + devices[0].mac + '</td>\
+				</tr>\
+			');
+			csv = csv + ([this.name, this.type, devices[0].name, devices[0].serial, devices[0].model, devices[0].lanIp, devices[0].mac].join()) + "\r\n";
+			for (i=1; i<number_of_devices; i++) {
+				$("#meraki_inventory_output_table").append('\
+					<tr>\
+						<td>' + devices[i].name + '</td>\
+						<td>' + devices[i].serial + '</td>\
+						<td>' + devices[i].model + '</td>\
+						<td>' + devices[i].lanIp + '</td>\
+						<td>' + devices[i].mac + '</td>\
+					</tr>\
+				');
+				csv = csv + ([sorted[j].name, sorted[j].type, devices[i].name, devices[i].serial, devices[i].model, devices[i].lanIp, devices[i].mac].join()) + "\r\n";
+			}
+		}
+		else {
+			$("#meraki_inventory_output_table").append('\
+				<tr>\
+					<td class="meraki_output_group">' + this.name + '</td>\
+					<td class="meraki_output_group">' + this.type + '</td>\
+					<td>No devices found</td>\
+					<td></td>\
+					<td></td>\
+					<td></td>\
+					<td></td>\
+				</tr>\
+			');
+		}
+	});
+	$("#meraki_inventory_output").append('<p><br/><br/>Please find below in CSV format:</p>');
+	$("#meraki_inventory_output").append('<textarea name="meraki_inventory_csv_output" id="meraki_inventory_csv_output" style="width:100%" rows="50" ></textarea>');
+	$('#meraki_inventory_csv_output').text(csv);
+	status_update("Done...");
+}
+
+function check_nets_complete() {
+    if( nets_completed != number_of_nets) { 
+		status_update("Retrieved data for " + nets_completed + " / " + number_of_nets + " networks - waiting for more data...");
+        return false;
+    }
+    return true;
+}
+
 //GET LICENCES
 
@@ -522,7 +694,7 @@
 }
 
+
 function do_this_when_all_loops_are_done() {
 	status_update("Done...");
-	//Output something?
 }
 
Index: include.php
===================================================================
--- include.php	(revision 18b334175a50d4277e8b097d135fa82f13bc86ea)
+++ include.php	(revision 8971868f8273c59683e92cd79c747691e784ebd0)
@@ -64,4 +64,12 @@
 				echo ( get_org_admins($_POST['orgid'], $key) );
 				break;
+			case "get_org_networks":
+				error_log("Username: " . $_SERVER['REMOTE-USER'] . " Key: " . $truncated_key . " Action: " . $_POST['action'], 0);
+				echo ( get_org_networks($_POST['orgid'], $key) );
+				break;
+			case "get_network_devices":
+				error_log("Username: " . $_SERVER['REMOTE-USER'] . " Key: " . $truncated_key . " Action: " . $_POST['action'], 0);
+				echo ( get_network_devices($_POST['orgid'], $_POST['networkid'], $key) );
+				break;
 			case "add_org_admin":
 				error_log("Username: " . $_SERVER['REMOTE-USER'] . " Key: " . $truncated_key . " Action: " . $_POST['action'], 0);
@@ -91,6 +99,11 @@
 	
 	//Get a list of networks in an organisation
-	function get_org_nets($orgid, $key) {
+	function get_org_networks($orgid, $key) {
 		return get_request('/organizations/' . $orgid . '/networks', $key);
+	}
+	
+	//Get a list of devices in an organisation
+	function get_network_devices($orgid, $netid, $key) {
+		return get_request('/networks/' . $netid . '/devices', $key);
 	}
 
Index: index.php
===================================================================
--- index.php	(revision 18b334175a50d4277e8b097d135fa82f13bc86ea)
+++ index.php	(revision 8971868f8273c59683e92cd79c747691e784ebd0)
@@ -11,4 +11,5 @@
 	<p>Please select a function:</p>
 	<ul>
+		<li><a href="inventory.php">Inventory</a></li>
 		<li><a href="licences.php">Licences</a></li>
 		<li><a href="accounts.php">Account Administration</a></li>
Index: inventory.php
===================================================================
--- inventory.php	(revision 8971868f8273c59683e92cd79c747691e784ebd0)
+++ inventory.php	(revision 8971868f8273c59683e92cd79c747691e784ebd0)
@@ -0,0 +1,42 @@
+<?php
+include ('include.php');
+
+$page_name = "Meraki Inventory";
+$page_header = preg_replace ( '/PAGE_NAME/', $page_name, $page_header );
+
+if ( !isset ( $_POST['action'] ) || $_POST['action'] == "" ) {
+	echo ( $page_header );
+	new_request();
+	echo ( $page_footer );
+}
+else {
+	parse_request();
+}
+
+	function new_request() { ?>
+		
+		<div class="meraki_licence_state" id="meraki_licence_state">
+			<h2>Inventory of Organisation</h2>
+			<div id="meraki_status"><pre>Current status: Awaiting user input</pre></div>
+
+			<div class="meraki_container meraki_form">
+				<?php ro_key_fields(); ?>
+				<input type="button" class="meraki_button" name="meraki_next1" id="meraki_next1" value="Next" onclick="get_inv_orgs();">
+			</div>
+			
+			<div id="meraki_orgs_output"></div>
+			
+			<div id="meraki_inventory_output"></div>
+		</div>
+			
+
+
+		
+		<script>
+			var page = "inventory";
+		</script>
+		<?php
+		return;
+	}
+
+?>
