Code Monkey home page Code Monkey logo

xled's Introduction

XLED - unofficial control of Twinkly - Smart Decoration LED lights

XLED is a python library and command line interface (CLI) to control Twinkly - Smart Decoration LED lights for Christmas.

Official materials says:

Twinkly is a LED light device that you can control via smartphone. It allows you to play with colouful and animated effects, or create new ones. Decoration lights, not suitable for household illumination.

Since its Kickstarter project in 2016 many products were introduced with varying properties and features. Most notably products released since September 2019 are identified as Generation II. Older products are since then referred as Generation I.

Library and CLI are free software available under MIT license.

Installation

Both library and CLI tool are supported on Linux, primarily Fedora.

  1. First make sure that you have pip installed. E.g. for Fedora:

    $ sudo dnf install python3-pip python3-wheel
    
  2. You might want to create and activate a virtual environment. E.g.:

    $ mkdir -p ~/.virtualenvs
    $ python3 -m venv ~/.virtualenvs/xled
    $ source ~/.virtualenvs/xled/bin/activate
    
  3. Install xled from PyPI:

    $ python3 -m pip install --upgrade xled
    

Usage

If you have installed the project into virtual environment, activate it first. E.g.

$ source ~/.virtualenvs/xled/bin/activate

Use of the library:

>>> import xled
>>> discovered_device = xled.discover.discover()
>>> discovered_device.id
'Twinkly_33AAFF'
>>> control = xled.ControlInterface(discovered_device.ip_address, discovered_device.hw_address)
>>> control.set_mode('movie')
<ApplicationResponse [1000]>
>>> control.get_mode()['mode']
'movie'
>>> control.get_device_info()['number_of_led']
210

Documentation for the library can be found online.

Use of the CLI:

$ xled on
Looking for any device...
Working on device: Twinkly_33AAFF
Turned on.

For more commands and options see xled --help.

Why?

My first Twinkly was 105 LEDs starter light set. That was the latest available model in 2017: TW105S-EU. As of December 2017 there are only two ways to control lights: mobile app on Android or iOS or hardware button on the cord.

Android application didn't work as advertised on my Xiaomi Redmi 3S phone. On first start it connected and disconnected in very fast pace (like every 1-2 seconds) to the hardware. I wasn't able to control anything at all. Later I wanted to connect it to my local WiFi network. But popup dialog that shouldn't have appear never did so.

Public API was promised around Christmas 2016 for next season. Later update from October 2016 it seems API won't be available any time soon:

API for external control are on our dev check list, we definitely need some feedback from the community to understand which could be a proper core set to start with.

It turned out that application uses HTTP to control lights. I ended up with capturing network traffic and documented this private API. In the end I'm able to configure the device pretty easilly.

As of 2020 Twinkly devices can be controlled by Amazon Alexa and Google Assistant as well. Mobile application now requires an account to operate lights even locally. No sign of public API for local devices though. Therefore with my second device - Twinkly 210 RGB+W Wall I keep improving this library and CLI documentation to be able to operate my devices locally and not rely on availability of manufacturer's servers.

Related projects

Unofficial documentation of private protocol and API is available online.

For other projects that might be more suitable for your needs see section client implementations in xled-docs.

Credits

This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.

Join the chat at https://gitter.im/xled-community/chat

xled's People

Contributors

anders-holst avatar gitter-badger avatar kamalmostafa avatar magicus avatar musl avatar pyup-bot avatar rec avatar scrool avatar timon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xled's Issues

Discovery when multiple interfaces are present

This might be related to #61

I'd like to use xled with Home Assistant, and for that I consder using autodiscovery.
My setup is Raspberry PI which is connected to home automation WiFi. and also a regular ethernet, and Twinkly that is registered in the home automation WiFi.

It appears to me that the discovery process is running only on one interface: if both interfaces are up, xled.discover.discover() takes a long time (and I have stopped it with ^C). Unplugging the ethernet cord resulted in a quick response from my twinkly.

I think that the discoverer should try all running interfaces.

P.S. I could try implementing this myself if you could provide me with outline how this could be achieved

get_mode() always returns ApplicationResponse[None]

Trying to create a toggle function but in order to do this, need to get the current state. I am able to set_mode('movie') or set_mode('off'), but unable to read the state.

`import os
import xled

hosts = ['192.168.2.196']

for host in hosts:
response = os.system('ping ' + host + ' -n 1 -w 250|find /i "TTL=" /c')
if response == 0:
print('Checking ' + host + '...')
control = xled.ControlInterface(host)
print(control.get_mode())
`
returns:
Checking 192.168.2.196...
<ApplicationResponse [None]>

interactive in Python 2.7 brings the same "None" response as well.

If mac address isn't in cache, gets stuck in loop

(.venv) m@spore:~/go/src/github.com/scrool/xled$ xled --verbosity-auth DEBUG --verbosity-discover DEBUG --verbosity-control DEBUG --hostname 192.168.4.33 get-mode
Looking for device with address: 192.168.4.33...
DEBUG:xled.discover:Sending ping
DEBUG:xled.discover:Waiting for a beacon.
DEBUG:xled.discover:Ignoring ping message received from network from 192.168.4.21.
DEBUG:xled.discover:Waiting for a beacon.
DEBUG:xled.discover:Received a beacon from 192.168.4.38.
DEBUG:xled.discover:Received b'&\x04\xa8\xc0OKTwinkly_36DE85\x00'
DEBUG:xled.discover:Getting hardware address of b'192.168.4.38'.
ERROR:asyncio:Exception in callback BaseAsyncIOLoop._handle_events(20, 1)
handle: <Handle BaseAsyncIOLoop._handle_events(20, 1)>
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/home/m/go/src/github.com/scrool/xled/.venv/lib/python3.8/site-packages/tornado/platform/asyncio.py", line 189, in _handle_events
    handler_func(fileobj, events)
  File "/home/m/go/src/github.com/scrool/xled/xled/discover.py", line 465, in handle_beacon
    hw_address = bytes(hw_address, "utf-8")
TypeError: encoding without a string argument
DEBUG:xled.discover:Waiting for a beacon.
DEBUG:xled.discover:Received a beacon from 192.168.4.39.
DEBUG:xled.discover:Received b"'\x04\xa8\xc0OKTwinkly_396D45\x00"
DEBUG:xled.discover:Getting hardware address of b'192.168.4.39'.
ERROR:asyncio:Exception in callback BaseAsyncIOLoop._handle_events(20, 1)
handle: <Handle BaseAsyncIOLoop._handle_events(20, 1)>
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/home/m/go/src/github.com/scrool/xled/.venv/lib/python3.8/site-packages/tornado/platform/asyncio.py", line 189, in _handle_events
    handler_func(fileobj, events)
  File "/home/m/go/src/github.com/scrool/xled/xled/discover.py", line 465, in handle_beacon
    hw_address = bytes(hw_address, "utf-8")
