Skip to content

Comments

feat: apply segment effect rule for RGBIC strips#463

Merged
mihai-dinculescu merged 9 commits intomihai-dinculescu:mainfrom
oliyy:feat/apply-segment-effect-rule
Jan 20, 2026
Merged

feat: apply segment effect rule for RGBIC strips#463
mihai-dinculescu merged 9 commits intomihai-dinculescu:mainfrom
oliyy:feat/apply-segment-effect-rule

Conversation

@oliyy
Copy link
Contributor

@oliyy oliyy commented Dec 30, 2025

What

Expose app-defined RGBIC segment effects with a set_segment_effect API that accepts either a SegmentEffectPreset or a custom SegmentEffect.

Why

L920/L930 app RGBIC effects are sent via apply_segment_effect_rule and cannot be expressed with LightingEffect, so users cannot automate them today.

Changes

Added SegmentEffect (custom) and SegmentEffectPreset (app defaults) with builder helpers and a typed SegmentEffectType.
Added set_segment_effect on the handler plus API client support for the apply_segment_effect_rule endpoint.

Notes

I didn't update the Python bindings/stubs yet because I wasn't sure if this feature is in scope for the library overall (or if there's a preferred approach). Happy to revise or extend this based on feedback! 🤠

Testing

Verified on Tapo L920 using app-captured effect payloads and preset IDs.
Firmware: 1.1.11 Build 250313 Rel.095031
Hardware Version: 1.0
Confirmed apply_segment_effect_rule succeeds only when both segments and states are provided for custom effects; omitting either returns InvalidParameters. Preset payloads (name/id/brightness/display_colors) work.

Before

No public API for apply_segment_effect_rule; segment effects were not controllable from the library.

After

Example usage:

use tapo::requests::{SegmentEffect, SegmentEffectPreset, SegmentEffectType};

device.set_segment_effect(SegmentEffectPreset::Birthday).await?;

let custom = SegmentEffect::new(
    "MyCoolEffect",
    SegmentEffectType::Circulating,
    true,
    true,
    100,
    vec![[267, 56, 100, 0]],
)
.with_id("TapoStrip_...")
.with_segments(vec![49])
.with_states(vec![[267, 56, 100, 0]]);

device.set_segment_effect(custom).await?;

@mihai-dinculescu
Copy link
Owner

Thank you for bringing this to my attention. I wasn’t aware that the app had introduced so many new effects, some of which rely on the new apply_segment_effect_rule endpoint.

If I understand correctly, apply_segment_effect_rule is intended to coexist with set_lighting_effect, rather than replace it outright. Is that a fair assumption?

I’d be keen to add support for this new functionality, but I want to do so in a way that’s user-friendly and consistent with the existing set_lighting_effect API. For example, it would be ideal to introduce a SegmentEffectPreset enum that encapsulates all segment effects available in the app, along with a set_segment_effect method that accepts both a SegmentEffectPreset and a SegmentEffect.

It looks like someone has already done significant work dumping all of the segment effects defined by the app. This could be very useful: python-kasa/python-kasa#975.

@oliyy
Copy link
Contributor Author

oliyy commented Jan 2, 2026

Thanks for the feedback!

Yes, that's a fair assumption. I'm fairly new to the Tapo ecosystem and only recently got around to setting up my L920 and from my testing the app seems to push most (if not all) the lighting effects for this specific strip through apply_segment_effect_rule. This is likely the case for both the L920 and L930 strips:

The segment effects are only available on L920 and L930 which support individually controlled leds - as noted here

I reworked the PR to add SegmentEffectPreset + SegmentEffect and a set_segment_effect API (aligned with the existing lighting effect pattern). The segment effects dump from the python-kasa issue was very helpful, thanks for sharing!

I validated on L920 that all 55 app presets work with the minimal payloads (just name/id/brightness/display_colors), and custom effects still require segments/states/type

Currently I'm missing a few values from the SegmentEffectType I added, but I should be able to extract those fairly easily doing some more traffic/request dumps.

Let me know if this direction is closer to what you had in mind, happy to revise further.

@mihai-dinculescu
Copy link
Owner

mihai-dinculescu commented Jan 4, 2026

This looks great 🎉 Once the missing effects are added, Python support is in place, and the Rust and Python examples are updated to showcase this new functionality, it should be ready to ship!

@oliyy
Copy link
Contributor Author

oliyy commented Jan 6, 2026

Thank you! Confirming I have now added the missing SegmentEffectType values and Python support.

I also updated the SUPPORTED_DEVICES.md matrix as well as the existing Rust and Python examples showcasing the functionality.

@mihai-dinculescu mihai-dinculescu merged commit 36bcaba into mihai-dinculescu:main Jan 20, 2026
19 checks passed
@mihai-dinculescu
Copy link
Owner

Thank you so much for this. It's a fantastic contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants