Build an IoT SaaS
using
Python
Software Engineer at Yodeck.com
kapetanos@yodeck.com
CEID - University of Patras
Previous experience
Java
μControllers and embedded devices
Present
Working with Python professionally - 3+ years
Django
Python, C, Linux on Raspberry Pi
Nikos Kapetanos
What is this presentation about?
Complete Digital Signage Solution
But first, what is digital signage?
Retail Stores
Information Billboards
Dashboards
Professionals & Offices
Complete digital signage platform
Manage your content and screens using a Web application
SaaS
Player based on Raspberry Pi
IoT in its nature (Screens being the Things)
Implemented with Python
Player
Python Application on Raspberry Pi
Web application (Backend)
Django (REST), Postgres, Celery, Redis
Web application (Frontend)
jQuery, Bootstrap, BackboneJS, RequireJS, UnderscoreJS
IoT Hub
Crossbar.io (WAMP), Redis, Postgres
Yodeck.com – Technologies
The lean way of doing business
Build an iteration of the product
Gather data on how the users are using the product (UI
heatmaps, analytics)
Analyze data and come up with ideas to change the product
based on that data
Go back and implement the changes
Fast
The lean way of doing business
Basic Building Blocks
Most popular Python web framework
Rapid development
It follows Python’s “batteries included” philosophy
User management – email verification, email reset etc.
ORM – skip SQL, just Python
Support for raw SQL queries, for complex cases or performance
Easy to use DB migration system
Powerful templating engine
…
Follows the MVC pattern
Web Framework
Django supports some of the major databases:
PostgreSQL
MariaDB (or MySQL)
OracleDB
SQLite (default on a fresh Django, tutorial-only)
Most of these are available by major cloud providers as managed
services.
Database
elery
Run tasks in the background that do not fit in a normal HTTP
request timeframe
Tasks can be run at specific intervals or just once in the future
Examples:
Offline Devices notifications
Backups
Create user reports
The code is ran in the same environment as Django, so any
Django specific code will work without any modification on
Celery.
Multiple task queues, distributed across multiple worker nodes
Task Scheduler
High Performance Web Server for our static files
Load-balancer to distribute load across multiple nodes
TLS termination
Rate limiting
Proxy requests to our Application Server (uWSGI)
Runs our Django application
Web Server / Application Server
Understanding Users
Voluntary Feedback
Tech Support contact widget
Ideas section – User submit and upvote features
Suggests existing support articles & ideas
Submit a ticket to support
Customer satisfaction polls
Alternatives: Intercom, Zendesk, Freshdesk, etc
Support – Knowledge base
Involuntary Feedback
Determine how the users are interacting with your UI
Gather heatmaps from your UI
Playback recorded user sessions
Detailed mouse clicks, movements
GDPR compliant (anonymized, opt-out)
Understanding Users
What’s missing?
Recurring payments, with all the subscription plumbing
Simple one-off payments
Keeps customer credit card information
Easy to integrate frontend widget
Webhooks (HTTP callbacks, e.g. new charge, credit card updated, etc.)
Django App: dj-stripe
Wraps all core functionality of Stripe providing a simple Python API
All data (except card numbers) also saved on our database
Supports webhooks
Recently started as beta for Greece
Alternative: Braintree
Payment Processing
What about the rest of the
presentation?
WAMP: Web Application Messaging Protocol
Allows easy communication between
“components” (code, devices, browsers, “things”)
Registered Websocket Sub-protocol
Bridges for HTTP and MQTT
What is WAMP?
HTTP provides one way communication
Client requests something from Server, Server responds
What about the other way around?
The Server needs to send something to the Client. The Client still
needs to request for it!
This is where Websockets and WAMP come into play
Why not just old good HTTP?
Crossbar.io
the reference WAMP Router
all messages are relayed by the router
Autobahn
the reference client library implementations
available for Python, Javascript (Node+Browsers), C++, Java, C
Many third-party implementations
WAMP Implementations
Publish / Subscribe
Components subscribe to topics
Components publish messages to topics
RPC (Remote Procedure Call)
Components register procedures
Other components can call these procedures
All communication is routed though the WAMP Router
What does WAMP provide?
Configuration is a single json file.
Defines Authentication, Authorization,
Transports, and more
Hands on – Crossbar.io Configuration File
Authorization: setup Roles and assign
Permissions
Specify URIs (or a pattern) and access rights
for it
When a component connects, assign a Role
Crossbar.io also supports dynamic
authentication and authorization
Just a regular component that provides RPCs
that implement authentication and
authorization
Hands on – Crossbar.io Configuration File
Connects to router
Subscribes to topic and prints out any
messages received
Publishes a “Hello World” message
Hands on – Hello Component
Connects to router
Retrieves the temperature of the
RPi
If the temperature is over 75C, call
an RPC to notify the user
Check again in 5 minutes
Hands on – Using WAMP as IoT Hub
(“thing”-side)
Connects to router
Registers a Remote Procedure to
be called through RPC
The procedure gets the
temperature as an argument
and sends out a warning email to
the user
Hands on – Using WAMP as IoT Hub
(“server”-side)
Provides a way to call RPCs and Publish to WAMP topics using standard HTTP
requests
Our Django application can interact with the devices connected to the
WAMP router using this method
So, in fact, the frontend requests the backend, the backend requests the
WAMP router and the router interacts with the device
But we can skip a step! Our frontend could be a component itself. It could
connect to the router directly. Autobahn is available also for Javascript!
This way we can provide more interactivity with the devices. The devices will
be now able to communicate directly with the frontend!
HTTP Bridge
Single router instance can handle hundreds of thousands
connected components!
How? “Twisted” asynchronous framework
Do not block on IO, yield the CPU to something that can run now.
Periodically check if IO completed
Crossbar.io Performance
Feel free to share any questions, thoughts or comments to
kapetanos@yodeck.com
Questions?