TypeError: encoding without a string argument
DEBUG:xled.discover:Waiting for a beacon.
DEBUG:xled.discover:Received a beacon from 192.168.4.43.
DEBUG:xled.discover:Received b'+\x04\xa8\xc0OKTwinkly_3C5095\x00'
DEBUG:xled.discover:Getting hardware address of b'192.168.4.43'.
ERROR:asyncio:Exception in callback BaseAsyncIOLoop._handle_events(20, 1)
handle: <Handle BaseAsyncIOLoop._handle_events(20, 1)>
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/home/m/go/src/github.com/scrool/xled/.venv/lib/python3.8/site-packages/tornado/platform/asyncio.py", line 189, in _handle_events
    handler_func(fileobj, events)
  File "/home/m/go/src/github.com/scrool/xled/xled/discover.py", line 465, in handle_beacon
    hw_address = bytes(hw_address, "utf-8")
TypeError: encoding without a string argument
DEBUG:xled.discover:Waiting for a beacon.
DEBUG:xled.discover:Received a beacon from 192.168.4.40.
DEBUG:xled.discover:Received b'(\x04\xa8\xc0OKTwinkly_35F259\x00'
DEBUG:xled.discover:Getting hardware address of b'192.168.4.40'.
ERROR:asyncio:Exception in callback BaseAsyncIOLoop._handle_events(20, 1)
handle: <Handle BaseAsyncIOLoop._handle_events(20, 1)>
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/home/m/go/src/github.com/scrool/xled/.venv/lib/python3.8/site-packages/tornado/platform/asyncio.py", line 189, in _handle_events
    handler_func(fileobj, events)
  File "/home/m/go/src/github.com/scrool/xled/xled/discover.py", line 465, in handle_beacon
    hw_address = bytes(hw_address, "utf-8")
TypeError: encoding without a string argument
DEBUG:xled.discover:Waiting for a beacon.
DEBUG:xled.discover:Received a beacon from 192.168.4.36.
DEBUG:xled.discover:Received b'$\x04\xa8\xc0OKTwinkly_36FC01\x00'
DEBUG:xled.discover:Getting hardware address of b'192.168.4.36'.
ERROR:asyncio:Exception in callback BaseAsyncIOLoop._handle_events(20, 1)
handle: <Handle BaseAsyncIOLoop._handle_events(20, 1)>
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/home/m/go/src/github.com/scrool/xled/.venv/lib/python3.8/site-packages/tornado/platform/asyncio.py", line 189, in _handle_events
    handler_func(fileobj, events)
  File "/home/m/go/src/github.com/scrool/xled/xled/discover.py", line 465, in handle_beacon
    hw_address = bytes(hw_address, "utf-8")
TypeError: encoding without a string argument
DEBUG:xled.discover:Waiting for a beacon.
DEBUG:xled.discover:Received a beacon from 192.168.4.32.
DEBUG:xled.discover:Received b' \x04\xa8\xc0OKTwinkly_377851\x00'
DEBUG:xled.discover:Getting hardware address of b'192.168.4.32'.
ERROR:asyncio:Exception in callback BaseAsyncIOLoop._handle_events(20, 1)
handle: <Handle BaseAsyncIOLoop._handle_events(20, 1)>
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/home/m/go/src/github.com/scrool/xled/.venv/lib/python3.8/site-packages/tornado/platform/asyncio.py", line 189, in _handle_events
    handler_func(fileobj, events)
  File "/home/m/go/src/github.com/scrool/xled/xled/discover.py", line 465, in handle_beacon
    hw_address = bytes(hw_address, "utf-8")
TypeError: encoding without a string argument
DEBUG:xled.discover:Waiting for a beacon.
DEBUG:xled.discover:Received a beacon from 192.168.4.42.
DEBUG:xled.discover:Received b'*\x04\xa8\xc0OKTwinkly_35E54D\x00'
DEBUG:xled.discover:Getting hardware address of b'192.168.4.42'.
ERROR:asyncio:Exception in callback BaseAsyncIOLoop._handle_events(20, 1)
handle: <Handle BaseAsyncIOLoop._handle_events(20, 1)>
Traceback (most recent call last):
  File "/usr/lib/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/home/m/go/src/github.com/scrool/xled/.venv/lib/python3.8/site-packages/tornado/platform/asyncio.py", line 189, in _handle_events
    handler_func(fileobj, events)
  File "/home/m/go/src/github.com/scrool/xled/xled/discover.py", line 465, in handle_beacon
    hw_address = bytes(hw_address, "utf-8")
TypeError: encoding without a string argument
DEBUG:xled.discover:Sending ping
DEBUG:xled.discover:Waiting for a beacon.
DEBUG:xled.discover:Ignoring ping message received from network from 192.168.4.21.
DEBUG:xled.discover:Waiting for a beacon.
DEBUG:xled.discover:Received a beacon from 192.168.4.36.
DEBUG:xled.discover:Received b'$\x04\xa8\xc0OKTwinkly_36FC01\x00'
DEBUG:xled.discover:Getting hardware address of b'192.168.4.36'.
ERROR:asyncio:Exception in callback BaseAsyncIOLoop._handle_events(20, 1)
handle: <Handle BaseAsyncIOLoop._handle_events(20, 1)>
Traceback (most recent call last):

I suspect this is only an issue on Py3 - the checks here are in the wrong order, PR to follow

Discovery doesn't work on python 3

Trying to use discovery with CLI ends up in loop tracebacks:

$ xled off
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib64/python3.4/threading.py", line 911, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.4/threading.py", line 859, in run
    self._target(*self._args, **self._kwargs)
  File "…/xled/xled/discover.py", line 278, in start
    pc.start()
  File "…/.virtualenvs/[email protected]/lib/python3.4/site-packages/tornado-5.1.1-py3.4-linux-x86_64.egg/tornado/ioloop.py", line 1206, in start
    self.io_loop = IOLoop.current()
  File "…/.virtualenvs/[email protected]/lib/python3.4/site-packages/tornado-5.1.1-py3.4-linux-x86_64.egg/tornado/ioloop.py", line 282, in current
    loop = asyncio.get_event_loop()
  File "/usr/lib64/python3.4/asyncio/events.py", line 626, in get_event_loop
    return get_event_loop_policy().get_event_loop()
  File "/usr/lib64/python3.4/asyncio/events.py", line 572, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'Thread-1'.

^C
Aborted!

How to send messages in `rt` mode?

The reverse engineered documentation of the Twinkly API talks about an operating mode "rt - receive effect in real time".

This is intriguing but the API doesn't seem to have any way to actually send the data.

(If you were to point me in approximately the right direction, I could probably send you a pull request to accomplish this...)

Problem command line to work

UPDATE:
IGNORE THIS ...

In the docs you show a command line example as
xled on

I can see the various command line options in cli.py but am missing a way to invoke them.
I have made a small Python launcher that calls cli.main but not seeing any output, including when using obviously bad command line parameters.

Is there a helper/wrapper to make it easy for the cli to be used?

Edit:
I did try
python3 cli.py on
first.
I put some print statements in it to show that it is launched ... they came out ... but no sign of the command line being processed.

Edit2:
Looks like I had to logout / login to get the xled shim available ... I guess it was not in the path before and is now. So now I can type
xled on
and it works.
Thanks.

