Skip to main content

neewer

Python control library for Neewer TL-series RGB tube lights (TL120C / TL90C and friends) over Bluetooth LE — no app, no pairing.

import asyncio
from neewer import Fleet

async def main():
    async with Fleet() as fleet:              # scan + connect everything in range
        await fleet.set_hsi("all", 240, 100, 100)     # all lights blue

asyncio.run(main())

The typed methods (set_hsi, power, set_cct, …) are the primary API. A one-line string grammar (fleet.dispatch("all hsi 240 100 100")) is also available as a convenience — see The string grammar.

Or from the terminal:

$ neewer scan                     # list the lights it can see
$ neewer all hsi 240 100 100      # everything blue
$ neewer all power off
$ neewer t1 cct 100 5600          # position 1 -> 5600 K

Firmware flashing lives in its own tool, neewer-ota (dry-run by default; --confirm writes). Stop anything else holding the light first:

$ neewer-ota <MAC> --file fw.bin --check     # connect, probe, validate, no write
$ neewer-ota <MAC> --file fw.bin --confirm   # actually flash

What you get

  • neewer.Fleet — the batteries-included BLE client: continuous discovery, persistent connections, an auto-reconnect supervisor (exponential backoff + jitter) that survives a light being switched off or grabbed by another device, target addressing (all / t<N> / MAC / alias / group), and typed methods for every action. Subscribe with fleet.subscribe(cb) to be notified on any state change (connect / disconnect / telemetry / command) instead of polling.
  • neewer.protocol — the pure, standard-library-only frame/reply/model layer, including the typed command model (neewer.protocol.commands, one dataclass per action, with the shared commands.ACTIONS argument-order registry) and neewer.protocol.dmx DMX-over-IP personalities (hsi, cct, rgb, rgbw) plus WriteGovernor, a self-tuning per-connection write pacer that keeps each tube at or below its measured BLE delivery rate (dropping the newest frame rather than backing up the Bluetooth transmit queue). It never imports bleak, so a non-BLE transport (an ESP32 bridge, a UART gateway) can reuse all the frame knowledge without a radio.
  • neewer.transport — the radio seam: a Transport Protocol with a bleak-backed default (BleakTransport). Fleet takes transport= so you can inject a fake (for tests) or an alternative backend. neewer.fleet itself imports without bleak; only the transport pulls it in, lazily.
  • neewer.errors — typed errors (UnknownTarget / UnknownAction / Unsupported / …); command failures raise, they don't return sentinel strings.
  • neewer.grammar — the opt-in <target> <action> [args] string grammar (parse, dispatch, OSC mapping) layered over the typed API. Register extra verbs with fleet.register_verb(name, handler).
  • neewer.effects — animation engines (comet / hue-flow / palette) that run against a held Fleet.
  • neewer.devices — the device book: give your lights human names, physical positions, and groups in ~/.config/neewer/devices.toml.

The package ships type hints (py.typed).

Install

$ pip install neewer

Requires Python 3.11+. The only runtime dependency is bleak.

Windows

Installation works out of the box on Windows with Bluetooth LE support. The bleak dependency automatically installs the required WinRT packages for Windows Bluetooth access.

If the console scripts (neewer, neewer-ota) are not on your PATH after installation, you have two options:

  1. Add the Scripts directory to your PATH:

    • Typically located at %APPDATA%\Python\Python3XX\Scripts
    • Add this directory to your system PATH environment variable
  2. Use the module directly:

    python -m neewer.cli scan
    python -m neewer.cli all hsi 240 100 100
    python -m neewer.ota <MAC> --file fw.bin --check
    

The Python module approach works everywhere without PATH configuration.

The typed API

Every action is a method on Fleet; the first argument is always a target (all / t<N> / MAC / alias / group):

