// SubscribeCommand() function updates the command.
func (service *Service) SubscribeCommands(device *core.Device, timestamp string, timeout time.Duration) (listener *core.CommandListener, err error) {
	task, err := service.prepareSubscribeCommand(device, timestamp)
	if err != nil {
		log.Warnf("WS: failed to prepare /command/subscribe task (error: %s)", err)
		return
	}

	// add to the TX pipeline
	service.tx <- task

	select {
	case <-time.After(timeout):
		log.Warnf("WS: failed to wait %s for /command/subscribe task", timeout)
		err = fmt.Errorf("timed out")

	case <-task.done:
		err = service.processSubscribeCommand(task)
		if err != nil {
			log.Warnf("WS: failed to process /command/subscribe task (error: %s)", err)
			return
		}

		// done, create listener
		listener = core.NewCommandListener()
		service.insertCommandListener(device.Id, listener)
	}

	return
}
Example #2
0
// subscribe for commands
func (service *Service) SubscribeCommands(device *core.Device, timestamp string, timeout time.Duration) (listener *core.CommandListener, err error) {
	if listener, ok := service.commandListeners[device.Id]; ok {
		return listener, nil
	}

	// install new
	listener = core.NewCommandListener()
	service.commandListeners[device.Id] = listener

	go func(deviceId string) {
		log.Debugf("REST: start command polling %q", deviceId)
		for {
			names := ""
			wait := "30"
			cmds, err := service.PollCommands(device, timestamp, names, wait, 60*time.Second)
			if err != nil {
				log.Warnf("REST: failed to poll commands (error: %s)", err)
				// TODO: break? wait and try again?
			}
			if listener, ok := service.commandListeners[deviceId]; ok {
				for _, cmd := range cmds {
					log.Debugf("REST: got command %s received", cmd)
					timestamp = cmd.Timestamp
					listener.C <- &cmd
				}
			} else {
				log.Debugf("REST: stop command polling %q", deviceId)
				return // stop
			}
		}
	}(device.Id)

	return
}