madVR Envy Python Library
Spec-first async Python client for madVR Envy IP Control.
This project intentionally does not inherit implementation patterns from existing community libraries. It is being built from the official Envy IP Control specification and protocol captures.
Current API Shape
- Typed command helpers in
madvr_envy.commands - High-level async client in
madvr_envy.client.MadvrEnvyClient - Typed protocol parser in
madvr_envy.protocol
Example:
import asyncio
from madvr_envy.client import MadvrEnvyClient
async def main() -> None:
client = MadvrEnvyClient(host="192.168.1.100")
await client.start()
await client.wait_synced(timeout=10)
snapshot = await client.refresh_device()
print(snapshot.power_state, snapshot.incoming_signal, snapshot.aspect_ratio)
await client.get_mac_address(wait_for_ack=True)
await client.display_message(3, "Hello from py-madvr-envy")
await client.change_option("temporary\\hdrNits", 120)
groups = await client.enum_profile_groups_collect()
for group in groups:
print(group.group_id, group.name)
await client.stop()
asyncio.run(main())
Protocol Basis
- Source:
https://madvrenvy.com/wp-content/uploads/EnvyIpControl.pdf - Document title:
madVR Envy IP Control revision 1.1.3 - Retrieved: 2026-02-27
- HTTP metadata observed during retrieval:
Last-Modified: Mon, 20 May 2024 02:40:13 GMT
Development
uv sync --group dev
uv run ruff check .
uv run ruff format --check .
uv run ty check madvr_envy
uv run pytest -v
Protocol Coverage
See docs/PROTOCOL_COVERAGE.md for implemented command and notification coverage.
Enumeration Collectors
For stream enumerations, use typed collectors:
enum_profile_groups_collect()enum_profiles_collect(profile_group)enum_setting_pages_collect()enum_config_pages_collect()enum_options_collect(page_or_path)
These helpers wait for protocol end markers and raise EnumerationTimeoutError if an end marker is not observed in time.
Runtime State
Use client.refresh_device() when an integration needs a complete, typed view of the device. The client owns the protocol request sequence for runtime telemetry, video geometry, temperatures, and profiles, then returns an EnvyDeviceSnapshot.
Use EnvyRuntime for long-running control-system integrations that need reliable video geometry:
from madvr_envy import EnvyRuntime, MadvrEnvyClient, RefreshPolicy
client = MadvrEnvyClient(host="192.168.1.100")
runtime = EnvyRuntime(
client,
policy=RefreshPolicy(
volatile_video_interval=5.0,
geometry_debounce=0.75,
stale_after=15.0,
),
)
runtime.subscribe(lambda snapshot: print(snapshot.video.trusted, snapshot.video.masking_ratio))
await runtime.start()
EnvyRuntime keeps volatile video state fresh without continuously refreshing static catalogs. It reacts to push notifications, debounces display changes, polls signal/geometry while awake, clears geometry on NoSignal, and marks stale geometry untrusted.
For lower-level streaming consumers, madvr_envy.adapter.EnvyStateAdapter converts mutable runtime state into immutable snapshots plus typed deltas/events:
You can wire this directly through the client:
from madvr_envy.adapter import EnvyStateAdapter
adapter = EnvyStateAdapter()
def on_update(snapshot, deltas, events):
...
handle = client.register_adapter_callback(adapter, on_update)
# later: client.deregister_adapter_callback(handle)
Release files for madvr-envy 2.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| madvr_envy-2.1.0.tar.gz | 41.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| madvr_envy-2.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 66.5 kB
Release files / madvr_envy-2.1.0.tar.gz
| Download URL | madvr_envy-2.1.0.tar.gz |
|---|---|
| Size | 41.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
273fb63b3ed01b29e72f5510cc8e44216e21fea0cea8390c574a8e00c77bb7c0
|
|
BLAKE2b-256 checksum How to use checksums |
efb5937ee3c479f7c52958d6922cf5007608880897f21e217d405fce5c037094
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.
Transparency logRelease files / madvr_envy-2.1.0-py3-none-any.whl
| Download URL | madvr_envy-2.1.0-py3-none-any.whl |
|---|---|
| Size | 25.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
adcb55908fa346b56c9e1785a6fe62981f4a9cb010b135e0482545c4bbeb918a
|
|
BLAKE2b-256 checksum How to use checksums |
c6c7d8e437b2268b364c6f49e4e221c8ccaa019c4229761528440de617726bcf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.
Transparency log