Virtual devices. I'm thinking the role of the device interface is to automate the set up of the device, as well as translate between a declarative syntax, for example, "turn on the light", and which method to call on which API. I think it's also important to emphasise that a lot of IoT devices have complex APIs, so the virtual device can and should only focus on those that are important to the user.
Declarative syntax. I think it's important for the syntax to be as declarative as possible. This is because the most significant and recurring source of complexity in an IoT use case is how the devices interact with each other and fit into the workflow, rather than device-specific operations. Hence, we try and push all the complex, imperative code to the creation of the device class - such that the user only has to specify what exactly they mean by "turn on the light" once, and then can reuse it in complex code without much deep thought.
Tags as interfaces. This is an idea we've had for a while, but the more I think about it, the more I like it. Tags as interfaces can inform many decisions - if your bulb bursts and you want to replace it, the interface could inform what functionality the new bulb you're going to buy to replace it has to meet.
Feel free to add on to this