Automatically authenticate known auth-required API calls

I know that most of rest API calls require authentication. Due the way how requests auth handler is written request to get auth token is done only after HTTP 403 Forbidden is received.

Make it possible to login first. One HTTP round-trip less.

Validation error

Summary

I'am running the latest Raspberry Pi OS and a fresh Python3.7 venv. When I try xled on I get this validation error:

xled on
Looking for any device...
Working on device: b'Twinkly_EBEA99'
ERROR:xled.auth:challenge-response invalid. Received challenge-response: '4b8af...' but '0fdb2...' was expected.
Traceback (most recent call last):
  File "/home/pi/xledvenv/bin/xled", line 10, in <module>
    sys.exit(main())
  File "/home/pi/xledvenv/lib/python3.7/site-packages/click/core.py", line 1137, in __call__
    return self.main(*args, **kwargs)
  File "/home/pi/xledvenv/lib/python3.7/site-packages/click/core.py", line 1062, in main
    rv = self.invoke(ctx)
  File "/home/pi/xledvenv/lib/python3.7/site-packages/click/core.py", line 1668, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/pi/xledvenv/lib/python3.7/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/pi/xledvenv/lib/python3.7/site-packages/click/core.py", line 763, in invoke
    return __callback(*args, **kwargs)
  File "/home/pi/xledvenv/lib/python3.7/site-packages/click/decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/pi/xledvenv/lib/python3.7/site-packages/xled/cli.py", line 107, in turn_on
    control_interface.turn_on()
  File "/home/pi/xledvenv/lib/python3.7/site-packages/xled/control.py", line 554, in turn_on
    return self.set_mode("movie")
  File "/home/pi/xledvenv/lib/python3.7/site-packages/xled/control.py", line 322, in set_mode
    response = self.session.post(url, json=json_payload)
  File "/home/pi/xledvenv/lib/python3.7/site-packages/requests/sessions.py", line 590, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/home/pi/xledvenv/lib/python3.7/site-packages/xled/auth.py", line 329, in request
    headers = self.add_authorization(headers)
  File "/home/pi/xledvenv/lib/python3.7/site-packages/xled/auth.py", line 354, in add_authorization
    self.fetch_token()
  File "/home/pi/xledvenv/lib/python3.7/site-packages/xled/auth.py", line 272, in fetch_token
    self.client.challenge_response_valid(self.hw_address)
  File "/home/pi/xledvenv/lib/python3.7/site-packages/xled/auth.py", line 403, in challenge_response_valid
    raise ValidationError()
xled.exceptions.ValidationError

Affected XLED components

  • core

  • Command Line Interface (CLI)

  • Libary

  • Documentation

  • Other

XLED version

Name: xled
Version: 0.6.1
Summary: Python library and command line interface to control Twinkly - Smart Decoration LED lights for Christmas.
Home-page: https://github.com/scrool/xled
Author: Pavol Babinčák
Author-email: [email protected]
License: MIT license
Location: /home/pi/xledvenv/lib/python3.7/site-packages
Requires: Click, arpreq, tornado, netaddr, pyzmq, cryptography, click-log, requests, requests-toolbelt
Required-by:

Twinkly device details

TWF020STP 192.168.2.122

Device information

{
    "product_name": "Twinkly",
    "hardware_version": "100",
    "bytes_per_led": 3,
    "hw_id": "ebea98",
    "flash_size": 64,
    "led_type": 14,
    "product_code": "TWF020STP",
    "fw_family": "F",
    "device_name": "Twinkly_EBEA99",
    "uptime": "232837887",
    "mac": "f0...:eb:ea:99",
    "uuid": "A5804158-...",
    "max_supported_led": 510,
    "number_of_led": 20,
    "led_profile": "RGB",
    "frame_rate": 81,
    "measured_frame_rate": 90.91,
    "movie_capacity": 992,
    "wire_type": 1,
    "copyright": "LEDWORKS 2021",
    "code": 1000
}

Firmware version

{
    "version": "2.7.1",
    "code": 1000
}

Operating system

Raspberry Pi OS Linux pi4 5.10.52-v7l+ #1440 SMP Tue Jul 27 09:55:21 BST 2021 armv7l GNU/Linux

Python version

Python 3.7.3

Using xled on OS X

Install on OS X fails:

use of undeclared identifier 'SIOCGIFHWADDR'

Is this a known issue?

Firmware 2.1 Login process changed?

Attempted to follow https://xled-docs.readthedocs.io/en/latest/rest_api.html#login, but when I issue a challenge I get an 1106 status code back from the lights.

I've attempted to packet sniff via Wireshark against a local android emulator running in Android Studio, but I couldn't get it to see the lights via the Twinkly app. I could however do the http://<ip>/xled/v1/gestalt URL, so it can definitely see the lights if you know where to look.

Any further ideas what to do to investigate how the login works now?

Cheers,
Stuart

brightness control

hi guys,
i'm looking into an API method to control those leds brightness (equivalent of brightness slider in the app). anyone?

Question - using MAC address rather than Discovery

This is a question rather than an issue.
I have been experimenting with using CLI from shell scripts and it is working well.
However, the discovery process seems to take between 2 and 4 seconds ... so I modified cli.py to support passing in a MAC address ... and if the host address (ip address) and new mac address are given on the command line then I skip the discovery phase and use the given parameters.
This does mean that the device name is not known as a result of discovery ... but are there any other consequences that you can think of that could cause problems?
For cli it is a fire once and exit function - so the background discovery functionality should not matter.
Of course, the user might get the parameters incorrect - but that is easily fixed by the user.

Trick to update app with new mapping?

Hey

So I've tweaked my led layout slightly, just to clean it up a bit from the mapping. I've successfully pushed the new layout config with set_led_layout, and can retrieve the updated layout via get_led_layout. However, the app must cache the last known state that it was aware of.

Does anyone know a trick to force the app to pick up the updated layout? I've tried to delete the scene, remove the set in question from the app and re-added, but it comes with the default Christmas tree layout.

For ref, and in case it helps anyone that's trying to do similar, this is how I've been working with the layout, plotting via matplotlib to get the visualisation, and adjusting layouts via another script.

`
import xled
import numpy as np
from matplotlib import pyplot as plt

c = xled.ControlInterface("192.168.8.118")
coord = c.get_led_layout().data['coordinates']

a = []
for item in coord:
a.append([item['x'], item['y']])

arr = np.array(a)
x, y = arr.T
plt.scatter(x,y)
plt.show()
`

Packet Capture for Gen 2 750 Light Tree

For reference, I am sharing a Wireshark packet capture between the iOS Twinkly app and my Gen 2 750 light RGB Christmas tree. This capture includes the app launch, editing a solid color effect (rt mode), then applying that effect as a movie.

My primary reason for sharing is because I believe the realtime UDP protocol has changed, or at least is different for such a a large number of lights. I believe the movie API may have changed a bit as well.

I'm hoping that anyone who understands the code but does not have access to this kinds of device might be able to improve the documentation and code to support newer devices and firmware.

