コード例 #1
0
 def __init__(self, mac, image_dir):
     from timebox import TimeBox
     self._mac = mac
     self._image_dir = image_dir
     self._timebox = TimeBox()
     self._timebox.connect(host=mac)
     if not os.path.isdir(image_dir):
         _LOGGER.error(
             "image_dir {0} does not exist, timebox will not work".format(
                 image_dir))
     from timeboximage import TimeBoxImage
     self._state_image = TimeBoxImage()
     self.display_image_file('ha-logo')
コード例 #2
0
        self.matrix = self._transpose_matrix(new_matrix)

    def iterate(self):
        """Perform one iteration of Jacobi's method."""
        row, column, theta = self._select_pivot()
        srot, crot = sin(theta), cos(theta)
        # update columns according to the rotation
        self._rotate_column(row, column, srot, crot)
        # update rows according to the rotation
        self._rotate_row(row, column, srot, crot)
        return self.theta()


JACOBI = JacobiIteration()

# create the Timebox object
TIMEBOX = TimeBox()
# open the connection to the Timebox
TIMEBOX.connect()

while True:
    JACOBI.randomize_matrix()

    THETA = 1
    while abs(THETA) > 0.05:
        THETA = JACOBI.iterate()
        IMAGE = JACOBI.as_image()
        TIMEBOX.set_static_image(IMAGE)
        sleep(0.5)
        TIMEBOX.clear_input_buffer()
コード例 #3
0
ファイル: loadgif.py プロジェクト: roflcoopter/timebox
"""Load a gif file and display it on TimeBox."""

import sys
from timeboximage import TimeBoxImage
from timebox import TimeBox
from gifreader import GIFReader

if len(sys.argv) < 2:
    print('Please provide name of a GIF file to display.')
    exit()

FILENAME = sys.argv[1]

GIFREADER = GIFReader()
GIFREADER.read(FILENAME)

IMAGE = TimeBoxImage()
for xix in range(11):
    for yix in range(11):
        IMAGE.put_pixel(xix, yix, GIFREADER.output_image[xix][yix][0] >> 4, \
                            GIFREADER.output_image[xix][yix][1] >>4, \
                            GIFREADER.output_image[xix][yix][2]>>4)

TIMEBOX = TimeBox()
TIMEBOX.connect()
TIMEBOX.set_static_image(IMAGE)
TIMEBOX.close()
コード例 #4
0
ファイル: trace.py プロジェクト: roflcoopter/timebox
            print('Garbage: ', TIMEBOX.remove_garbage())
        else:
            rec = TIMEBOX.remove_message()
            dec = TIMEBOX.decode(rec)
            if dec[0:5] == 'error':
                print(dec, rec)
            else:
                decb = [c for c in dec]
                print('Rec: ', ' '.join('{:02X}'.format(k, 'x') for k in decb))
        TIMEBOX.receive()


TRACE = [
    ["set view", [0x01, 0x00, 0x00, 0xff, 0x00]],
    ["switch radio", [0x01]],
    ["set view", [0x00, 0x01, 0x00, 0x00, 0xff]],
    ["switch radio", [0x00]],
]

TIMEBOX = TimeBox()
TIMEBOX.connect()

receive_timebox()

for cmd in TRACE:
    TIMEBOX.send_command(cmd[0], cmd[1])
    sleep(1.5)
    receive_timebox()

TIMEBOX.close()
コード例 #5
0
ファイル: gameoflife.py プロジェクト: roflcoopter/timebox
""" Test TimeBox interface"""
from time import sleep
from timebox import TimeBox
from life import GameOfLife

TIMEBOX = TimeBox()
TIMEBOX.connect()

GOL = GameOfLife()
GOL.randomize_board()

while True:
    GOL.randomize_board()
    for i in range(100):
        for j in range(GOL.animationSteps):
            TIMEBOX.set_static_image(GOL.as_image(j))
            sleep(0.04)
        old_board = GOL.board
        GOL.iterate()
        TIMEBOX.clear_input_buffer_quick()
        if old_board == GOL.board:
            sleep(4.0)
            break

TIMEBOX.close()
コード例 #6
0
ファイル: sendanim.py プロジェクト: roflcoopter/timebox
""" Test TimeBox interface"""
#import sys
import random
from timeboximage import TimeBoxImage
from timebox import TimeBox

IMAGES = []

TIMEBOX = TimeBox()

# create some image

for i in range(10):
    IMAGE = TimeBoxImage()
    rand_r = random.randrange(0, 16)
    rand_g = random.randrange(0, 16)
    rand_b = random.randrange(0, 16)
    IMAGE.put_pixel(random.randrange(0, 11), random.randrange(0, 11), rand_r,
                    rand_g, rand_b)
    IMAGES.append(IMAGE)

TIMEBOX.connect()
FRAME_DELAY = 5
TIMEBOX.set_dynamic_images(IMAGES, FRAME_DELAY)
TIMEBOX.close()
コード例 #7
0
ファイル: gameoflife.py プロジェクト: jbfuzier/timebox
""" Test TimeBox interface"""
from time import sleep
from timebox import TimeBox
from life import GameOfLife

TIMEBOX = TimeBox()
TIMEBOX.connect()

GOL = GameOfLife()
GOL.randomize_board()

while True:
    GOL.randomize_board()
    for i in range(100):
        for j in range(GOL.animationSteps):
            TIMEBOX.set_static_image(GOL.as_image(j))
            sleep(0.04)
        GOL.iterate()

TIMEBOX.close()

