Skip to main content

crownstone-lib-python-uart

Official Python lib for Crownstone: "Crownstone Unified System Bridge", or Crownstone USB implementation.

This works on all platforms and requires a Crownstone USB to work.

Install guide

This module is written in Python 3 and needs Python 3.7 or higher. The reason for this is that most of the asynchronous processes use the embedded asyncio core library.

If you want to use python virtual environments, take a look at the README_VENV

Pip is used for package management. You can install all dependencies by running:

python setup.py install

# or

python3 setup.py install

You can also install the package by pip

pip3 install crownstone-uart

Requirements for the Crownstone USB

OS X

OS X requires installation of the SiliconLabs driver: https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers

Ubuntu

In order to use serial without root access, you should be in the dialout group.

You can check if you're in the group:

$ groups

To add yourself:

$ sudo adduser $USER dialout

Raspbian

Similar to Ubuntu.

Arch Linux

To use serial in Arch Linux, add yourself to the uucp group.

To add yourself to the group:

$ sudo gpasswd -a $USER uucp

Make sure to logout and login again to register the group change.

Example

An example is provided in the root of this repository.

Prerequisites

  • First use the phone app to setup your Crownstones and the Crownstone USB.
  • Make sure you update the Crownstones' firmware to at least 2.1.0.
  • Find out what port to use (e.g. COM1, /dev/ttyUSB0, or /dev/tty.SLAB_USBtoUART) and fill this in at discoveryExample.py and example.py at the initializeUSB method.
  • install the CrownstoneUartLib library using the setup.py:
python3 setup.py install

# or:

python setup.py install

Find the IDs of your Crownstones

Firstly run the example script that simply lists the IDs of the Crownstones. They are located in /examples/examplesUsb:

$ python3 ./examples/discoveryExample.py

Some systems may require calling python3 specifically:

$ python3 ./examples/discoveryExample.py

Once some IDs are printed, use one of them for the next example. This can take a while because Crownstones, if not switched, only broadcast their state every 60 seconds.

Switch a Crownstone, and show power usage.

After filling in the port to use, and the Crownstone ID to switch, run the example with python 3:

$ python example.py

Some systems may require calling python3 specifically:

$ python3 example.py

The code

The example is shown below to get an idea of how everything works:

#!/usr/bin/env python3

"""An example that switches a Crownstone, and prints the power usage of the selected Crownstone."""

import time
from crownstone_uart import CrownstoneUart, UartEventBus, UartTopics


# This is the id of the Crownstone we will be switching
# change it to match the Crownstone Id you want to switch!
targetCrownstoneId = 3

def showNewData(data):
    global targetCrownstoneId
    if data["id"] == targetCrownstoneId:
        print("New data received!")
        print("PowerUsage of crownstone", data["id"], data["powerUsageReal"])
        print("-------------------")

# initialize the library
uart = CrownstoneUart()

# Start up the USB bridge.
uart.initialize_usb_sync()
# you can alternatively do this async by
# await uart.initialize_usb()

# Set up event listeners
UartEventBus.subscribe(UartTopics.newDataAvailable, showNewData)

# Switch this Crownstone on and off. This will be the initial state
switchState = True

# the try except part is just to catch a control+c, time.sleep does not appreciate being killed.
for i in range(0,100):
    if not uart.running:
        break

    if switchState:
        print("Switching Crownstone on  (iteration: ", i,")")
    else:
        print("Switching Crownstone off (iteration: ", i,")")
    uart.switch_crownstone(targetCrownstoneId, on = switchState)

    switchState = not switchState
    time.sleep(2)

# close the connection with the Crownstone USB and cleanup.
uart.stop()

Documentation

This lib is used to interpret the serial data from the Crownstone USB.

This library exposes the crownstone_uart module. From this module you can use CrownstoneUart.

from crownstone_uart import CrownstoneUart

# this is what you will be working with:
uart = CrownstoneUart()

Switching Crownstones on, off and dimming