Twinkly Gen 2 750 Lights - App Launch & Effect Change.pcapng.zip

What about adding a Discussion forum for xled in github?

There is an option in the Github settings for a Discussion tab. Wouln't that be useful for xled?

Not everything people like to share fits under "issues". It might be that someone needs help, or wants to ask people with different variants of the lights of their experiences, or wants to share experiences, or give tips of how to produce nice effects on their leds.

I think such a possibility would be nice.

/ Anders

Skip discovery to workaround network that doesn't propagate broadcasts

Discovery is currently implemented as a broadcast. On some networks broadcasts are not propagated. That effectively means Twinkly devices cannot be found. Unicast connections work just fine (e.g. because they are forwarded across networks).

Twinkly app falls back to unicast for each address on the network. It does this only once - when new device is added to the app and then stores information about the device and addresses it directly.

Doing unicast discovery by CLI would be too expensive.

I'd like to mitigate this by ability to skip discovery - probably implicitly when --hostname is specified.

Skip of discovery might require #59.

Turn device on doesn't work after factory reset

Summary

Turning lights on with CLI doesn't work after factory reset and before any movie is uploaded.

Affected XLED components

  • Command Line Interface (CLI)
  • Libary
  • Documentation
  • Other

XLED version

git checkout v0.6.1-21-g2eb4bbe

Twinkly device details

Device information

Gen I TW105SEUM06:

{
  "product_name": "Twinkly",
  "product_version": "2",
  "hardware_version": "6",
  "flash_size": 16,
  "led_type": 5,
  "led_version": "1",
  "product_code": "TW105SEUM06",
  "device_name": "Twinkly_XXXXXX",
  "uptime": "2847430",
  "rssi": -57,
  "hw_id": "XXXXXXX",
  "mac": "5c:cf:7f:XX:XX:XX",
  "uuid": "00000000-0000-0000-0000-000000000000",
  "max_supported_led": 255,
  "base_leds_number": 105,
  "number_of_led": 105,
  "led_profile": "RGB",
  "frame_rate": 25,
  "movie_capacity": 719,
  "copyright": "LEDWORKS 2017",
  "code": 1000
}

Gen II TWS250STP

{
  "product_name": "Twinkly",
  "hardware_version": "100",
  "bytes_per_led": 3,
  "hw_id": "XXXXXX",
  "flash_size": 64,
  "led_type": 14,
  "product_code": "TWS250STP",
  "fw_family": "F",
  "device_name": "Twinkly_XXXXXX",
  "uptime": "1020612",
  "mac": "24:0a:c4:xx:xx:xx",
  "uuid": "XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXXX",
  "max_supported_led": 510,
  "number_of_led": 250,
  "led_profile": "RGB",
  "frame_rate": 30.3,
  "movie_capacity": 1984,
  "copyright": "LEDWORKS 2018",
  "code": 1000
}

Gen II TWI190SPP

{
  "product_name": "Twinkly",
  "hardware_version": "100",
  "bytes_per_led": 4,
  "hw_id": "XXXXXX",
  "flash_size": 64,
  "led_type": 12,
  "product_code": "TWI190SPP",
  "fw_family": "G",
  "device_name": "Twinkly_XXXXXX",
  "uptime": "3542784",
  "mac": "fc:f5:c4:xx:xx:xx",
  "uuid": "XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXXX",
  "max_supported_led": 1200,
  "number_of_led": 190,
  "led_profile": "RGBW",
  "frame_rate": 27.78,
  "movie_capacity": 992,
  "wire_type": 4,
  "copyright": "LEDWORKS 2018",
  "code": 1000
}

Firmware version

TW105SEUM06:

{
  "version": "2.3.8",
  "code": 1000
}

TWS250STP:

{
  "version": "2.2.1",
  "code": 1000
}

TWI190SPP:

{
  "version": "2.4.22",
  "code": 1000
}

Operating system

  • Fedora release 32 (Thirty Two)
  • Fedora release 33 (Thirty Three)

Python version

  • Python 3.8.6
  • Python 3.9.1

Steps to reproduce

  1. factory reset the device
  2. connect to its AP or connect it to WiFi so it can be controlled
  3. run: xled --name Twinkly_XXXXXX on

Expected behavior

Lights turn on or error is printed.

Actual results

$ xled --verbosity-cli DEBUG --verbosity-control DEBUG --verbosity-auth DEBUG --name Twinkly_XXXXXX on                     
Looking for a device with name: Twinkly_D49CED...
Working on requested device.
debug: HW address = 24:0a:c4:XX:XX:XX
debug: IP address = 192.168.1.248
debug: Turning on...
debug: Generated new state b'\xad\xbf\x8bMi\x90\x04\xc7K=\x1e\xb8,\xfb\xb8\x81\xe0\x12j\x84\x0c\x14F\x04\x9d\xa3\xb1N\x83\x94\xc3u'.
debug: ClientApplication(): Challenge: b'\xad\xbf\x8bMi\x90\x04\xc7K=\x1e\xb8,\xfb\xb8\x81\xe0\x12j\x84\x0c\x14F\x04\x9d\xa3\xb1N\x83\x94\xc3u'
debug: receive_authentication_token(): got token: 5e42MMP7h+A=
debug: challenge-response is correct.
debug: Requesting url http://192.168.1.248/xled/v1/led/mode using method POST.
debug: Supplying headers {'X-Auth-Token': '5e42MMP7h+A='}
debug: Passing through key word arguments {'data': None, 'json': {'mode': 'movie'}}.
Turned on.

But lights stay turned off

Additional information

locale.nl_langinfo(locale.T_FMT) unsupported on Windows.

nl_langinfo seems to be unsupported on Windows.

More curious on how you'd like to see this approached.
It's used at least in get-timer to format the times.

if sys.platform == 'win32':
    format = "%H:%M:%S"
else:
    format = locale.nl_langinfo(locale.T_FMT)

Thoughts appreciated.

Error in error handler

raise ApplicationError(msg, response=self.response)

File "/home/pi/wakeupcall/.venv/src/xled/xled/response.py", line 69, in data raise ApplicationError(msg, response=self.response) File "/home/pi/wakeupcall/.venv/src/xled/xled/exceptions.py", line 6, in __init__ super(XledException, self).__init__(*args, **kwargs) TypeError: ApplicationError() takes no keyword arguments

ControlInterface wrapper to help with timeouts

I use set_rt_frame_socket to send individual frames to my light strings. These are shown for 60 seconds before the string reverts to its last stored movie. Because the xled.control.ControlInterface does not set a short timeout when communicating with the lights, sometimes I see many-minute hangs during which communication is lost. These failed connections are intermittent, so in the absence of an xled timeout argument I’ve found that this wrapper class works well:

