예제 #1
0
func GetDeviceCurrentStatus(urlparams martini.Params, r render.Render) {
	identifier := urlparams["identifier"]
	server.Log.Printf("ACTION GetDeviceCurrentStatus, identifier:: %v", identifier)

	device := &models.Device{}
	err := server.RPCCallByName("registry", "Registry.FindDeviceByIdentifier", identifier, device)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrDeviceNotFound, err))
		return
	}

	onlineargs := rpcs.ArgsGetDeviceOnlineStatus{
		Id: uint64(device.ID),
	}
	onlinereply := rpcs.ReplyGetDeviceOnlineStatus{}
	err = server.RPCCallByName("devicemanager", "DeviceManager.GetDeviceOnlineStatus", onlineargs, &onlinereply)
	if err != nil {
		server.Log.Errorf("get devie online status error: %v", err)
		r.JSON(http.StatusOK, renderError(ErrDeviceNotOnline, err))
		return
	}

	statusargs := rpcs.ArgsGetStatus{
		Id: uint64(device.ID),
	}
	statusreply := rpcs.ReplyGetStatus{}
	err = server.RPCCallByName("controller", "Controller.GetStatus", statusargs, &statusreply)
	if err != nil {
		server.Log.Errorf("get devie status error: %v", err)
		r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
		return
	}

	product := &models.Product{}
	err = server.RPCCallByName("registry", "Registry.FindProduct", device.ProductID, product)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrProductNotFound, err))
		return
	}

	c, err := productconfig.New(product.ProductConfig)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrWrongProductConfig, err))
		return
	}

	data, err := c.StatusToMap(statusreply.Status)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrWrongStatusFormat, err))
		return
	}
	result := DeviceStatusResponse{
		Data: data,
	}

	r.JSON(http.StatusOK, result)
	return
}
예제 #2
0
func (ift *Ifttt) Check(deviceid uint64, eventid uint16) error {
	actions := &[]models.Rule{}
	query := &models.Rule{
		RuleType: "ifttt",
		DeviceID: int64(deviceid),
	}
	err := server.RPCCallByName("registry", "Registry.QueryRules", query, actions)
	if err != nil {
		server.Log.Warnf("load ifttt rules error : %v", err)
		return err
	}

	if len(*actions) > 0 {
		device := &models.Device{}
		err := server.RPCCallByName("registry", "Registry.FindDeviceById", int64(deviceid), device)
		if err != nil {
			server.Log.Errorf("find device error : %v", err)
			return err
		}

		product := &models.Product{}
		err = server.RPCCallByName("registry", "Registry.FindProduct", device.ProductID, product)
		if err != nil {
			server.Log.Errorf("find product error : %v", err)
			return err
		}

		c, err := productconfig.New(product.ProductConfig)
		if err != nil {
			server.Log.Errorf("product config error : %v", err)
			return err
		}

		name := ""
		for _, ev := range c.Events {
			if ev.No == int(eventid) {
				name = ev.Name
			}
		}

		for _, action := range *actions {
			if action.Trigger == name {
				err := performRuleAction(action.Target, action.Action)
				if err != nil {
					server.Log.Warnf("ifttt action failed: %v", err)
				}
			}
		}
	}

	return nil
}
예제 #3
0
// check if proudct is ok and map a product config to context, must by called after CheckDevice
func CheckProductConfig(context martini.Context, device *models.Device,
	params martini.Params, req *http.Request, r render.Render) {
	product := &models.Product{}
	err := server.RPCCallByName("registry", "Registry.FindProduct", device.ProductID, product)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrProductNotFound, err))
		return
	}

	c, err := productconfig.New(product.ProductConfig)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrWrongProductConfig, err))
		return
	}

	context.Map(c)
}
예제 #4
0
func addProduct() error {
	args := models.Product{}

	reader := bufio.NewReader(os.Stdin)

	fmt.Printf("vendor ID: ")
	id, err := reader.ReadString('\n')
	if err != nil {
		return err
	}
	vendor := strings.Replace(id, "\n", "", -1)
	vendorid, err := strconv.Atoi(vendor)
	if err != nil {
		return err
	}
	args.VendorID = int32(vendorid)

	fmt.Printf("product name: ")
	name, err := reader.ReadString('\n')
	if err != nil {
		return err
	}
	args.ProductName = strings.Replace(name, "\n", "", -1)

	fmt.Printf("product description: ")
	desc, err := reader.ReadString('\n')
	if err != nil {
		return err
	}
	args.ProductDescription = strings.Replace(desc, "\n", "", -1)

	fmt.Printf("product config json file: ")
	file, err := reader.ReadString('\n')
	if err != nil {
		return err
	}
	jsonfile := strings.Replace(file, "\n", "", -1)
	fi, err := os.Open(jsonfile)
	if err != nil {
		return err
	}
	content, err := ioutil.ReadAll(fi)
	config := string(content)
	fi.Close()
	_, err = productconfig.New(config)
	if err != nil {
		return err
	}
	args.ProductConfig = config

	reply := &models.Product{}

	err = server.RPCCallByName("registry", "Registry.SaveProduct", &args, reply)
	if err != nil {
		return err
	}

	fmt.Println("=======> product created successfully:")
	printStruct(reply)
	fmt.Println("=======")

	return nil
}
예제 #5
0
func SetDeviceStatus(urlparams martini.Params, req *http.Request, r render.Render) {
	identifier := urlparams["identifier"]
	server.Log.Printf("ACTION GetDeviceCurrentStatus, identifier:: %v", identifier)

	device := &models.Device{}
	err := server.RPCCallByName("registry", "Registry.FindDeviceByIdentifier", identifier, device)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrDeviceNotFound, err))
		return
	}

	onlineargs := rpcs.ArgsGetDeviceOnlineStatus{
		Id: uint64(device.ID),
	}
	onlinereply := rpcs.ReplyGetDeviceOnlineStatus{}
	err = server.RPCCallByName("devicemanager", "DeviceManager.GetDeviceOnlineStatus", onlineargs, &onlinereply)
	if err != nil {
		server.Log.Errorf("get devie online status error: %v", err)
		r.JSON(http.StatusOK, renderError(ErrDeviceNotOnline, err))
		return
	}

	var args interface{}
	decoder := json.NewDecoder(req.Body)
	err = decoder.Decode(&args)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrWrongStatusFormat, err))
		return
	}

	product := &models.Product{}
	err = server.RPCCallByName("registry", "Registry.FindProduct", device.ProductID, product)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrProductNotFound, err))
		return
	}

	c, err := productconfig.New(product.ProductConfig)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrWrongProductConfig, err))
		return
	}

	m, ok := args.(map[string]interface{})
	if !ok {
		r.JSON(http.StatusOK, renderError(ErrWrongStatusFormat, err))
		return
	}

	status, err := c.MapToStatus(m)
	if err != nil {
		r.JSON(http.StatusOK, renderError(ErrWrongStatusFormat, err))
		return
	}

	statusargs := rpcs.ArgsSetStatus{
		DeviceId: uint64(device.ID),
		Status:   status,
	}
	statusreply := rpcs.ReplySetStatus{}
	err = server.RPCCallByName("controller", "Controller.SetStatus", statusargs, &statusreply)
	if err != nil {
		server.Log.Errorf("set devie status error: %v", err)
		r.JSON(http.StatusOK, renderError(ErrSystemFault, err))
		return
	}

	r.JSON(http.StatusOK, Common{})
	return

}
예제 #6
0
func (n *Notifier) reportEvent(event rpcs.ArgsOnEvent) error {
	server.Log.Debugf("reporting event %v", event)

	device := &models.Device{}
	err := server.RPCCallByName("registry", "Registry.FindDeviceById", int64(event.DeviceId), device)
	if err != nil {
		server.Log.Errorf("find device error : %v", err)
		return err
	}

	product := &models.Product{}
	err = server.RPCCallByName("registry", "Registry.FindProduct", device.ProductID, product)
	if err != nil {
		server.Log.Errorf("find product error : %v", err)
		return err
	}

	c, err := productconfig.New(product.ProductConfig)
	if err != nil {
		server.Log.Errorf("product config error : %v", err)
		return err
	}

	ev := &protocol.Event{}
	ev.Head.No = event.No
	ev.Head.SubDeviceid = event.SubDevice
	ev.Params = event.Params

	m, err := c.EventToMap(ev)
	if err != nil {
		server.Log.Errorf("gen event json error : %v", err)
		return err
	}

	res := ReportPack{
		Tag:        "event",
		Identifier: device.DeviceIdentifier,
		Data:       m,
	}

	jsonRes, err := json.Marshal(res)
	if err != nil {
		server.Log.Errorf("json marshal error : %v", err)
		return err
	}

	reqHead := map[string]string{}
	reqHead["Content-Type"] = "application/json"

	for _, app := range n.apps {
		if nil == checkAppDomain(app.AppDomain, device.DeviceIdentifier) {
			reqHead["App-Token"] = app.AppToken
			_, err := utils.SendHttpRequest(app.ReportUrl, string(jsonRes), "POST", reqHead)
			if err != nil {
				server.Log.Errorf("http post json error : %v", err)
			}
			server.Log.Debugf("http post json succ : %v", string(jsonRes))
		}
	}

	return nil
}
예제 #7
0
func performRuleAction(target string, action string) error {
	server.Log.Infof("trigger rule action: %v, %v", target, action)

	parts := strings.Split(target, "/")
	if len(parts) != 3 {
		return fmt.Errorf("error target format: %v", target)
	}

	identifier := parts[1]
	device := &models.Device{}
	err := server.RPCCallByName("registry", "Registry.FindDeviceByIdentifier", identifier, device)
	if err != nil {
		return err
	}

	product := &models.Product{}
	err = server.RPCCallByName("registry", "Registry.FindProduct", device.ProductID, product)
	if err != nil {
		return err
	}

	config, err := productconfig.New(product.ProductConfig)
	if err != nil {
		return err
	}

	var args interface{}
	err = json.Unmarshal([]byte(action), &args)
	if err != nil {
		server.Log.Errorf("marshal action error: %v", err)
		return err
	}

	m, ok := args.(map[string]interface{})
	if !ok {
		server.Log.Errorf("decode action error:%v", err)
		return fmt.Errorf("decode action error:%v", err)
	}

	sendType := parts[2]
	switch sendType {
	case "command":
		command, err := config.MapToCommand(m)
		if err != nil {
			server.Log.Errorf("action format error: %v", err)
			return err
		}

		cmdargs := rpcs.ArgsSendCommand{
			DeviceId:  uint64(device.ID),
			SubDevice: uint16(command.Head.SubDeviceid),
			No:        uint16(command.Head.No),
			WaitTime:  uint32(3000),
			Params:    command.Params,
		}
		cmdreply := rpcs.ReplySendCommand{}
		err = server.RPCCallByName("controller", "Controller.SendCommand", cmdargs, &cmdreply)
		if err != nil {
			server.Log.Errorf("send device command error: %v", err)
			return err
		}
	case "status":
		status, err := config.MapToStatus(m)
		if err != nil {
			return err
		}

		statusargs := rpcs.ArgsSetStatus{
			DeviceId: uint64(device.ID),
			Status:   status,
		}
		statusreply := rpcs.ReplySetStatus{}
		err = server.RPCCallByName("controller", "Controller.SetStatus", statusargs, &statusreply)
		if err != nil {
			server.Log.Errorf("set devie status error: %v", err)
			return err
		}
	default:
		server.Log.Errorf("wrong action %v", action)
	}

	return nil
}