Welcome to Tingbot’s documentation!ΒΆ

Contents:

TingbotΒΆ

Python APIs to write apps for Tingbot.

🌈 Graphics¢

DrawingΒΆ

screen.fill(color)ΒΆ

Fills the screen with the specified color.

The color option can be specified using a name (e.g. ‘white’, ‘black’), or an RGB triple.

Example: fill the screen with whiteΒΆ
screen.fill(color='white')
Example: fill the screen with redΒΆ
screen.fill(color=(255, 0, 0))
screen.text(string…, xy=…, color=…, align=…, font=…, font_size=…, max_width=…, max_lines=…, max_height=…)ΒΆ

Draws text string.

xy is the position that the text will be drawn.

The align option is one of:

topleft, left, bottomleft, top, center, bottom, topright, right, bottomright

If a custom font is used, it must be included in the tingapp bundle.

Example: Write ‘Hello world’ in black on the screenΒΆ
screen.text('Hello world!', color='black')
Example: changing the alignmentΒΆ
screen.text('Hello world!', xy=(20,20), color='black', align='topleft')
Example: Using a custom fontΒΆ
screen.text('Hello world!', color='black', font='Helvetica.ttf')
Example: Changing the text sizeΒΆ
screen.text('Hello world!', color='black', font_size=50)
Example: Confining text to a single lineΒΆ
screen.text('Lorem ipsum dolor sit amet, consectetur adipiscing elit!', color='black', max_lines=1)
Example: Confining text to two linesΒΆ
screen.text('Lorem ipsum dolor sit amet, consectetur adipiscing elit!', color='black', max_width=300, max_lines=2)
screen.rectangle(xy=…, size=…, color=…, align=…)ΒΆ

Draws a rectangle at position xy, with the specified size and color.

Align is one of

topleft, left, bottomleft, top, center, bottom, topright, right, bottomright,
Example: Drawing a red squareΒΆ
screen.rectangle(xy=(25,25), size=(100,100), color=(255,0,0))
Example: Drawing centeredΒΆ
screen.rectangle(xy=(160,120), size=(100,100), color=(255,0,0), align='center')
screen.image(filename…, xy=…, scale=…, align=…, max_width=…, max_height=…, raise_error=True)ΒΆ