You can use your CrownstoneUart instance to turn Crownstones on and off. This is done using the switchCrownstone function:

# this Crownstone will be switched
target_crownstone_id = 15

# turn on
uart.switch_crownstone(target_crownstone_id, on = True)

# turn off
uart.switch_crownstone(target_crownstone_id, on = False)

The Crownstone IDs range from 1 to 255. There is a limit of 255 Crownstones per Sphere. More on Spheres and Crownstone IDs can be found here (TODO).

To dim a Crownstone, you first need to tell it that is it allowed to dim. Currently this is done through the Crownstone app. When it is set to allow dimming, it can dim and switch up to 100 W devices.

You can dim your Crownstones with the dimCrownstone method:

# any value between 0 and 1 can be used. 0 is off, 1 is on
uart.dim_crownstone(target_crownstone_id, 0.5)

Getting Data

The CrownstoneUart python lib uses an event bus to deliver updates to you. You can request an instance of the event bus from CrownstoneUart:

EventBus API

You can obtain the eventBus directly from the lib:

from crownstone_uart import UartEventBus, UartTopics
subscribe(topic_name: enum, function) -> subscription_id

Returns a subscription ID that can be used to unsubscribe again with the unsubscribe method

unsubscribe(subscription_id: number)

This will stop the invocation of the function you provided in the subscribe method, unsubscribing you from the event.

These can be used like this:

# simple example function to print the data you receive
def showNewData(data):
	print("received new data: ", data)


# Set up event listeners
UartEventBus.subscribe(UartTopics.newDataAvailable, showNewData) # keep in mind that this is using the UartTopics

# unsubscribe again
UartEventBus.unsubscribe(subscriptionId)

Events

These events are available for the USB part of the lib.

UartTopics.newDataAvailable

This is a topic with a summary of the data of a message received via the mesh. If you care about the power usage, you can get it from here. If the hasError: true, the accumulated energy is not filled, nor is the power factor and the powerUsageApparent. Data format is a dictionary with the fields shown below:

{
    id:                           int    # crownstone id (0-255)
    setupMode:                    bool   # is in setup mode
    switchState:                  int
    temperature:                  int    # chip temp in Celcius
    powerFactor:                  int    # factor between real and apparent
    powerUsageReal:               int    # power usage in watts (W)
    powerUsageApparent:           int    # power usage in VA
    accumulatedEnergy:            int
    timestamp:                    int    # time on Crownstone seconds since epoch with locale correction
    dimmingAvailable:             bool   # dimming is available for use (it is not in the first 60 seconds after boot)
    dimmingAllowed:               bool   # this Crownstone can dim
    switchLocked:                 bool   # this Crownstone is switch-locked
    hasError:                     bool   # this crownstone has an error, if the crownstone has an error, the errors: {} dict is only valid if errorMode: true. This boolean is always valid.
    errorMode:                    bool   # summary type errorMode : the errors JSON is valid. This alternates with normal advertisements
    errors: {
        overCurrent:              bool
        overCurrentDimmer:        bool
        temperatureChip:          bool
        temperatureDimmer:        bool
        dimmerOnFailure:          bool
        dimmerOffFailure:         bool
        bitMask:                  int
    }
    timeIsSet:                    bool   # this crownstone knows what time it is
}
UartTopics.uartMessage

This topic will print anything you send to the USB dongle using CrownstoneUart.uartEcho. This can be used for a ping-pong implementation. Data format is a dictionary with the fields shown below:

{
    data:             [array of bytes]
    string:           stringified representation of the data
}

CrownstoneUart Synchronous API

The library can be designed synchronously (blocking) or asynchronously (asyncio). We will be moving

initialize_usb_sync(self, port : str = None, baudrate : int = 230400)

port: optional, COM port used by the serial communication. If None or not provided automatic connect will be performed.

baudrate: optional, set baudrate. Do not use if you don't know what this does.

