类 如何在 Samsung SmartThings 应用程序中实现设备和传感器?

How classes for devices and sensors are implemented in Samsung SmartThings applications?

我们想为三星 Groovy SmartThings 实施基础设施。当然,基础设施的主要部分是使用相应的方法为每个设备实现不同的 classes。 例如,对于锁的设备,我们假设我们有一把锁 class,方法是 lock() 和 unlock()。这里的问题是我们在 Groovy:

中的一个 SmartThings 应用程序中有这部分代码
def presence(evt)
{
    if (evt.value == "present") {
            //Somecode
            lock1.unlock()
    }
    else {
            //Somecode
            lock1.lock()
    }
}

所以很可能,lock1 是 class 锁的对象,而 lock() 和 unlock() 是 class 的方法。事情是这样的: 使用 lock1[0].unlock() 命令解锁编号为 #0 的门锁,但使用 lock1.unlock() 命令解锁所有门锁。

这里的问题是 class 是如何创建的?如果 lock1 是一个对象列表,我们如何才能拥有像 lock1.unlock() 这样的命令。

这里的要点是两个对象都应具有相同的名称 lock1,并且两个方法都是名为 lock() 的相同方法。

提前致谢。

这里有 2 个选项:

1) 使用 Groovy 的扩展运算符对列表的每个元素调用该方法:

List lock1 = [.....]
lock1.*lock()

2) 创建一个 Lock class 扩展或包含元素列表,并向其添加一个 class-level 方法:

class Lock {
  List locks

  def lock() {
    locks.*lock()
  }

  // this method allows for calls like lock1[42].lock()
  def getAt( int ix ) { 
    locks[ ix ] 
  } 
}

实际上,继承对于物联网设备来说是不好的。

这里要看到的"problem"是Groovy中的(隐含的)spread operator

The expression cars*.make is equivalent to cars.collect{ it.make }. Groovy’s GPath notation allows a short-cut when the referenced property isn’t a property of the containing list, in that case it is automatically spread. In the previously mentioned case, the expression cars.make can be used, though retaining the explicit spread-dot operator is often recommended.

(那里的例子说的是 GPath,但对于列表、地图等也是如此)

所以在这种情况下 lock1.unlock()lock1*.unlock()。 (动态)Groovy 会看到,列表中没有 unlock() 方法,只是散开。

至于"So most probably, lock1 is the object for class lock",会让你做噩梦。不要猜测 - 找出答案。您可以 println(lock1.inspect()) 了解详细信息,希望 class 的作者有先见之明来添加有用的 toString() 方法。检查文档,你分配 locks1 的函数 returns 是什么。使用工具,告诉您类型(IDE、调试器、...)。

对于开发者更好的命名有帮助:

// BAD naming
def locks1 = smartThings.getAll(Lock, clientId)
// better naming, add the type if it helps you or your IDE
Collection<Lock> allLocks = smartThings.getAll(Lock, clientId)

现在,如果您调用 allLocks.lock(),发生的事情就更明显了。

要防止隐式扩展运算符,您可以在 groovy 脚本中使用静态编译。例如:

class Lock {
    def lock() { println "lock" }
    def unlock() { println "unlock" }
}

@groovy.transform.CompileStatic
class X {
    public static main() {
        [new Lock()].lock()
    }
}

这不会编译:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
x.groovy: 9: [Static type checking] - Cannot find matching method java.util.List#lock(). Please check if the declared type is correct and if the method exists.
 @ line 9, column 3.
                [new Lock()].lock()
     ^

1 error

使用显式扩展运算符 ([new Lock()]*.lock()) 进行编译。