package hds import ( "errors" "log" "strconv" "strings" "sync" "imuslab.com/arozos/mod/iot" ) /* Home Dynamic System Author: tobychui This is a compaitbility module for those who are still using HDSv1 protocol If you are still using HDSv1, you should consider upgrading it to the latest version of HDS protocols. */ type Handler struct { lastScanTime int64 } //Create a new HDS Protocol Handler func NewProtocolHandler() *Handler { //Create a new MDNS Host return &Handler{} } //Start the HDSv1 scanner, which no startup process is required func (h *Handler) Start() error { log.Println("*IoT* Home Dynamic System (Legacy) Loaded") return nil } //Scan all the HDS devices in LAN using the legacy ip scanner methods func (h *Handler) Scan() ([]*iot.Device, error) { //Get the current local IP address ip := getLocalIP() if ip == "" { //Not connected to a network? return nil, errors.New("Unable to get ip address of host device") } //Only handle a small subset of ip ranges (Last 255 addfress) scanBase := "" valid := false if ip[:8] == "192.168." { tmp := strings.Split(ip, ".") tmp = tmp[:len(tmp)-1] scanBase = strings.Join(tmp, ".") + "." //Return 192.168.0. valid = true } else if ip[:4] == "172." { //Handle 172.16.x.x - 172.31.x.x tmp := strings.Split(ip, ".") val, err := strconv.Atoi(tmp[1]) if err == nil { if val >= 16 && val <= 31 { //Private addr range valid = true scanBase = strings.Join(tmp, ".") + "." //Return 172.16.0. } } } //Check if the IP range is supported by HDS protocol if !valid { log.Println("*IoT* Home Dynamic Protocol requirement not satisfied. Skipping Scan") return nil, nil } //Create a IP scanner var wg sync.WaitGroup for i := 1; i < 256; i++ { wg.Add(1) go tryGetHDSUUID(&wg, scanBase+strconv.Itoa(i)) } log.Println("*IoT* Home Dynamic waiting for responses") wg.Wait() log.Println("*IoT* Home Dynamic - DONE") return nil, nil } //Home Dynamic system's devices no need to established conenction before executing anything func (h *Handler) Connect(device *iot.Device, authInfo *iot.AuthInfo) error { return nil } //Same rules also apply to disconnect func (h *Handler) Disconnect(device *iot.Device) error { return nil } //Get the status of the device func (h *Handler) Execute(device *iot.Device, endpoint *iot.Endpoint, payload interface{}) (interface{}, error) { var result interface{} return result, nil } //Get the status of the device func (h *Handler) Status(device *iot.Device) (map[string]interface{}, error) { resp, err := tryGet("http://" + device.IPAddr + "/status") if err != nil { return map[string]interface{}{}, err } //Convert the resp into map string itnerface result := map[string]interface{}{} result["status"] = resp return result, nil } //Return the specification of this protocol handler func (h *Handler) Stats() iot.Stats { return iot.Stats{ Name: "Home Dynamic", Desc: "A basic IoT communication protocol for ESP8266 for ArOZ Online Beta", Version: "1.0", ProtocolVer: "1.0", Author: "tobychui", AuthorWebsite: "https://git.hkwtc.org/TC/HomeDynamic", AuthorEmail: "", ReleaseDate: 1576094199, } }