class TimeoutControlInterface:
    interface = None

    def __init__(self, *args, **kwargs):
        """Initialize xled.control.ControlInterface with same arguments"""
        self.interface = xled.control.ControlInterface(*args, **kwargs)

    def __getattr__(self, name):
        """Retrieve versions of self.interface methods that use a threaded timeout"""
        original_method, responses = getattr(self.interface, name), []

        def wrapped_method(*args, **kwargs):
            """Call the original method and stash its response"""
            responses.append(original_method(*args, **kwargs))

        def threaded_method(*args, **kwargs):
            """Call the wrapped method inside a thread and return its response"""
            thread = threading.Thread(target=wrapped_method, args=args, kwargs=kwargs)
            thread.start()
            thread.join(timeout=5.0)
            if thread.is_alive():
                raise Exception("Thread still alive")
            return responses[0]

        return threaded_method

It’s used just like xled.control.ControlInterface but raises an exception when a method call requires more than five seconds to complete. Hope it’s useful to someome!

AttributeError: module 'xled' has no attribute 'security'

Summary

I'm running the sample code and get the following error

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/michael.whitley/Developer/xled/xled/control.py", line 226, in get_device_info
    response = self.session.get(url)
  File "/Users/michael.whitley/opt/anaconda3/lib/python3.8/site-packages/requests/sessions.py", line 543, in get
    return self.request('GET', url, **kwargs)
  File "/Users/michael.whitley/Developer/xled/xled/auth.py", line 329, in request
    headers = self.add_authorization(headers)
  File "/Users/michael.whitley/Developer/xled/xled/auth.py", line 354, in add_authorization
    self.fetch_token()
  File "/Users/michael.whitley/Developer/xled/xled/auth.py", line 272, in fetch_token
    self.client.challenge_response_valid(self.hw_address)
  File "/Users/michael.whitley/Developer/xled/xled/auth.py", line 396, in challenge_response_valid
    expected = xled.security.make_challenge_response(self._challenge, hw_address)
AttributeError: module 'xled' has no attribute 'security'```

# Affected XLED components

- [ ] Command Line Interface (CLI)
- [x] Libary
- [ ] Documentation
- [ ] Other

# XLED version
v0.6.1-62-g624b519

# Twinkly device details
<!--- Project support only some device models. Provide details by calling its API where HOSTNAME is either IP address or host name of your device. -->

## Device information

```{"product_name":"Twinkly","hardware_version":"304","bytes_per_led":3,"hw_id":"c55a6c","flash_size":64,"led_type":14,"product_code":"TWS400STP","fw_family":"F","device_name":"Twinkly_C55A6D","uptime":"236293617","mac":"a4:e5:7c:xx:xx:xx","uuid":"FFB78939-XXXX-XXXX-XXXX-A11CB1AXXXXX","max_supported_led":510,"number_of_led":400,"led_profile":"RGB","frame_rate":13,"measured_frame_rate":15.38,"movie_capacity":3382,"wire_type":2,"copyright":"LEDWORKS 2021","code":1000}

Firmware version

Operating system

MacOS

Python version

Python 3.8.5

Steps to reproduce

import xled
discovered_device = xled.discover.discover()
discovered_device.id
control = xled.ControlInterface(discovered_device.ip_address, discovered_device.hw_address)
control.get_device_info()['number_of_led']

Expected behavior

Return number of LEDs

Actual results

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/michael.whitley/Developer/xled/xled/control.py", line 226, in get_device_info
    response = self.session.get(url)
  File "/Users/michael.whitley/opt/anaconda3/lib/python3.8/site-packages/requests/sessions.py", line 543, in get
    return self.request('GET', url, **kwargs)
  File "/Users/michael.whitley/Developer/xled/xled/auth.py", line 329, in request
    headers = self.add_authorization(headers)
  File "/Users/michael.whitley/Developer/xled/xled/auth.py", line 354, in add_authorization
    self.fetch_token()
  File "/Users/michael.whitley/Developer/xled/xled/auth.py", line 272, in fetch_token
    self.client.challenge_response_valid(self.hw_address)
  File "/Users/michael.whitley/Developer/xled/xled/auth.py", line 396, in challenge_response_valid
    expected = xled.security.make_challenge_response(self._challenge, hw_address)
