Prechádzať zdrojové kódy

Added iot support in agi (wip)

TC pushbot 5 4 rokov pred
rodič
commit
8e33338e8d

+ 3 - 1
iot.go

@@ -95,6 +95,8 @@ func IoTHubInit() {
 
 		//Add more here if needed
 
+		//Finally, inject the gateway into the AGI interface
+		AGIGateway.Option.IotManager = iotManager
 	}
 
-}
+}

+ 3 - 0
mod/agi/agi.go

@@ -13,6 +13,7 @@ import (
 	apt "imuslab.com/arozos/mod/apt"
 	auth "imuslab.com/arozos/mod/auth"
 	metadata "imuslab.com/arozos/mod/filesystem/metadata"
+	"imuslab.com/arozos/mod/iot"
 	user "imuslab.com/arozos/mod/user"
 )
 
@@ -46,6 +47,7 @@ type AgiSysInfo struct {
 	ModuleRegisterParser func(string) error
 	AuthAgent            *auth.AuthAgent
 	FileSystemRender     *metadata.RenderHandler
+	IotManager           *iot.Manager
 
 	//Scanning Roots
 	StartupRoot   string
@@ -91,6 +93,7 @@ func NewGateway(option AgiSysInfo) (*Gateway, error) {
 	gatewayObject.ImageLibRegister()
 	gatewayObject.FileLibRegister()
 	gatewayObject.HTTPLibRegister()
+	gatewayObject.IoTLibRegister()
 
 	return &gatewayObject, nil
 }

+ 9 - 9
mod/agi/agi.http.go

@@ -37,23 +37,23 @@ func (g *Gateway) injectHTTPFunctions(vm *otto.Otto, u *user.User) {
 		//Get URL from function variable
 		url, err := call.Argument(0).ToString()
 		if err != nil {
-			return otto.NaNValue()
+			return otto.NullValue()
 		}
 
 		//Get respond of the url
 		res, err := http.Get(url)
 		if err != nil {
-			return otto.NaNValue()
+			return otto.NullValue()
 		}
 
 		bodyContent, err := ioutil.ReadAll(res.Body)
 		if err != nil {
-			return otto.NaNValue()
+			return otto.NullValue()
 		}
 
 		returnValue, err := vm.ToValue(string(bodyContent))
 		if err != nil {
-			return otto.NaNValue()
+			return otto.NullValue()
 		}
 
 		return returnValue
@@ -63,7 +63,7 @@ func (g *Gateway) injectHTTPFunctions(vm *otto.Otto, u *user.User) {
 		//Get URL from function paramter
 		url, err := call.Argument(0).ToString()
 		if err != nil {
-			return otto.NaNValue()
+			return otto.NullValue()
 		}
 
 		//Get JSON content from 2nd paramter
@@ -89,13 +89,13 @@ func (g *Gateway) injectHTTPFunctions(vm *otto.Otto, u *user.User) {
 		resp, err := client.Do(req)
 		if err != nil {
 			log.Println(err)
-			return otto.NaNValue()
+			return otto.NullValue()
 		}
 		defer resp.Body.Close()
 
 		bodyContent, err := ioutil.ReadAll(resp.Body)
 		if err != nil {
-			return otto.NaNValue()
+			return otto.NullValue()
 		}
 
 		returnValue, _ := vm.ToValue(string(bodyContent))
@@ -107,13 +107,13 @@ func (g *Gateway) injectHTTPFunctions(vm *otto.Otto, u *user.User) {
 		//Get URL from function paramter
 		url, err := call.Argument(0).ToString()
 		if err != nil {
-			return otto.NaNValue()
+			return otto.NullValue()
 		}
 
 		//Request the url
 		resp, err := http.Get(url)
 		if err != nil {
-			return otto.NaNValue()
+			return otto.NullValue()
 		}
 
 		headerKey, err := call.Argument(1).ToString()

+ 101 - 0
mod/agi/agi.iot.go

@@ -0,0 +1,101 @@
+package agi
+
+import (
+	"encoding/json"
+	"log"
+
+	"github.com/robertkrimen/otto"
+	user "imuslab.com/arozos/mod/user"
+)
+
+/*
+	AGI IoT Control Protocols
+
+	This is a library for allowing AGI script to control / send commands to IoT devices
+	Use with caution and prepare to handle errors. IoT devices are not always online / connectabe.
+
+	Author: tobychui
+*/
+
+func (g *Gateway) IoTLibRegister() {
+	err := g.RegisterLib("iot", g.injectIoTFunctions)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func (g *Gateway) injectIoTFunctions(vm *otto.Otto, u *user.User) {
+	vm.Set("_iot_scan", func(call otto.FunctionCall) otto.Value {
+		scannedDevices := g.Option.IotManager.ScanDevices()
+		js, _ := json.Marshal(scannedDevices)
+		devList, err := vm.ToValue(string(js))
+		if err != nil {
+			return otto.FalseValue()
+		}
+		return devList
+	})
+
+	vm.Set("_iot_list", func(call otto.FunctionCall) otto.Value {
+		devices := g.Option.IotManager.GetCachedDeviceList()
+		js, _ := json.Marshal(devices)
+		devList, err := vm.ToValue(string(js))
+		if err != nil {
+			return otto.FalseValue()
+		}
+		return devList
+	})
+
+	vm.Set("_iot_connect", func(call otto.FunctionCall) otto.Value {
+		return otto.NullValue()
+	})
+
+	vm.Set("_iot_status", func(call otto.FunctionCall) otto.Value {
+		return otto.NullValue()
+	})
+
+	vm.Set("_iot_exec", func(call otto.FunctionCall) otto.Value {
+		return otto.NullValue()
+	})
+
+	vm.Set("_iot_disconnect", func(call otto.FunctionCall) otto.Value {
+		return otto.NullValue()
+	})
+
+	vm.Set("_iot_iconTag", func(call otto.FunctionCall) otto.Value {
+		return otto.NullValue()
+	})
+
+	vm.Set("_iot_ready", func(call otto.FunctionCall) otto.Value {
+		if g.Option.IotManager == nil {
+			return otto.FalseValue()
+		} else {
+			return otto.TrueValue()
+		}
+	})
+
+	//Wrap all the native code function into an imagelib class
+	_, err := vm.Run(`
+		var iot = {
+			"scan": function(){
+				var devList = _iot_scan();
+				return JSON.parse(devList);
+			},
+			"list": function(){
+				var devList = _iot_list();
+				return JSON.parse(devList);
+			}
+		};
+
+		iot.ready = _iot_ready;
+		iot.connect = _iot_connect;
+		iot.status = _iot_status;
+		iot.exec = _iot_exec;
+		iot.disconnect = _iot_disconnect;
+		iot.iconTag = _iot_iconTag;
+		
+	`)
+
+	if err != nil {
+		log.Println("*AGI* IoT Functions Injection Error", err.Error())
+	}
+}

+ 11 - 3
mod/iot/handlerManager.go

@@ -161,7 +161,7 @@ func (m *Manager) HandleGetDeviceStatus(w http.ResponseWriter, r *http.Request)
 //Handle IoT Scanning Request
 func (m *Manager) HandleScanning(w http.ResponseWriter, r *http.Request) {
 	//Scan the devices
-	scannedDevices := m.scanDevices()
+	scannedDevices := m.ScanDevices()
 
 	js, _ := json.Marshal(scannedDevices)
 	sendJSONResponse(w, string(js))
@@ -170,14 +170,22 @@ func (m *Manager) HandleScanning(w http.ResponseWriter, r *http.Request) {
 //Handle IoT Listing Request
 func (m *Manager) HandleListing(w http.ResponseWriter, r *http.Request) {
 	if m.cachedDeviceList == nil {
-		m.scanDevices()
+		m.ScanDevices()
 	}
 
 	js, _ := json.Marshal(m.cachedDeviceList)
 	sendJSONResponse(w, string(js))
 }
 
-func (m *Manager) scanDevices() []*Device {
+func (m *Manager) GetCachedDeviceList() []*Device {
+	if m.cachedDeviceList == nil {
+		m.ScanDevices()
+	}
+
+	return m.cachedDeviceList
+}
+
+func (m *Manager) ScanDevices() []*Device {
 	scannedDevices := []*Device{}
 	for _, ph := range m.RegisteredHandler {
 		//Scan devices using this handler

+ 3 - 3
web/SystemAO/file_system/file_explorer.html

@@ -1585,7 +1585,7 @@
                                 <img draggable="true"ondragstart="disableDrag(event);" src="../../../img/desktop/files_icon/${filesIconTheme}/folder.png" style="height: 148px; width: 148px; display: inline-block;">
                             </div>
                             <div class="content" style="font-size: 12px;">
-                                <div class="header ${currentTheme} ${textclass}">${displayName} ${shareicon}</div>
+                                <div class="header ${currentTheme} ${textclass}" title="${filename}">${displayName} ${shareicon}</div>
                             </div>
                         </div>`);
                     }
@@ -1667,7 +1667,7 @@
                                 <img draggable="true"ondragstart="disableDrag(event);" style="height: 148px; width: 148px; display:inline-block;" src="${imagePath}">
                             </div>
                             <div class="content">
-                                <div class="header ${currentTheme} ${textclass}" style="text-overflow: ellipsis; font-size: 100%">${displayName} ${shareicon}</div>
+                                <div class="header ${currentTheme} ${textclass}" title="${filename}" style="text-overflow: ellipsis; font-size: 100%">${displayName} ${shareicon}</div>
                                 <div class="meta ${currentTheme}">
                                     <div>.${ext}</div>
                                 </div>
@@ -4438,7 +4438,7 @@
                             $("#folderList").html(`<div class="ts basic segment ${currentTheme}">
                                 <div class="ts header ${currentTheme}">
                                     <i class="question icon" ${currentTheme}></i> <span class="${currentTheme}">No Matching Results</span>
-                                    <div class="sub header ${currentTheme}">The host return no matching results for your keyword "${keyword}"". <br>Check your spelling and if your wildcard are valid.</div>
+                                    <div class="sub header ${currentTheme}">The host return no matching results for your keyword "${keyword}". <br>Check your spelling and if your wildcard are valid.</div>
                                 </div>
                             </div>`);
                         }else{

+ 24 - 0
web/UnitTest/backend/iot.list.js

@@ -0,0 +1,24 @@
+//IoT Scanner
+//This agi script will list the manager cached device list. If the list not exists
+//It will perform an auto scan instead.
+
+//Require the iot lib
+requirelib("iot");
+
+function main(){
+	//Check if the IoT Controller is ready
+	if (iot.ready() == true){
+		//List the iot device in cache
+		var deviceList = iot.list();
+		
+		//Return the value as JSON string
+		HTTP_HEADER = "application/json; charset=utf-8";
+		sendResp(JSON.stringify(deviceList));
+		
+	}else{
+		sendResp("IoT Manager not ready");
+	}
+}
+
+//Run the main function
+main();

+ 21 - 0
web/UnitTest/backend/iot.scan.js

@@ -0,0 +1,21 @@
+//IoT Scanner
+//This agi script force the IoT Manager to update the IoT scan results
+
+//Require the iot lib
+requirelib("iot");
+
+function main(){
+	//Check if the IoT Controller is ready
+	if (iot.ready() == true){
+		var deviceList = iot.scan();
+		
+		//Return the value as JSON string
+		sendResp(deviceList.length + " IoT devices discovered. Run iot.list.js to see the list.");
+		
+	}else{
+		sendResp("IoT Manager not ready");
+	}
+}
+
+//Run the main function
+main();