コード例 #8
0
class TimeBoxNotificationService(BaseNotificationService):
    """Implement the notification service for TimeBox."""
    def __init__(self, mac, image_dir):
        from timebox import TimeBox
        self._mac = mac
        self._image_dir = image_dir
        self._timebox = TimeBox()
        self._timebox.connect(host=mac)
        if not os.path.isdir(image_dir):
            _LOGGER.error(
                "image_dir {0} does not exist, timebox will not work".format(
                    image_dir))
        from timeboximage import TimeBoxImage
        self._state_image = TimeBoxImage()
        self.display_image_file('ha-logo')

    def display_image_file(self, fn):
        image_data = self.load_image_file(fn)
        if image_data is not None:
            self.display_image(image_data)

    def display_image(self, image_data):
        if self.valid_image(image_data):
            from timeboximage import TimeBoxImage
            image = TimeBoxImage()
            image.image = image_data
            self._timebox.set_static_image(image)
        else:
            _LOGGER.error("Invalid image data received")

    def valid_color(self, color):
        """Verifies a color is valid
        (Array of three ints, range 0-15)"""
        valid = False
        if (isinstance(color, list) and len(color) == 3):
            valid = True
            for chan in color:
                valid = valid and (0 <= chan <= 15)
        if not valid:
            _LOGGER.warn("{0} was not a valid color".format(color))
        return valid

    def valid_image(self, image):
        """Verifies an image array is valid.
        An image should consist of a 2D array, 11x11. Each array
        element is again an arry, containing a valid colour
        (see valid_color())."""
        valid = False
        if (isinstance(image, list) and len(image) == 11):
            valid = True
            for row in image:
                if (isinstance(row, list) and len(row) == 11):
                    for pixel in row:
                        if not self.valid_color(pixel):
                            valid = False
                            break
                else:
                    valid = False
                    break
        if not valid:
            _LOGGER.error("Invalid image data received")
        return valid

    def load_image_file(self, image_file_name):
        """Loads image data from a file and returns it."""
        fn = os.path.join(self._image_dir, "{0}.json".format(image_file_name))
        try:
            fh = open(fn)
        except:
            _LOGGER.error("Unable to open {0}".format(fn))
            return None
        try:
            image = json.load(fh)
            return image
        except Exception as e:
            _LOGGER.error(
                "{0} does not contain a valid image in JSON format".format(fn))
            _LOGGER.error(e)
            return None

    def convert_color(self, color):
        """We expect all colors passed in to be in the range 0-15.
        But some parts of the timebox API expect 0-255. This function
        converts a passed in color array to something the API can
        work with. Does not do validation itself."""
        return [color[0] * 16, color[1] * 16, color[2] * 16]

    def send_message(self, message="", **kwargs):
        if kwargs.get(ATTR_DATA) is None:
            _LOGGER.error("Service call needs a message type")
            return False
        data = kwargs.get(ATTR_DATA)
        mode = data.get(PARAM_MODE)
        # HA used to internally cast "off" to a boolean False.
        # Apparently it doesn't any more?
        if mode == False or mode == 'off':
            self.display_image_file('blank')

        elif mode == "clock":
            color = data.get(PARAM_COLOR)
            if self.valid_color(color):
                color = self.convert_color(color)
            else:
                color = [255, 255, 255]
            self._timebox.show_clock(color=color)

        elif mode == "temp":
            color = data.get(PARAM_COLOR)
            if self.valid_color(color):
                color = self.convert_color(color)
            else:
                color = [255, 255, 255]
            self._timebox.show_temperature(color=color)

        elif mode == "image":
            image_data = data.get(PARAM_IMAGE)
            self.display_image(image_data)

        elif mode == "image-file":
            image_filename = data.get(PARAM_FILE_NAME)
            self.display_image_file(image_filename)

        elif mode == "sync-clock":
            dt = datetime.datetime.now()
            head = [
                0x0A, 0x00, 0x18, dt.year % 100,
                int(dt.year / 100), dt.month, dt.day, dt.hour, dt.minute,
                dt.second
            ]
            self._timebox.send_payload(head)

        elif mode == "show-states":
            self._timebox.set_static_image(self._state_image)

        elif mode == "set-state":
            color = data.get(PARAM_COLOR)
            x = data.get(PARAM_X)
            y = data.get(PARAM_Y)
            show_state = data.get(PARAM_SHOW_STATE)
            self._state_image.put_pixel(x, y, color[0], color[1], color[2])
            if show_state == True:
                self._timebox.set_static_image(self._state_image)

        elif mode == "set-state-lerp":
            x = data.get(PARAM_X)
            x = int(x)
            y = data.get(PARAM_Y)
            y = int(y)
            _LOGGER.info("x: " + str(x) + " y:" + str(y))
            start_color = data.get(PARAM_START_COLOR)
            end_color = data.get(PARAM_END_COLOR)
            start_color = [int(x) for x in start_color]
            end_color = [int(x) for x in end_color]

            value = data.get(PARAM_VALUE)
            value = float(value)
            min_value = data.get(PARAM_MIN_VALUE)
            min_value = float(min_value)
            max_value = data.get(PARAM_MAX_VALUE)
            max_value = float(max_value)
            _LOGGER.debug("val: " + str(value) + " min:" + str(min_value) +
                          " max:" + str(max_value))
            _LOGGER.debug("start_col: " + str(start_color) + " end: " +
                          str(end_color))

            show_state = data.get(PARAM_SHOW_STATE)
            color = calculate_lerp_color(start_color, end_color, value,
                                         min_value, max_value)
            _LOGGER.info("calc_col: " + str(color))

            self._state_image.put_pixel(x, y, color[0], color[1], color[2])
            if show_state == True or show_state.lower() == "true":
                self._timebox.set_static_image(self._state_image)

        elif mode == "animation":
            # TODO
            pass

        else:
            _LOGGER.error(
                "Invalid mode '{0}', must be one of 'off', 'clock', 'temp', 'image', 'animation'"
                .format(mode))
            return False

        return True