Skip to main content

pyjvcprojector

Test

A Python client library for controlling JVC Projectors over a network connection.

Features

  • Async/await support - Built with asyncio for non-blocking operations
  • Network-based control - Connects to JVC projectors over TCP
  • Command system - Get/set projector parameters and send remote control commands
  • Model detection - Automatically detects projector model and adjusts capabilities
  • Password support - Optional password authentication
  • Command discovery - Check supported commands and capabilities
  • CLI tool - Command-line interface included

Installation

python -m pip install pyjvcprojector

Requirements

  • Python 3.11 or higher

Quickstart

import asyncio
from jvcprojector import JvcProjector, command


async def main():
    # Create projector instance
    jp = JvcProjector("{ip}")
    await jp.connect()

    # Get projector info
    print(f"Model: {jp.model}")

    # Get current power state
    power_state = await jp.get(command.Power)
    print(f"Power state: {power_state}")

    # Turn projector on
    if power_state == command.Power.STANDBY:
        await jp.set(command.Power, command.Power.ON)

    # Using the remote method to send remote control commands
    await jp.remote(command.Remote.UP)

    # Or use the more powerful get/set reference/operation method
    current_input = await jp.get(command.Input)
    print(f"Current input: {current_input}")

    # Disconnect
    await jp.disconnect()


asyncio.run(main())

Usage

Creating a Connection

from jvcprojector import JvcProjector

# Basic connection
jp = JvcProjector("{ip}")

# With custom port and timeout
jp = JvcProjector("{ip}", port=20554, timeout=5.0)

# With password authentication
jp = JvcProjector("{ip}", password="{password}")

# Connect to projector
await jp.connect()

Getting and Setting Parameters

from jvcprojector import command

# Get a parameter value (reference command)
power_state = await jp.get(command.Power)
input_mode = await jp.get(command.Input)
picture_mode = await jp.get(command.PictureMode)

# Set a parameter value (operation command)
await jp.set(command.Power, command.Power.ON)
await jp.set(command.Input, command.Input.HDMI1)
await jp.set(command.PictureMode, command.PictureMode.CINEMA)

Sending Remote Commands

from jvcprojector import command

# Send remote control button presses
await jp.remote(command.Remote.MENU)
await jp.remote(command.Remote.UP)
await jp.remote(command.Remote.OK)
await jp.remote(command.Remote.BACK)

Discovering Capabilities

# Check if a command is supported
import command

if jp.supports(command.InstallationMode):
    await jp.set(command.LensMemory, "memory-1")

# Get description of a command
description = jp.describe(command.Power)
print(description)

# Get all supported commands
capabilities = jp.capabilities()
for cmd_name, cmd_info in capabilities.items():
    print(f"{cmd_name}: {cmd_info}")

# Get projector information
info = jp.info()
print(info)  # {'ip': '192.168.1.100', 'model': 'NZ8', 'spec': '...'}

API Reference

JvcProjector

Constructor:

JvcProjector(host, port=20554, timeout=2.0, password=None)

Methods:

  • await connect(model=None) - Initialize connection to the projector
  • await disconnect() - Close connection to the projector
  • await get(command) - Get a projector parameter value (reference command)
  • await set(command, value) - Set a projector parameter value (operation command)
  • await remote(value) - Send a remote control command
  • capabilities() - Get all supported commands for current projector model
  • supports(command) - Check if a command is supported by the projector model
  • describe(command) - Get description of a command
  • info() - Get projector information (IP, model, spec)

Properties:

  • host - IP address
  • port - TCP port (default: 20554)
  • ip - Resolved IP address (available after connect)
  • model - Projector model name (available after connect)
  • spec - Projector specification (available after connect)

Command-Line Interface

The library includes a CLI tool:

% jvcprojector --help

Usage: jvcprojector <-h|--host HOST> [-p|--password PASSWORD] <command> [args...]

Commands:
  list                    List all available commands
  describe <command>      Describe a command
  get <command>           Get value of a command
  set <command> <value>   Set value of a command
  listen                  Listen for events  

Options:
  -h, --host HOST         Projector hostname or IP address
  -p, --password PASS     Projector password (if required)
  -m, --model MODEL       Model override (e.g. B8B1)
  -v, --verbose           Enable verbose logging

Development

The project is managed with uv:

git clone https://github.com/SteveEasley/pyjvcprojector.git
cd pyjvcprojector
uv sync
uv run prek install   # optional: run the checks on every commit