Draws an image with name filename at position xy. If filename is a URL (e.g. http://example.com/cats.png) then it will attempt to download this and display it.

Images can be animated GIFs. Make sure to draw them in a loop() function to see them animate.

Scale is a number that changes the size of the image e.g. scale=2 makes the image bigger, scale=0.5 makes the image smaller. There are also special values ‘fit’ and ‘fill’, which will fit or fill the image according to max_width and max_height.

Align is one of

topleft, left, bottomleft, top, center, bottom, topright, right, bottomright

If raise_error is True then any errors encountered while opening or retrieving the image will cause an exception. If it is False, then if there is an error a “file not found” icon will be displayed instead

Example: Drawing an ImageΒΆ
screen.image('tingbot.png', xy=(25,25))
Example: Drawing an Image from a URLΒΆ
screen.image('http://i.imgur.com/xbT92Gm.png')
screen.line(start_xy=…, end_xy=…, color=…, width=…)ΒΆ

Draws a line between start_xy and end_xy.

ScreenΒΆ

The screen supports all the methods above, and some extras below.

screen.update()ΒΆ

After drawing, this method should to be called to refresh the screen. When drawing in a draw() or loop() function, this is called automatically, but when drawing in a tight loop, e.g. during a calculation, it can called manually.

Example: An app without a run loop - calling screen.update() manuallyΒΆ
import tingbot
from tingbot import *

screen.fill(color='black')

# pump the main run loop just once to make sure the app starts
tingbot.input.EventHandler().poll()

frame_count = 0

while True:
    screen.fill(color='black')
    screen.text(frame_count)
    screen.update()
    frame_count += 1
screen.brightnessΒΆ

The brightness of the screen, between 0 and 100.

Example: Dimming the screenΒΆ
screen.brightness = 25
Example: Brightness test appΒΆ
import tingbot
from tingbot import *

state = {'brightness': 0}

def loop():
    screen.brightness = state['brightness']

    screen.fill(color='black')
    screen.text('Brightness\n %i' % state['brightness'])

    state['brightness'] += 1

    if state['brightness'] > 100:
        state['brightness'] = 0

tingbot.run(loop)

The align optionΒΆ

When used without the xy parameter, the item is positioned relative to the screen/drawing surface.

Setting Screenshot Code
topleft _images/topleft.png screen.rectangle(color='green', align='topleft')
top _images/top.png screen.rectangle(color='green', align='top')
topright _images/topright.png screen.rectangle(color='green', align='topright')
left _images/left.png screen.rectangle(color='green', align='left')
center _images/center.png screen.rectangle(color='green', align='center')
right _images/right.png screen.rectangle(color='green', align='right')
bottomleft _images/bottomleft.png screen.rectangle(color='green', align='bottomleft')
bottom _images/bottom.png screen.rectangle(color='green', align='bottom')
bottomright _images/bottomright.png screen.rectangle(color='green', align='bottomright')

When used with the xy parameter, it positions the item relative to the xy point.

Setting Screenshot Code
topleft _images/topleft1.png screen.rectangle(xy=(160, 120), align='topleft')
top _images/top1.png screen.rectangle(xy=(160, 120), align='top')
topright _images/topright1.png screen.rectangle(xy=(160, 120), align='topright')
left _images/left1.png screen.rectangle(xy=(160, 120), align='left')
center _images/center1.png screen.rectangle(xy=(160, 120), align='center')
right _images/right1.png screen.rectangle(xy=(160, 120), align='right')
bottomleft _images/bottomleft1.png screen.rectangle(xy=(160, 120), align='bottomleft')
bottom _images/bottom1.png screen.rectangle(xy=(160, 120), align='bottom')
bottomright _images/bottomright1.png screen.rectangle(xy=(160, 120), align='bottomright')

The color optionΒΆ

The color option can be either an RGB value, or predefined color name.

RGB valuesΒΆ

RGB values (as a tuple), like (255, 128, 0).

Predefined colorsΒΆ

We also have a set of default colors, referred to by their name, as a string.

'navy' (0, 116, 217)
'blue' (0, 116, 217)
'aqua' (127, 219, 255)
'teal' (57, 204, 204)
'olive' (61, 153, 112)
'green' (46, 204, 64)
'lime' (1, 255, 112)
'yellow' (255, 220, 0)
'orange' (255, 133, 27)
'red' (255, 65, 54)
'maroon' (133, 20, 75)
'fuchsia' (240, 18, 190)
'purple' (177, 13, 201)
'black' (0, 0, 0)
'gray' (170, 170, 170)
'silver' (221, 221, 221)
'white' (255, 255, 255)

Thanks to http://clrs.cc for the color scheme!

πŸ‘ˆ TouchΒΆ

Your Tingbot comes equipped with a resistive touch screen! It’s easy to react to touch events.

Example: Simple drawing appΒΆ
import tingbot
from tingbot import *

screen.fill(color='black')

@touch()
def on_touch(xy):
    screen.rectangle(xy=xy, size=(5,5), color='blue')

tingbot.run()

This is a simple drawing app. It uses the @touch() decorator to receive touch events and draws a rectangle to the screen at the same place.

@touch(xy=…, size=…, align=…)

This ‘decorator’ marks the function after it to receive touch events.

You can optionally pass an area that you’re interested in, using the xy, size and align arguments. If you specify no area, you will receive all touch events.

The handler function can optionally take the arguments xy and action. xy is the location of the touch. action is one of ‘down’, ‘move’, ‘up’.

Example: Simple Drawing app codeΒΆ
@touch()
def on_touch(xy):
    screen.rectangle(xy=xy, size=(5,5), color='blue')
Example: Making a button do somethingΒΆ
@touch(xy=(0,0), size=(100,50), align='topleft')
def on_touch(xy, action):
    if action == 'down':
        state['screen_number'] = 2

◽️ ️ButtonsΒΆ

There are four buttons on the top of the Tingbot. These can be used in programs to trigger functions in your code.

Example: Score-keeping app.ΒΆ
import tingbot
from tingbot import *

state = {'score': 0}

@left_button.press
def on_left():
    state['score'] -= 1

@right_button.press
def on_right():
    state['score'] += 1

def loop():
    screen.fill(
        color='black')
    screen.text(
        state['score'],
        color='white')

tingbot.run(loop)

This is a simple counter program. Whenever the right button is pressed, the score goes up by one. On the left button, the score goes down.

@left_button.pressΒΆ
@midleft_button.pressΒΆ
@midright_button.pressΒΆ
@right_button.pressΒΆ

This ‘decorator’ marks the function to be called when a button is pressed.

button can be one of: left_button, midleft_button, midright_button, right_button.

Example: Button handlerΒΆ
@left_button.press
def on_left():
    state['score'] -= 1
Example: Button handler for all buttonsΒΆ
@left_button.press
@midleft_button.press
@midright_button.press
@right_button.press
def on_button():
    state['score'] -= 1

Only presses shorter than a second count - anything longer counts as a ‘hold’ event.

@Button.holdΒΆ

This marks the function to be called when a button is held down for longer than a second.

Example: Reset button handlerΒΆ
@left_button.hold
def reset_score():
    state['score'] = 0
@Button.downΒΆ

This marks the function to be called as soon as a button is pushed down. This could be the start of a ‘press’ or a ‘hold’ event.

This one is useful for games or when you want the button to be as responsive as possible.

Example: Reset button handlerΒΆ
@right_button.down
def jump():
    dude.jump()
@Button.upΒΆ

This marks the function to be called when a button is released.

Example: Down/up handler pairΒΆ
@right_button.down
def down():
    state['button_is_down'] = True

@right_button.up
def up():
    state['button_is_down'] = False
@button.combo(buttons...)ΒΆ

This marks the function to be called when some buttons are pressed at the same time.

You can give it as many buttons as you like and combo will call the function when all the buttons are pressed together.

Example: Combo to dim/wake the screenΒΆ
@button.combo(left_button, right_button)
def screen_dim():
    if screen.brightness == 100:
        screen.brightness = 0
    else:
        screen.brightness = 100

⚑️ Webhooks¢

You can push data to Tingbot using webhooks.

Here is an example that displays SMS messages using If This Then That. See our tutorial video to see how to set up IFTTT with webhooks.

import tingbot
from tingbot import *

screen.fill(color='black')
screen.text('Waiting...')

@webhook('demo_sms')
def on_webhook(data):
    screen.fill(color='black')
    screen.text(data, color='green')

tingbot.run()
@webhook(webhook_name…)ΒΆ

This decorator calls the marked function when a HTTP POST request is made to the URL http://webhook.tingbot.com/webhook_name. To avoid choosing the same name as somebody else, you can add a random string of characters to the end.

The POST data of the URL is available to the marked function as the data parameter. The data is limited to 1kb, and the last value that was POSTed is remembered by the server, so you can feed in relatively slow data sources.

You can use webhooks to push data to Tingbot, or to notify Tingbot of an update that happened elsewhere on the internet.

Hint

IFTTT is a great place to start for ideas for webhooks. Slack also has native support for webhooks!

β˜‘οΈ SettingsΒΆ

You can store local data on the tingbot. Simply use tingbot.app.settings as a dict. This will store any variables you like on a file in the application directory (called local_settings.json). This is stored in JSON format.

import tingbot

#store an item
tingbot.app.settings['favourite_colour'] = 'red'

#local_settings.json on disk now contains: {"favourite_colour":"red"}

#retrieve an item
tingbot.screen.fill(tingbot.app.settings['favourite_colour'])

Any item that can be stored in JSON can be used in tingbot.app.settings - so strings, ints, floats, even dicts and lists can be used.

Note

Take care when changing the insides of dicts or lists that are stored in tingbot.app.settings, as your changes will not be saved automatically.

You can force a save by calling tingbot.app.settings.save()

import tingbot

# create a sub-dictionary
tingbot.app.settings['ages'] = {'Phil': 39, 'Mabel': 73}

# local_settings.json on disk now contains: {"ages":{"Phil":39,"Mabel":73}}

tingbot.app.settings['ages']['Barry'] = 74

# warning: local_settings.json has not been updated because you haven't directly changed tingbot.app.settings

tingbot.app.settings.save()

# now local_settings.json on disk now contains: {"ages":{"Phil":39,"Mabel":73,"Barry":74}}

StorageΒΆ

There are three settings files, that have different uses:

  • default_settings.json When writing your app, you can put default values for your settings in this file.
  • settings.json Somebody who’s downloaded your app can create this file in Tide to fill in some settings before uploading to Tingbot. This file should be ‘gitignored’ so it’s not shared when the app is copied, and can contain secrets like API keys or passwords.
  • local_settings.json When code within the app sets a setting, it’s stored in this file. This prevents the app from overwriting data from the previous two files. This shouldn’t be copied with an app and should be ‘gitignored’ too.

When the first setting is accessed the app loads each file in turn, so values in ‘local_settings’ override those in ‘settings’, which override those is ‘default_settings’.

⏱ Run loop¢

Tingbot has an internal run loop that it uses to schedule events.

tingbot.run(loop=None)ΒΆ

This function starts the run loop.

The optional loop function is called every 1/30th seconds.

@every(hours=0, minutes=0, seconds=0)ΒΆ

This decorator will call the function marked periodically, according to the time specified.

Example: Refreshing data every 10 minutesΒΆ
@every(minutes=10)
def refresh_data():
    r = requests.get('http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=bd82977b86bf27fb59a04b61b657fb6f')
    state['data'] = r.json()
@once(hours=0, minutes=0, seconds=0)ΒΆ

This decorator will call the function marked once, after the duration specified.

tingbot.RunLoop.call_after(callable)ΒΆ

Call function callable at the next possible moment from the run loop. This allows threads to communicate with the main run loop in a thread-safe fashion

πŸ“Ÿ HardwareΒΆ

There are several useful functions that can be used to see if hardware is connected to the tingbot.

get_ip_address()ΒΆ

Returns the IP address of the tingbot or None if it is not connected.

get_wifi_cell()ΒΆ

Returns a WifiCell object (or None if there is no wifi adapter).

A WifiCell object has the following attributes:

  • ssid
  • link_quality
  • signal_level
mouse_attached()ΒΆ

Returns True if a mouse is attached

keyboard_attached()ΒΆ

Returns True if a keyboard is attached

joystick_attached()ΒΆ

Returns True if a joystick is attached

πŸ”Š SoundsΒΆ

If you plug in a USB audio device into your Tingbot, you can play sounds.

Example: Simple sounds appΒΆ
import tingbot
from tingbot import *

sound = Sound('car_chirp.wav')

@left_button.press
def on_press():
    sound.play()

@every(seconds=1.0/30)
def draw():
    screen.fill(color='black')
    screen.text('Press the left button to play a sound.')

tingbot.run()
class Sound(filename)ΒΆ

Loads a sound ready for playing. Currently WAV and OGG files are supported.

play(loop=False)ΒΆ

Starts the playback of the sound.

Parameters:loop (bool) – Pass True to loop the sound until stop() is called.
stop()ΒΆ

Stops the sound.

Full referenceΒΆ

Indices and tablesΒΆ