AttributeError: module 'xled' has no attribute 'security'```
# Additional information

<!--- Anything else you would like to add? -->
I love the work done on this and look forward to using it!

xled sometimes hangs, probably when network is flaky

Summary

Usually when there are network issues the driver raises an exception, but sometimes it just hangs forever.

Affected XLED components

  • Command Line Interface (CLI)
  • [ x ] Library
  • Documentation
  • Other

XLED version

Tried with both the most recent pip version, and HEAD here.

[I skipped the device information because I can't get it right now, but I will if necessary.]

Operating system

Darwin bantam.local 19.6.0 Darwin Kernel Version 19.6.0: Thu Sep 16 20:58:47 PDT 2021; root:xnu-6153.141.40.1~1/RELEASE_X86_64 x86_64

Linux raspberrypi 5.10.63-v7+ #1459 SMP Wed Oct 6 16:41:10 BST 2021 armv7l GNU/Linux

Python version

Python 3.6.6, also tried 3.8.x on Mac
On RP, 3.9.1

Steps to reproduce

I've been running this driver 24/7 for over a month, on two different machines.

I thought my network was solid, but it seems there are occasional short outages which I never notice (e.g. when watching Netflix). (In my experience, this is typical of home systems.)

After a day or two, one of three different behaviors seems to happen:

GOOD:

  File "/code/xled/xled/control.py", line 1314, in show_rt_frame
    self.set_rt_frame_socket(frame, 3)
  File "/code/xled/xled/control.py", line 893, in set_rt_frame_socket
    self.udpclient.send(packet)
  File "/code/xled/xled/udp_client.py", line 95, in send
    return self.handle.sendto(message, 0, (self.destination_host, self.port))
OSError: [Errno 101] Network is unreachable

GOOD:

  File "/Users/tom/synthetic/code/xled/xled/control.py", line 1314, in show_rt_frame
    self.set_rt_frame_socket(frame, 3)
  File "/Users/tom/synthetic/code/xled/xled/control.py", line 893, in set_rt_frame_socket
    self.udpclient.send(packet)
  File "/Users/tom/synthetic/code/xled/xled/udp_client.py", line 95, in send
    return self.handle.sendto(message, 0, (self.destination_host, self.port))
OSError: [Errno 65] No route to host

BAD: nothing - it just hangs and the animation stops working, and there is no output.

Additional information

I reran both programs with --verbose and I'll let you know what happens. This should also give me a stack trace when I break out of the hanging program, which was before suppressed by the calling program.

There will probably be more information coming, but I wanted to get all this down to start with to see if this were familiar to you!

Thanks again for an excellent program.

cli --hostname argument does nothing (broadcast ping gets used regardless)

Summary

DiscoveryInterface() calls InterfaceAgent() incorrectly, such that destination_host gets lost. The result is that the cli --hostname argument does nothing: InterfaceAgent ends up pinging the broadcast address regardless of whether or not --hostname address is specified.

Affected XLED components

  • Command Line Interface (CLI)
  • Libary
  • Documentation
  • Other

XLED version

v0.6.1-109-g91da7b1 (origin/develop)

Twinkly device details

N/A

Device information

Firmware version

Operating system

Python version

Steps to reproduce

  1. Run xled --verbosity-discover=DEBUG --hostname {some BOGUS IP addess} get-mode ...
  2. Notice that the specified bogus IP address is actually ignored; xled just pings the broadcast address, and then discovers and communicates with an arbitrary attached Twinkly device.

Expected behavior

The --hostname argument should actually work as documented.

Actual results

Additional information

"get" Commands Not Functioning As Expected

I have a strand of Twinkly lights (Model TWS250STP-GUS) that I wanted to try this API on however I can not get a simple "get" to function as intended. The light strand is connected to same Wi-Fi network as the Raspberry Pi and I can get requests such as "set_mode()", "set_brightness()", "turn_off()" and "turn_on()" to work however when I try "is_on()", the code always returns the except statement "Could not determine". I can not figure out how to get it to return "True" or "False". Code provided below:

import xled
host = ip_address #Redacted
def LightState():
try:
State = xled.HighControlInterface(host)
Power_State = State.is_on()
return Power_State
except:
return "Could not determine"
print (LightState())

I run into the same issue with "get_mode", "get_device_info()" or "get_device_name()". Reading through the documentation, I saw this specific product was not listed in hardware however I wanted to make sure I was not missing anything.

xled on not working

Summary

The problem has similarities to a previous issue (#66), but I did not do a factory reset or other reset. So when I run the command to switch the lights on, it shows in the CLI that it has switched them on. However, nothing happens. When I switch them on with the Twinkly app and then switch them off via the CLI it works fine. It was all working fine yesterday and I'm pretty sure I did not change anything.

Affected XLED components

  • Command Line Interface (CLI)
  • Libary
  • Documentation
  • Other

XLED version

Name: xled
Version: 0.7.0
Summary: Python library and command line interface to control Twinkly - Smart Decoration LED lights for Christmas.
Home-page: https://github.com/scrool/xled
Author: Pavol Babinčák
Author-email: [email protected]
License: MIT license
Location: /usr/local/lib/python3.7/dist-packages
Requires: click-log, pyzmq, Click, cryptography, tornado, requests, netaddr, requests-toolbelt
Required-by:

Twinkly device details

Device information

{
  "product_name": "Twinkly",
  "hardware_version": "100",
  "bytes_per_led": 3,
  "hw_id": "XXXXXX",
  "flash_size": 64,
  "led_type": 19,
  "product_code": "TWS600STP",
  "fw_family": "M",
  "device_name": "Twinkly_XXXXXX",
  "uptime": "3046141",
  "mac": "XX:XX:XX:XX:XX:XX",
  "uuid": "XXXXXXXXXXXXXXXXXXXX",
  "max_supported_led": 600,
  "number_of_led": 600,
  "led_profile": "RGB",
  "frame_rate": 9,
  "measured_frame_rate": 9.8,
  "movie_capacity": 2245,
  "wire_type": 1,
  "copyright": "LEDWORKS 2021",
  "code": 1000
}

Firmware version

{
  "version": "2.8.3",
  "code": 1000
}

Operating system

PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

Python version

Python 2.7.16
Python 3.7.3

Steps to reproduce

xled --name DEVICENAME on

Expected behavior

Expect lights to switch on.

Actual results

Nothing happens

xled --verbosity-cli DEBUG --verbosity-control DEBUG --verbosity-auth DEBUG --name Twinkly_XXXXXX on
Looking for a device with name: Twinkly_XXXXXX...
Working on requested device.
debug: HW address = XX:XX:XX:XX:XX:XX
debug: IP address = XXX.XXX.XXX.XXX
debug: Turning on...
debug: Generated new state 'W\xd9\x04\xa1s\x98MN\xf7\x14M\x0b\x8c\x1c\xc9\xed\xc3%IC2\x14\xe9<e\xdb\x13n_\xd6\xeaI'.
debug: ClientApplication(): Challenge: 'W\xd9\x04\xa1s\x98MN\xf7\x14M\x0b\x8c\x1c\xc9\xed\xc3%IC2\x14\xe9<e\xdb\x13n_\xd6\xeaI'
debug: receive_authentication_token(): got token: LaPx6RSxcCw=
debug: challenge-response is correct.
debug: Requesting url http://XXX.XXX.XXX.XXX/xled/v1/led/mode using method POST.
debug: Supplying headers {'X-Auth-Token': u'LaPx6RSxcCw='}
debug: Passing through key word arguments {'json': {'mode': 'movie'}, 'data': None}.
Turned on.

Additional information

Compatibility for OS X

Hey, I found a way to use the library on Mac, didn't I send you a pull request? I would offer to test and maintain this package for Mac if that's ok with you.

Device polling

Hi, guys
Not an issue of this library (btw, I like the old single file version more, now it become a monster) but the xled protocol itself.
The problem happen with device polling (check mode and brightness from time to time). It kills mobile app session because of auth token changed. This way its not possible to setup new effects etc when some smarthome controller polling the device.
Any ideas?

Documentation is rendered incorrectly (inconsistently) on read the docs

GitHub renders block fine:

xled readme github


Local run of Sphinx the same:

xled readme sphinx


Even on PyPI it renders fine:

xled readme pypi


But on Read the Docs it is missing code blocks:

xled readme readthedocs


Problematic section:

Installation
------------

Both library and CLI tool are supported on Linux, primarily Fedora.

#. First make sure that you have `pip installed`_. E.g. for Fedora:

   ::

       $ sudo dnf install python3-pip python3-wheel

#. You might want to `create and activate a virtual environment`_. E.g.:

   ::

       $ mkdir -p ~/.virtualenvs
       $ python3 -m venv ~/.virtualenvs/xled
       $ source ~/.virtualenvs/xled/bin/activate

#. Install `xled from PyPI`_:

   ::

       $ python3 -m pip install --upgrade xled

music dongle support?

Does the API provide a way to toggle the USB music dongle on/off? It's their standalone mic, that picks up ambient sound (presumably from music playing nearby) and uses that to influence patterns on the lights. It'd be great to have on/off control of it.

The strips will fall back to using their saved playlist of lighting effects if the music is turned off.

Firmware file

Hello, is it possible to have the firmware file. I have several ESP-01 modules and I would like to order Ws2811 LED ribbons with this application.

`python setup.py install`/`develop` need manual intervention to install dependencies

Summary

python setup.py install/develop should install all the dependencies.

On Darwin Kernel Version 19.6.0 == MacOS 10.15.7 (and also 10.13), this gets:

error: The 'requests' distribution was not found and is required by xled

If you run the same command twice more it works.

Affected XLED components

  • Command Line Interface (CLI)
  • Libary
  • Documentation
  • Other

XLED version

The develop branch

Operating system

MacOS 10.15.7 but I also saw this on a 10.13

Python version

Python 3.6.6 and 3.8.9

Steps to reproduce

  1. Clear a virtualenv
  2. python setup.py develop or install

Additional information

I have seen this issue reported before on a different project by a Mac user, so I have a fix (coming), but I don't know the cause, or really why the fix works.

Xled_plus - use xled to produce various effects

This is not really an issue, but rather an announcement:
I have moved out my proposed xled additions (previously in pull request #80) into its own repository xled_plus. It adds features on top of xled for creating different types of effects on your lights, removing the need to use the (rather limited and awkward) app for that.

There is a discussion forum there too, which we can use to discuss both xled and xled_plus things (which doesn't fit better here as issues of course). I will, as a kind of "advent calendar", publish daily effects there, starting tomorrow Dec 1.

You are welcome to check it out!

Bad File Descriptor when getting second device from xdiscover

When using xdiscover and having two devices on the network, the following example code causes an exception on the second next call

    devices = []
    discovered_devices = xled.discover.xdiscover()
    while True:
        try:
            device = next(discovered_devices)
            devices.append(device)
        except StopIteration:
            break
    return devices
ERROR:asyncio:Exception in callback BaseAsyncIOLoop._handle_events(24, 1)
handle: <Handle BaseAsyncIOLoop._handle_events(24, 1)>
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.2_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "/Users/alex/.local/share/virtualenvs/wakeupcall-EJzfLl60/lib/python3.7/site-packages/tornado/platform/asyncio.py", line 138, in _handle_events
    handler_func(fileobj, events)
  File "/Users/alex/.local/share/virtualenvs/wakeupcall-EJzfLl60/src/xled/xled/discover.py", line 442, in handle_beacon
    data, host = self._next_packet()
  File "/Users/alex/.local/share/virtualenvs/wakeupcall-EJzfLl60/src/xled/xled/discover.py", line 421, in _next_packet
    data, host = self.udp.recv(64)
  File "/Users/alex/.local/share/virtualenvs/wakeupcall-EJzfLl60/src/xled/xled/udp_client.py", line 110, in recv
    buf, addrinfo = self.handle.recvfrom(bufsize)
OSError: [Errno 9] Bad file descriptor

Example of movie file/stream?

First: Thanks to all for developing this!
Any good simple examples of how to send a movie using the library?
Another example I could use is how to use RT mode - I thought I saw references to it somewhere but set_mode only supports 'on', 'off', 'movie' and 'demo'.
Thanks again!

Initial Update

The bot created this issue to inform you that pyup.io has been set up on this repo.
Once you have closed it, the bot will open pull requests for updates as soon as they are available.

Example Files for Movie and Real Time modes

It would be super helpful if you could publish an example movie file that can be uploaded onto the Twinkly lights and played.
It would also be great if there was a file or directions on how to send real time data to the Twinkly's.

I am trying to get these lights to run the way I want them to, not based on the lame animations that come with the iPhone App!

Thanks!

error on Mac

Building wheel for arpreq (setup.py) ... error
ERROR: Command errored out with exit status 1:
command: /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-install-XrQqXv/arpreq/setup.py'"'"'; file='"'"'/private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-install-XrQqXv/arpreq/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' bdist_wheel -d /private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-wheel-bJhqbV
cwd: /private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-install-XrQqXv/arpreq/
Complete output (37 lines):
running bdist_wheel
running build
running build_ext
building 'arpreq' extension
creating build
creating build/temp.macosx-10.15-x86_64-2.7
creating build/temp.macosx-10.15-x86_64-2.7/src
cc -fno-strict-aliasing -fno-common -dynamic -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -iwithsysroot /usr/local/libressl/include -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -arch x86_64 -pipe -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c src/arpreq.c -o build/temp.macosx-10.15-x86_64-2.7/src/arpreq.o -std=c99
src/arpreq.c:215:39: error: use of undeclared identifier 'SIOCGIFHWADDR'
if (ioctl(st->socket, SIOCGIFHWADDR, &ifreq) == -1) {
^
src/arpreq.c:218:49: error: no member named 'ifr_hwaddr' in 'struct ifreq'
memcpy(&mac_address, &ifreq.ifr_hwaddr, sizeof(mac_address));
~~~~~ ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_string.h:63:33: note: expanded from macro 'memcpy'
__builtin___memcpy_chk (dest, VA_ARGS, __darwin_obsz0 (dest))
^~~~~~~~~~~
src/arpreq.c:226:28: error: no member named 'arp_dev' in 'struct arpreq'
strncpy(arpreq.arp_dev, ifa->ifa_name, IFNAMSIZ);
~~~~~~ ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_string.h:128:28: note: expanded from macro 'strncpy'
__builtin___strncpy_chk (dest, VA_ARGS, __darwin_obsz (dest))
^~~~
src/arpreq.c:226:28: error: no member named 'arp_dev' in 'struct arpreq'
strncpy(arpreq.arp_dev, ifa->ifa_name, IFNAMSIZ);
~~~~~~ ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_string.h:128:62: note: expanded from macro 'strncpy'
__builtin___strncpy_chk (dest, VA_ARGS, __darwin_obsz (dest))
^~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_common.h:39:54: note: expanded from macro '__darwin_obsz'
#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1 ? 1 : 0)
^~~~~~
src/arpreq.c:227:35: error: use of undeclared identifier 'SIOCGARP'
if (ioctl(st->socket, SIOCGARP, &arpreq) == -1) {
^
5 errors generated.
error: command 'cc' failed with exit status 1

ERROR: Failed building wheel for arpreq
Running setup.py clean for arpreq
Successfully built xled
Failed to build arpreq
Installing collected packages: arpreq, monotonic, pyzmq, backports-abc, futures, tornado, xled
Running setup.py install for arpreq ... error
ERROR: Command errored out with exit status 1:
command: /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-install-XrQqXv/arpreq/setup.py'"'"'; file='"'"'/private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-install-XrQqXv/arpreq/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record /private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-record-QAkkgv/install-record.txt --single-version-externally-managed --user --prefix= --compile --install-headers /Users/vjee/Library/Python/2.7/include/python2.7/arpreq
cwd: /private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-install-XrQqXv/arpreq/
Complete output (37 lines):
running install
running build
running build_ext
building 'arpreq' extension
creating build
creating build/temp.macosx-10.15-x86_64-2.7
creating build/temp.macosx-10.15-x86_64-2.7/src
cc -fno-strict-aliasing -fno-common -dynamic -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -iwithsysroot /usr/local/libressl/include -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -arch x86_64 -pipe -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c src/arpreq.c -o build/temp.macosx-10.15-x86_64-2.7/src/arpreq.o -std=c99
src/arpreq.c:215:39: error: use of undeclared identifier 'SIOCGIFHWADDR'
if (ioctl(st->socket, SIOCGIFHWADDR, &ifreq) == -1) {
^
src/arpreq.c:218:49: error: no member named 'ifr_hwaddr' in 'struct ifreq'
memcpy(&mac_address, &ifreq.ifr_hwaddr, sizeof(mac_address));
~~~~~ ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_string.h:63:33: note: expanded from macro 'memcpy'
__builtin___memcpy_chk (dest, VA_ARGS, __darwin_obsz0 (dest))
^~~~~~~~~~~
src/arpreq.c:226:28: error: no member named 'arp_dev' in 'struct arpreq'
strncpy(arpreq.arp_dev, ifa->ifa_name, IFNAMSIZ);
~~~~~~ ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_string.h:128:28: note: expanded from macro 'strncpy'
__builtin___strncpy_chk (dest, VA_ARGS, __darwin_obsz (dest))
^~~~
src/arpreq.c:226:28: error: no member named 'arp_dev' in 'struct arpreq'
strncpy(arpreq.arp_dev, ifa->ifa_name, IFNAMSIZ);
~~~~~~ ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_string.h:128:62: note: expanded from macro 'strncpy'
__builtin___strncpy_chk (dest, VA_ARGS, __darwin_obsz (dest))
^~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/secure/_common.h:39:54: note: expanded from macro '__darwin_obsz'
#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1 ? 1 : 0)
^~~~~~
src/arpreq.c:227:35: error: use of undeclared identifier 'SIOCGARP'
if (ioctl(st->socket, SIOCGARP, &arpreq) == -1) {
^
5 errors generated.
error: command 'cc' failed with exit status 1
----------------------------------------
ERROR: Command errored out with exit status 1: /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-install-XrQqXv/arpreq/setup.py'"'"'; file='"'"'/private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-install-XrQqXv/arpreq/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record /private/var/folders/bh/fv5yblvn2f9_s4zl3v0tjm2w0000gn/T/pip-record-QAkkgv/install-record.txt --single-version-externally-managed --user --prefix= --compile --install-headers /Users/vjee/Library/Python/2.7/include/python2.7/arpreq Check the logs for full command output.

Error: Only one usage of each socket address

I'm new here. I'm using Miniconda virtual environment. When I ruan following command it got frozen:

(xled) PS C:\Users\home> xled on
Looking for any device...

When I tried to specify the name of the device I got this:

(xled) PS C:\Users\home> xled --name Twinkly_71B12D on
Looking for a device with name: Twinkly_71B12D...
Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Users\home\AppData\Local\Programs\Python\Python37\lib\threading.py", line 926, in _bootstrap_inner
    self.run()
  File "C:\Users\home\AppData\Local\Programs\Python\Python37\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\home\AppData\Local\Programs\Python\Python37\lib\site-packages\xled-0.6.1-py3.7.egg\xled\discover.py", line 370, in start
    self.udp.handle.fileno(), self.handle_beacon, self.loop.READ
  File "C:\Users\home\AppData\Local\Programs\Python\Python37\lib\site-packages\xled-0.6.1-py3.7.egg\xled\udp_client.py", line 59, in handle
    _handle.bind(("", self.port))
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

I've googled a bit and I saw something to do with port already used by other application. Any suggestion how to fix this?
Thanks in advance.

Gen II: Invalid challenge-response

Hello,
Using Twinkly Gen2, Debian Buster amd64 and xled with python 3.7, I get this following error using cli:
Looking for any device...
Working on device: 'Twinkly_*****'
ERROR:xled.auth:challenge-response invalid. Received challenge-response: 'a28de0d5a2149a2073b2beadfbb1099a19828fe3' but '2ed085ade3f9b16c9195407436327b86331cf2a4' was expected.
Do you have an idea of what happends?
Thank you!

Is uploading a movie currently unsupported?

This may only be a documentation issue. The private protocol documentation sets out the movie format, and a few words about how it's uploaded (https://xled.readthedocs.io/en/latest/protocol_details.html#upload-full-movie-led-effect), but I can't see the ability to actually upload it in the Python xled package. Nor does the API reference make this very clear.

Am I missing something (I know very little python) or is this not implemented yet?

Thanks very much for your work on this so far though - it's appreciated.

Can't install via pip on Windows

Received error:

error: Microsoft Visual C++ 9.0 is required. Get it from http://aka.ms/vcpython27

installed from that location and tried again, continued slightly further but got another error:

src/arpreq.c(3) : fatal error C1083: Cannot open include file: 'stdbool.h': No such file or directory

after some searching in Google, found this message and several other similar .h file errors pointing to header files that are for *nix not for Win32/64. I tried creating blank files for all the subsequent error'ing .h missing files and ended up with many other errors:

src/arpreq.c(42) : error C2054: expected '(' to follow 'inline'
src/arpreq.c(44) : error C2085: 'mac_to_string' : not in formal parameter list
src/arpreq.c(44) : error C2143: syntax error : missing ';' before '{'
src/arpreq.c(62) : error C2054: expected '(' to follow 'inline'
src/arpreq.c(63) : error C2085: 'address_from_long' : not in formal parameter list
src/arpreq.c(63) : error C2143: syntax error : missing ';' before '{'
src/arpreq.c(84) : error C2054: expected '(' to follow 'inline'
src/arpreq.c(85) : error C2085: 'address_from_bytes' : not in formal parameter list
src/arpreq.c(85) : error C2143: syntax error : missing ';' before '{'
src/arpreq.c(102) : error C2054: expected '(' to follow 'inline'
src/arpreq.c(103) : error C2085: 'address_from_unicode' : not in formal parameter list
src/arpreq.c(103) : error C2143: syntax error : missing ';' before '{'
src/arpreq.c(117) : error C2054: expected '(' to follow 'inline'
src/arpreq.c(118) : error C2085: 'coerce_argument' : not in formal parameter list
src/arpreq.c(118) : error C2143: syntax error : missing ';' before '{'
src/arpreq.c(179) : error C2079: 'ip_address' uses undefined struct 'sockaddr_in'
src/arpreq.c(181) : error C2224: left of '.sin_family' must have struct/union type
src/arpreq.c(181) : error C2065: 'AF_INET' : undeclared identifier
src/arpreq.c(182) : warning C4013: 'coerce_argument' undefined; assuming extern returning int
src/arpreq.c(182) : error C2224: left of '.sin_addr' must have struct/union type
src/arpreq.c(186) : error C2065: 'uint32_t' : undeclared identifier
src/arpreq.c(186) : error C2146: syntax error : missing ';' before identifier 'addr'
src/arpreq.c(186) : error C2065: 'addr' : undeclared identifier
src/arpreq.c(186) : error C2224: left of '.sin_addr' must have struct/union type

etc (there were many more than that)...

Clearly this isn't the right way to work around the system for a Windows build, so any other guidance for a python/pip novice?

Writing firmware

I have an issue with the current Twinkly app version 1.5.2 (build 478) when controlling my LED string.
The LEDs are running firmware version 1.99.10 (older than yours) and the app refuses to map the LEDs because the firmware is too old.
However, the firmware update fails because the app times out before the response to the firmware update completes.
I reported it to Twinkly last week - but so far have no solution.

So ... I am thinking about using your xled to do the firmware write (I have captured what the official app was trying to upload and my SHA1 checksums for the captured data matches what the LEDs return in the fw update response).

Given that writing firmware could go horribly wrong ... I would like to know if that function in your xled has library has been tested.
For example - it does not appear to set "Content-Type: application/octet-stream" via
headers={'Content-Type': 'application/octet-stream'}
Is that because it is not needed - or is it untested?

The comment in the upload fw routines say that "firmware" parameter is a "file-like object that points to firmware file".
So should I pass in the name of a file?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.