Running tests

uv run pytest

To test against another supported Python version:

uv run --python 3.11 pytest

Linting, type checking, and formatting

Checks run as prek hooks: ruff (linting and formatting), codespell, zizmor, yamllint, mypy, and pylint.

uv run prek run --all-files

Adding New Commands

The library uses a command system defined in jvcprojector/command/command.py. This file contains:

  1. Specifications and Models - Defines which projector models support which command sets
  2. Command Classes - Individual command implementations (55+ commands including Power, Input, PictureMode, etc.)

Command Structure

Each command class inherits from Command and defines:

class Power(Command):
    """Power command."""

    code = "PW"  # JVC protocol command code
    reference = True  # Supports reading (get)
    operation = True  # Supports writing (set)
    limp_mode = True  # Available in limp mode (unknown models)

    # Constants for command values
    OFF = "off"
    ON = "on"
    STANDBY = "standby"
    COOLING = "cooling"
    WARMING = "warming"

    # Parameter mapping between JVC codes and human-readable values
    parameter = MapParameter(
        size=1,
        read={"0": STANDBY, "1": ON, "2": COOLING, "3": WARMING},
        write={"0": OFF, "1": ON},
    )

Model-Specific Commands

Some commands are only available on certain models. Use conditional parameters:

class SomeCommand(Command):
    code = "XX"
    reference = True
    operation = True

    # Different parameters for different specifications
    parameter = {
        CS20241: MapParameter(size=1, readwrite={"0": "value1", "1": "value2"}),
        (CS20221, CS20191): MapParameter(size=1, readwrite={"0": "value1"}),
    }

Parameter Types

  • MapParameter - Maps JVC protocol values to human-readable strings

    • size - Expected response size in characters
    • read - Mapping for reference (get) operations
    • write - Mapping for operation (set) operations
    • readwrite - Shorthand when read/write mappings are identical
  • ModelParameter - Parses model names

  • MacAddressParameter - Formats MAC addresses

  • VersionParameter - Handles version strings

  • LaserPowerParameter - Converts laser power (hex to percentage)

  • LightTimeParameter - Converts light source time (hex to hours)

Specifications

The SPECIFICATIONS tuple at the top of command.py defines model families and their command support:

SPECIFICATIONS = (
    CS20241 := Spec(
        "CS20241",
        B8A2 := Model("B8A2"),  # RS3200, NZ800, etc.
        B8A1 := Model("B8A1"),  # RS4200, NZ900, etc.
    ),
    # ... more specs
)

Models are matched in order:

  1. Exact model name match
  2. Prefix match (first 3 characters)
  3. Falls back to "limp mode" with minimal command support

Adding a New Command

  1. Define the command class in command.py
  2. Set the JVC protocol code
  3. Mark as reference and/or operation
  4. Define the parameter (use MapParameter for most cases)
  5. Add human-readable constants for common values
  6. Optionally specify model-specific support using spec keys
  7. Run uv run python tools/update_imports.py to update imports

The command automatically registers itself and becomes available via command.YourCommandName.

License

This project is licensed under the terms specified in the LICENSE file included in this repository.

Metadata

Release files for pyjvcprojector 2.1.0

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

Source distribution (sdist)

Source distribution for pyjvcprojector 2.1.0
File Size Uploaded
pyjvcprojector-2.1.0.tar.gz 30.7 kB Details

Built distribution (wheel)

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

Total release size: 58.9 kB

Release files / pyjvcprojector-2.1.0.tar.gz

Download URL pyjvcprojector-2.1.0.tar.gz
Size 30.7 kB
Tags Source
SHA-256 checksum
How to use checksums
efdbac4c16ff5cffaf6958ad852dd43894d4d89f0007fe7f621211b0a3a73679
BLAKE2b-256 checksum
How to use checksums
b0539a731508b6dda14c17bd85175f33af408d0cd46a27b93f63f296a3c90a8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 12, 2026.

Transparency log

Release files / pyjvcprojector-2.1.0-py3-none-any.whl

Download URL pyjvcprojector-2.1.0-py3-none-any.whl
Size 28.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d29f14d3ab8cf02e3c04841ab32d2cff4b39690f02444acd0765a7b96c5f4cfe
BLAKE2b-256 checksum
How to use checksums
070cbb08b215aa8707b7c220b08de9dc82385ab5a9f75b31d8177ba9e2f30719
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 12, 2026.

Transparency log
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