Method Example
power(target, on) await fleet.power("all", False)
set_hsi(target, hue, sat=100, bri=100) await fleet.set_hsi("t1", 240, 100, 80)
set_cct(target, bri, temp, gm=50) await fleet.set_cct("t1", 100, 56)
set_bri(target, bri) await fleet.set_bri("all", 50)
set_rgbcw(target, bri, r, g, b, c, w) await fleet.set_rgbcw("t1", 60, 0, 0, 0, 255, 0)
set_xy(target, bri, x, y) await fleet.set_xy("t1", 50, 0.3127, 0.329)
set_gel(target, hue, sat, bri, brand, gel_no) await fleet.set_gel("t1", 45, 100, 50)
scene(target, effect, *params) await fleet.scene("all", 3)
pixel(target, colors) await fleet.pixel("t1", ["0", "off", "240"])
identify(target) await fleet.identify("t2")
raw(target, hexstr) await fleet.raw("t1", "78 81 01 01 fb")
flow(mode, **opts) / query(target) / render_state(target) await fleet.flow("comet")

Failures raise neewer.errors.NeewerError subclasses (UnknownTarget, Unsupported, …). See examples/ for runnable scripts.

The string grammar

For REPLs, wire protocols, and one-liners, neewer.grammar parses a line of <target> <action> [args] and dispatches it to the typed API. fleet.dispatch() is a thin convenience over it:

Action Example Effect
power on|off all power off toggle
hsi <h> <s> <i> all hsi 240 100 100 hue/saturation/intensity
cct <bri> <temp> [gm] t1 cct 100 5600 white, colour temperature
bri <0-100> all bri 50 brightness only
rgbcw <bri> <r> <g> <b> <c> <w> t1 rgbcw 60 0 0 0 255 0 RGB + cold/warm white (TL120C)
xy <bri> <x> <y> t1 xy 50 0.3127 0.329 CIE-1931 point (TL120C)
gel <hue> <sat> <bri> [brand] [no] t1 gel 45 100 50 lee 7 gel colour (TL120C)
scene <effect> [params...] all scene 3 built-in scene
pixel <colour...> t1 pixel 0 off 240 k3200 per-segment palette (TL120C)
identify t2 identify flash to locate
flow <mode> [k=v...] all flow comet start a running effect
scan / state / query state list / read / refresh cached state

Targets: all, t<N> (physical position), a MAC, or an alias/group from your device book.

  • neewerd — a ready-made control daemon built on this library: holds the BLE links and exposes the lights over socket / MQTT (Home Assistant discovery) / OSC / HTTP + web UI / Art-Net / sACN, plus an MCP server.
  • neewer-hardware — the hardware and wire-protocol reference this library implements: frame format, the full opcode table, provisioning, DMX, and per-model capabilities.

License

MIT.

Metadata

Release files for neewer 0.1.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for neewer 0.1.4
File Size Uploaded Provenance Actions
neewer-0.1.4.tar.gz 134.9 kB Without provenance Details for neewer-0.1.4.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for neewer 0.1.4
File Interpreter ABI Platform Actions
neewer-0.1.4-py3-none-any.whl Python 3 none any Details for neewer-0.1.4-py3-none-any.whl

Total release size: 231.9 kB

Release files / neewer-0.1.4.tar.gz

Download URL neewer-0.1.4.tar.gz
Size 134.9 kB
Tags Source
SHA-256 checksum
How to use checksums
8d88072258ee8239288d82011b86a1dc08ec350c608da0a0cda11cee76eebaa7
BLAKE2b-256 checksum
How to use checksums
3332c12250eb6b946900abf7038e7d465d2b7812bfc300a1d25715e316fd821b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Release files / neewer-0.1.4-py3-none-any.whl

Download URL neewer-0.1.4-py3-none-any.whl
Size 97.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
630103b825280d6117a714153eefac6fc1a90d5929427c9957f77bfec376ce26
BLAKE2b-256 checksum
How to use checksums
315cf58ab7f63b465ffc6aad6baca902a4a825d8a7d2054217b7e6967147a794
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Security for neewer 0.1.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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