[RFC] IoT frameworks
Nikolay Khabarov
Nikolay.Khabarov at dataart.com
Thu Apr 2 20:53:49 UTC 2015
Hello,
I’d like to share with you some ideas along with some practical implementations of Ubuntu Snappy Core Frameworks for developing IoT apps as set of abstractions to provide access to standard things like simple hardware interfaces (GPIO, UART, I2C), wireless protocols (Bluetooth Low Energy, ZigBee, EnOcean), cloud services, devices connected via this interfaces etc. With all of that architects and developers will be able to mash up various APIs on edge devices, bridge local protocols and peripherals into the cloud, or run event based logic on edge device.
Imagine the task when you need to connect a Bluetooth Low Energy (BLE) switch to control a BLE light bulb and at the same time, have the ability to turn lights on or off remotely, through a web app. Without frameworks you will have to rely on language/platform specific libraries to work with BLE, and cloud platform and carry these dependencies with your snaps, compile low-level libraries for different architectures increasing overall complexity of the solution. That’s how things are currently done with OpenWRT, Raspbian, BeagleBone, etc.
Having these Frameworks and Ubuntu Snappy Core you will have to: install BLE framework snap, add BLE Bulb and Switch profile Framework Snaps, then you will have to write app code like:
def toggle():
bulb = dbus.SystemBus().get_object("com.devicehive.ble.bulb", "com/devicehive/ble/bulb")
mac = bulb.scan()
if mac:
bulb.toggle(mac)
DBusGMainLoop(set_as_default=True)
sw = dbus.SystemBus().get_object("com.devicehive.ble.switch", "com/devicehive/ble/switch")
mac = sw.scan()
sw.connect_to_signal(mac, "clicked", toggle)
GObject.MainLoop().run()
We are taking Python as a meta-language, but same concepts, can be applied to Go, Node.js, C++, or even shell script.
Now developer can publish a Snap into Ubuntu Snappy store for further use. As you can see we suggest to use dbus as interface for frameworks making it the only dependency. Lots of programming languages already have dbus bindings, some of them, with dynamic typing like Python or Node.js, can provide syntax of converting method calls into d-bus calls.
Another example, more low-level, might be connecting simple hardware chips. Dallas DS18B20 for example. It has 1-wire protocol and each developer who want to use it can start do in a few sec with such frameworks. Just install 1-wire framework(1-wire interface implementation) and ds18b20 framework (chip protocol implementation for 1-wire interface) and the to find out a temperature just call:
sensor = dbus.SystemBus().get_object("com.devicehive.1wire.ds18b20", "com/devicehive/1wire/ds18b20")
sensor.get_temperature()
As it can be seen from examples above, instead of carrying over dependencies, Frameworks can be installed through standard snappy deployment mechanism and provide the same developer experience of hardware and cloud abstraction across different languages and different SoCs.
I think it's possible to imagine plenty of other usages. More detailed description of idea you can find here: https://docs.google.com/a/devicehive.com/document/d/1XxXMZx5ff8x05p92zdly8Av7LhWKQwywUdLG4v83-zc/edit?usp=sharing
To prove the idea, I've implemented simple GPIO framework. It works on real hardware - http://youtu.be/4RsMiQU_LMM
code of framework is here: https://github.com/devicehive/IoT-framework-gpio/blob/master/src/daemon/gpio-daemon
code of examples: https://github.com/devicehive/IoT-framework-gpio/tree/master/src/examples
dbus specification: https://github.com/devicehive/IoT-framework-gpio/blob/master/DBUS-SPEC.md
You can also download prebuilt snaps for it and play:
framework snap: https://drive.google.com/a/devicehive.com/file/d/0B9jKFl3qYG3paFVzekR6bzhYamc/view?usp=sharing
examples snap: https://drive.google.com/a/devicehive.com/file/d/0B9jKFl3qYG3pdXBDOUd3Nm5ycjQ/view?usp=sharing
Currently to run it on Ubuntu Snappy you need to modify /etc/dbus-1/system.conf - change 'deny' to 'allow' in this two lines
<deny own=*" />
<deny send_type="method_call" />
Another quick example is building s Snap that relies on BLE and EnOcean Frameworks to control a BLE bulb with a wireless switch without any battery power, generating energy to transmit signals through mechanical force: http://www.youtube.com/watch?v=S-sbMeetzL0
Provided there are EnOcean and BLE frameworks, the code looks like this and can be transferred across different platforms and re-created in different languages having only dbus binding as a dependency.
==================================
#!/usr/bin/python3
import dbus
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GObject
import json
DBUS_BUS_ENOCEAN_NAME = 'com.devicehive.enocean'
DBUS_BUS_BLE_NAME = 'com.devicehive.bluetooth'
SWITCH_ADDRESS = '00:2A:1A:B8'
BULB_ADDRESS = 'F4:04:4C:0C:58:A3'
bulb_on_value = '0f0d0300ffffffc800c800c8000059ffff'
bulb_off_value = '0f0d0300ffffff0000c800c8000091ffff'
bulb_handle = 0x002b
DBusGMainLoop(set_as_default=True)
def init_bulb():
bus = dbus.SystemBus()
ble_manager = bus.get_object(DBUS_BUS_BLE_NAME, '/')
bulb_path = ble_manager.Create(BULB_ADDRESS, dbus_interface='com.devicehive.BluetoothManager')
return bus.get_object(DBUS_BUS_BLE_NAME, bulb_path)
bulb = init_bulb()
def turn_bulb(on):
if on:
print('ON')
bulb.Write(bulb_handle, bulb_on_value, False, dbus_interface='com.devicehive.BluetoothDevice')
else:
print('OFF')
bulb.Write(bulb_handle, bulb_off_value, False, dbus_interface='com.devicehive.BluetoothDevice')
def message_received(value):
res = json.loads(value)
if res['sender'] == SWITCH_ADDRESS:
if res['R1']['raw_value'] == 2:
turn_bulb(True)
if res['R1']['raw_value'] == 3:
turn_bulb(False)
def main():
bus = dbus.SystemBus()
enocean_manager = bus.get_object(DBUS_BUS_ENOCEAN_NAME, '/com/devicehive/enocean')
enocean = dbus.Interface(enocean_manager, DBUS_BUS_ENOCEAN_NAME)
enocean.connect_to_signal('message_received', message_received)
try:
GObject.MainLoop().run()
except KeyboardInterrupt:
pass
if __name__ == '__main__':
main()
==================================
Thanks,
Nikolay Khabarov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ubuntu.com/archives/snappy-devel/attachments/20150402/af2eedc2/attachment-0001.html>
More information about the snappy-devel
mailing list