Sets up the communication with the Crownstone USB. This can take a few seconds and is blocking. There is a async version available.

You can optionally specify a port, but if you don't it will automatically connect to available comports and handshake. This will automatically connect within a second. For Windows devices this is commonly COM1, for Linux based system /dev/ttyUSB0 and for OSX /dev/tty.SLAB_USBtoUART. Addresses and number can vary from system to system.

switch_crownstone(crownstone_id: int, on: Boolean)

crownstone_id: uid of the targeted Crownstone.

on: True for on, False for off.

Switch a Crownstone on and off This method is fire and forget, it will be sent over the mesh and is not acknowledged.

dim_crownstone(crownstone_id: int, value: float [0 .. 1])

crownstone_id: uid of the targeted Crownstone.

value: 0 is off, 1 is fully on.

While dimming, the Crownstone is rated a maximum power usage of 100 W. Dim the Crownstone. 0 is off, 1 is fully on. While dimming, the Crownstone is rated a maximum power usage of 100 W. This method is fire and forget, it will be sent over the mesh and is not acknowledged.

get_crownstone_ids() -> List[int]

Get a list of the Crownstone IDs (ints) that are known to the library. After the usb is initialized, it will automatically keep a list of Crownstone IDs it has heard. Crownstones broadcast their state about once a minute and when they're switched. This method immediately returns with the currently known of ids

stop()

Stop any running processes.

uart_echo(text: str)

send a string command to the Crownstone. This will trigger a UartTopics.uartMessage event if a reply comes in.

is_ready()

Returns True if the uart is ready for commands, False if not.

CrownstoneUart Async API

Async methods have to be awaited.

await initialize_usb(self, port = None, baudrate=230400):

Set up the communication with the Crownstone USB.

Mesh Module

The mesh module houses most of the mesh commands. Some of these are presented on the main CrownstoneUart class for easy access. You can call these methods like so:

# initialization
uart = CrownstoneUart()
uart.initialize_usb_sync()

# synchronous mesh methods
uart.mesh.<method-name>

# async mesh methods
await uart.mesh.<method-name>

turn_crownstone_on(crownstone_id: int)

crownstone_id: uid of the targeted Crownstone.

This will turn the Crownstone with the specified ID on. Turning it on with this method will respect any Twilight intensity. Fire and forget. Is not acked.

turn_crownstone_off(crownstone_id: int)

crownstone_id: uid of the targeted Crownstone.

This will turn the Crownstone with the specified ID off. Fire and forget. Is not acked.

set_crownstone_switch_state(crownstone_id: int, switch_state: float)

crownstone_id: uid of the targeted Crownstone.

switch_state: 0 is off, 1 is fully on.

switch_state is a value between 0 and 1. If the Crownstone can't dim, anything over 0 will turn it on. Fire and forget. Is not acked.

Async methods

await set_time(timestamp: int = None)

timestamp: optional, seconds since Epoch

Set the time on all Crownstones in reach of this Crownstone. If timestamp is not provided, current time is used.

await send_no_op()

Send an empty message into the mesh.

await set_ibeacon_uuid(crownstone_id: int, uuid: str, index: int = 0) -> MeshResult

crownstone_id: uid of the targeted Crownstone.

uuid: string like "d8b094e7-569c-4bc6-8637-e11ce4221c18"

index: 0 or 1

By default, the iBeacon config at index 0 is active. It is set by the Crownstone setup process. This method will set the iBeacon UUID on this specific Crownstone via the mesh. Returns a MeshResult class instance. Defined below.

await set_ibeacon_major(self, crownstone_id: int, major: int, index: int = 0) -> MeshResult:

crownstone_id: uid of the targeted Crownstone.

major: int 0 - 65535

index: 0 or 1

By default, the iBeacon config at index 0 is active. It is set by the Crownstone setup process. This method will set the iBeacon major on this specific Crownstone via the mesh. Returns a MeshResult class instance. Defined below.

