Kivy rulz: ClockWidget: Final version

The code of the final version of the multi-touch enabled ClockWidget:

Kivy ClockWidget on a Lenovo X220T

ClockWidget.py:

import kivy
kivy.require('1.2.0')

import time

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty, StringProperty, NumericProperty
from kivy.clock import Clock
from kivy.uix.scatter import Scatter
from kivy.config import Config
Config.set('modules', 'touchring', '')

Weekday = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

def getDayOfWeek(dateString):
 t1 = time.strptime(dateString,"%m/%d/%Y")
 t2 = time.mktime(t1)
 return(time.localtime(t2)[6])

class ClockWidget(Scatter):
 uxTime = StringProperty('')
 uxSeconds = NumericProperty(0)
 uxSecondsStr = StringProperty('')
 uxDate = StringProperty('')
 uxDay = StringProperty('')

def update(self, dt):
 self.uxTime = time.strftime("%H:%M", time.localtime())
 self.uxSecondsStr = time.strftime("%S", time.localtime())
 self.uxSeconds = int(self.uxSecondsStr)
 self.uxDate = time.strftime("%d %B %Y", time.localtime())
 self.uxDay = Weekday[getDayOfWeek(time.strftime("%m/%d/%Y", time.localtime()))]

class ClockWidgetApp(App):
 def build(self):
    clockWidget = ClockWidget()
    Clock.schedule_interval(clockWidget.update, 1)
    return clockWidget

if __name__ == '__main__':
 ClockWidgetApp().run()

ClockWidget.kv:

#:kivy 1.0

<ClockWidget>:
   scale_max: 100
   size_hint: None, None
   size: (512, 512)
   pos: (50, 50)

FloatLayout:
   canvas:
   Color:
      rgb: 1, 1, 1
   Ellipse:
      size: 150, 150
      pos: 430, 240

   Color:
      rgb: 0, 0, 1
   Ellipse:
      size: 150, 150
      angle_start: 0
      angle_end: root.uxSeconds * 6
      pos: 430, 240

   Color:
      rgb: 0, 0, 0

   Ellipse:
      size: 130, 130
      pos: 440, 250

   Label:
      text: root.uxSecondsStr
      font_size: 70
      pos: 455, 260

   FloatLayout:
      size: root.width, root.height

   Label:
      id: time_label
      text: root.uxTime
      font_size: 100
      pos: 0, 50

   Label:
      id: date_label
      text: root.uxDate
      font_size: 30
      pos: 40, -20

   Label:
      id: day_label
      text: root.uxDay
      font_size: 30
      pos: 160, -60

Kivy rulz: ClockWidget: First version

kivy-logo-black-512

A couple of days ago, I discovered Kivy. It allows for rapid development of applications that make use of innovative user interfaces, such as multi-touch applications.

Some facts about Kivy:

  • based on Python
  • cross-platform: Windows, Mac OS X, Linux, Android, iOS
  • 100% free to use (LGPL v3 license)
  • GPU accelerated (OpenGL ES 2.0)
  • stable
  • well documented
  • damn fast

Let’s see how easy it is to build something.

We are going to build a ClockWidget. The design is based on the MoonyDesk digital clock, which you can find on CodePlex:

moonydesk

This is the result:

First version of the Kivy ClockWidget

I was able to build this in under four hours, although I am new to Kivy and had to go a lot through the documentation while I was implementing this.

In a following blog post we will add multi-touch behavior, so we are able to move, resize and rotate the widget. That will be a lot more fun.

Next time I will share the code with you.

Wireless Sensor Networks

The ZigBee protocol is a popular way of creating wireless sensor networks. It automatically forms networks that can heal themselves and provide routing.

Digi International manufactures a wide range of XBee-branded radios. For our sensor network, we will use the series 2 that support the full ZigBee protocol. Since we are located in Europe, 10mW is the maximum transmission power allowed per device.

ZigBee devices can be configured as Coordinator, Router or End Device, depending on their role in the network. Each network must have 1 and only 1 coordinator.  The others, depending on the topology and number of devices, will be configured as Router or End Device. In our network, we will configure the other devices as End Device and use a star-topology with the Coordinator as central hub.

An XBee can be connected to sensors and actuators. For our remote sensor nodes, we will connect a light sensor and a movement sensor (Passive Infra-Red). Furthermore, we will periodically send remote AT commands to the end devices to query their temperature (an XBee PRO feature) and their supply voltage.

EndDevice1     EndDevice2

The coordinator is connected to a microcontroller (a GHI Spider running .NET Micro Framework) that serves as the brain of the sensor network and a gateway to the internet.  End Devices are configured to periodically wake up, poll their sensors and send the data to the microcontroller. The movement sensor can also awake the XBee when movement is detected, so that the microcontroller is notified instantly.

In addition, some sensors are connected directly to the microcontroller: barometer, light, temperature and current. The microcontroller uses a WiFi module to send the collected sensor data to a repository on the web.

MCU

To access our data, we send it to thingspeak.com. For our network, we create a channel per end device. Each channel has four fields representing the four sensors of the end device: light, temperature, movement and supply voltage. ThingSpeak allows us to view our data in configurable graphs and react to certain conditions, for example send a tweet when movement is detected in a certain room. ThingSpeak functionality is also exposed by REST web services that easily integrate with your own applications.

The challenge is to make sense of it all. A huge amount of data is collected by the sensor network and simple graphs often don’t reveal useful information very clearly. New websites such as Open.Sen.se focus on creating (web) applications to process the raw data from the wireless sensor network and create new data, more useful than the raw bits sent by a sensor.

The microcontroller  uses the coordinator to send remote commands to the end devices to query their temperature and supply voltage. When actuators (switches, motors, …) are connected to the remote end devices, the microcontroller  can also control these using remote AT commands. You could, for example, use a switch in an Open.Sen.se application and when the switch is toggled, a value is written to an output feed that the microcontroller  polls using simple HTTP GET calls. When the microcontroller  notices a new value for the switch’s output feed, it sends the appropriate command to the remote end device, instructing it to change the value on the corresponding output pin.