await set_ibeacon_minor(self, crownstone_id: int, minor: int, index: int = 0) -> MeshResult:

crownstone_id: uid of the targeted Crownstone.

minor: int 0 - 65535

index: 0 or 1

By default, the iBeacon config at index 0 is active. It is set by the Crownstone setup process. This method will set the iBeacon minor on this specific Crownstone via the mesh. Returns a MeshResult class instance. Defined below.

await periodically_activate_ibeacon_index(self, crownstone_uid_array: List[int], index : int, interval_seconds: int, offset_seconds: int = 0) -> MeshResult:

crownstone_uid_array: array of Crownstone uids to target

index: 0 or 1

interval_seconds: every interval_seconds the ibeacon config at this index will be activated.

offset_seconds: if you set multiple intervals, you can use this offset to sync them up. These are based on the Crownstone time.

You need to have 2 stored ibeacon payloads (at index 0 and 1) in order for this to work. This can be done by the set_ibeacon methods available in this module.

Once the interval starts, it will set this ibeacon ID to be active. In order to have 2 ibeacon payloads interleaving, you have to call this method twice.
To interleave every minute
First,    periodically_activate_ibeacon_index, index 0, interval = 120 (2 minutes), offset = 0
Secondly, periodically_activate_ibeacon_index, index 1, interval = 120 (2 minutes), offset = 60

This will change the active ibeacon payload every minute:
T        = 0.............60.............120.............180.............240
activeId = 0.............1...............0...............1...............0
period_0 = |------------120s-------------|--------------120s-------------|

await stop_ibeacon_interval_and_set_index(self, crownstone_uid_array: List[int], index) -> MeshResult:

crownstone_uid_array: array of Crownstone uids to target

index: 0 or 1

If you have set an interval using the periodically_activate_ibeacon_index, this method will stop those intervals and the iBeacon config defined by index will be active for broadcasting after this method has completed.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

crownstone-uart-0.7.5.tar.gz (26.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

crownstone_uart-0.7.5-py3-none-any.whl (33.1 kB view details)

Uploaded Python 3

File details

Details for the file crownstone-uart-0.7.5.tar.gz.

File metadata

  • Download URL: crownstone-uart-0.7.5.tar.gz
  • Upload date:
  • Size: 26.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.4.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.7.6

File hashes

Hashes for crownstone-uart-0.7.5.tar.gz
Algorithm Hash digest
SHA256 02c69edbf263b83c3583d79fb7fa6aaf37308e80a30cb1e086c3f3bacbaf7023
MD5 c6562e2192c6b7e6788f86ea30552b07
BLAKE2b-256 f9216caa9779f7c63c64f7bbc60d5a7639b3d7fbf59085644e5366a6823e4ddd

See more details on using hashes here.

File details

Details for the file crownstone_uart-0.7.5-py3-none-any.whl.

File metadata

  • Download URL: crownstone_uart-0.7.5-py3-none-any.whl
  • Upload date:
  • Size: 33.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.4.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.7.6

File hashes

Hashes for crownstone_uart-0.7.5-py3-none-any.whl
Algorithm Hash digest
SHA256 da93085a24b42960f322bb2a387d243354f15eb4104e7c08ba10fe43f87af538
MD5 ab2163336bdbd7aabd25459914d36561
BLAKE2b-256 be92d96f1b0e5660d5c25a2028f499172c2f015c34407808c6e9b0b77ec72050

See more details on using hashes here.

Release history Release notifications | RSS feed

2.7.0

2 files

2.6.0

2 files

2.5.0

2 files

2.4.1

2 files

2.4.0

2 files

2.3.0

2 files

2.2.0

2 files

2.1.0

2 files

2.0.0

4 files

1.0.1

2 files

1.0.0

4 files

0.8.0

2 files

0.7.8

2 files

0.7.7

4 files

0.7.6

2 files

This release

0.7.5 This release

2 files

0.7.4

4 files

0.7.3

2 files

0.7.2

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.3

2 files

0.5.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page