Skip to content

Device Management

Manage and interact with discovered and known Samsung HVAC devices.

Device Types

NasaDevice

The base class for all devices:

device = nasa.devices["100000"]

print(device.address)           # Device address (string)
print(device.device_type)       # Device type (AddressClass enum)
print(device.last_packet_time)  # Last update time
print(device.attributes)        # All attributes dict
print(device.config)            # Configuration object

OutdoorNasaDevice

Represents outdoor units (typically address 100000):

outdoor = nasa.devices["100000"]

# Check if it's an outdoor device
if isinstance(outdoor, OutdoorNasaDevice):
    # Access outdoor-specific attributes
    print(outdoor.outdoor_temperature)
    print(outdoor.power_consumption)

IndoorNasaDevice

Represents indoor units (typically addresses 200020, 200021, etc.):

indoor = nasa.devices["200020"]

# Check if it's an indoor device
if isinstance(indoor, IndoorNasaDevice):
    # Access indoor-specific attributes
    if indoor.climate_controller:
        print(indoor.climate_controller.current_mode)
    if indoor.dhw_controller:
        print(indoor.dhw_controller.target_temperature)

Discovering Devices

Automatic Discovery

When you start the connection, devices advertise themselves:

nasa = SamsungNasa(
    host="192.168.1.100",
    port=8000,
    config={"client_address": 1}
)

await nasa.start()

# Wait for devices to appear
await asyncio.sleep(2)

# List discovered devices
for address, device in nasa.devices.items():
    print(f"{address}: {device.device_type}")

Known Devices

Pre-configure devices you want to monitor:

nasa = SamsungNasa(
    host="192.168.1.100",
    port=8000,
    config={
        "client_address": 1,
        "device_addresses": ["200000", "200020"]
    }
)

await nasa.start()

# Devices will be immediately available
outdoor = nasa.devices["100000"]
indoor = nasa.devices["200020"]

New Device Handler

Get notified when new devices appear:

async def on_new_device(device):
    print(f"New device found: {device.address}")
    print(f"Type: {device.device_type}")

    # Request its configuration
    await device.get_configuration()

nasa = SamsungNasa(
    host="192.168.1.100",
    port=8000,
    config={"client_address": 1},
    new_device_event_handler=on_new_device
)

await nasa.start()

Device Attributes

Universal Attributes

All devices have:

device = nasa.devices["100000"]

device.address           # Address string (e.g., "100000")
device.device_type      # AddressClass enum
device.last_packet_time # datetime of last update
device.attributes       # Dict of all attributes
device.config           # NasaConfig object
device.fsv_config       # FSV configuration dict

Outdoor Unit Attributes

outdoor = nasa.devices["100000"]

# Temperature
outdoor.outdoor_temperature         # Outdoor air temperature (°C)
outdoor.water_outlet_temperature    # Water outlet temp (°C)

# Power
outdoor.power_consumption           # Instantaneous power (W)
outdoor.power_current               # Current draw (A)
outdoor.power_produced              # Power produced (W)
outdoor.power_generated_last_minute # Power in last minute (W)
outdoor.cumulative_energy           # Total energy (kWh)

# Performance
outdoor.cop_rating                  # Efficiency rating
outdoor.compressor_frequency        # Compressor speed (Hz)
outdoor.fan_speed                   # Fan speed (RPM)

# Status
outdoor.heatpump_voltage           # Operating voltage (V)

Indoor Unit Attributes

indoor = nasa.devices["200020"]

# Check if controllers are available
has_climate = indoor.climate_controller is not None
has_dhw = indoor.dhw_controller is not None

# Climate control
if has_climate:
    cc = indoor.climate_controller
    cc.power                       # On/off status
    cc.current_mode                # Current mode (cool, heat, etc)
    cc.f_current_temperature       # Current room temp (°C)
    cc.f_target_temperature        # Target temp (°C)
    cc.current_humidity            # Humidity (%)
    cc.current_fan_mode            # Fan mode
    cc.current_fan_speed           # Fan speed (1-4)

# DHW control
if has_dhw:
    dhw = indoor.dhw_controller
    dhw.power                      # On/off status
    dhw.target_temperature         # Target temp (°C)
    dhw.current_temperature        # Current temp (°C)
    dhw.operation_mode             # Operating mode

Accessing Device Configuration

Get the FSV (Feature/Setting/Value) configuration:

device = nasa.devices["200020"]

# Get all FSV settings
fsv_config = device.fsv_config

# FSV is a dictionary of message ID to values
for msg_id, value in fsv_config.items():
    print(f"Message 0x{msg_id:04X}: {value}")

# Request configuration
await device.get_configuration()

Device State Management

Getting Raw Attributes

Access the raw attribute dictionary:

device = nasa.devices["100000"]

# Get all attributes
all_attrs = device.attributes
print(f"Total attributes: {len(all_attrs)}")

# Access a specific attribute by message ID
if 0x4203 in device.attributes:
    value = device.attributes[0x4203]
    print(f"Message 0x4203: {value}")

Checking Last Update

Monitor device responsiveness:

import time
from datetime import datetime, timezone

device = nasa.devices["100000"]

# Check when last updated
if device.last_packet_time:
    elapsed = datetime.now(timezone.utc) - device.last_packet_time
    print(f"Last update: {elapsed.total_seconds():.1f} seconds ago")
else:
    print("No data yet")

Device Callbacks

Device Update Callbacks

Register functions to be called when device data changes:

def on_update(device):
    print(f"Device {device.address} updated at {device.last_packet_time}")

device = nasa.devices["100000"]
device.add_device_callback(on_update)

# Later, remove it
device.remove_device_callback(on_update)

Message-Specific Callbacks

Listen for specific message types:

from pysamsungnasa.protocol.factory.messages.indoor import IndoorCurrentTemperature

def on_temp_message(device, **kwargs):
    message = kwargs['packet']
    print(f"Temperature update: {message.VALUE}")

indoor = nasa.devices["200020"]

# Add callback for message type (current temperature)
indoor.add_packet_callback(IndoorCurrentTemperature, on_temp_message)

# Later, remove it
indoor.remove_packet_callback(IndoorCurrentTemperature, on_temp_message)

Multiple Device Management

Iterate Over All Devices

for address, device in nasa.devices.items():
    print(f"\nDevice: {address}")
    print(f"  Type: {device.device_type}")
    print(f"  Last update: {device.last_packet_time}")

    # Register callbacks
    device.add_device_callback(lambda d: print(f"  Updated: {d.address}"))

Find Devices by Type

from pysamsungnasa.device import OutdoorNasaDevice, IndoorNasaDevice

outdoor_units = [d for d in nasa.devices.values() if isinstance(d, OutdoorNasaDevice)]
indoor_units = [d for d in nasa.devices.values() if isinstance(d, IndoorNasaDevice)]

print(f"Outdoor units: {len(outdoor_units)}")
print(f"Indoor units: {len(indoor_units)}")

Synchronize Multiple Devices

async def set_all_targets(nasa, temperature):
    """Set target temperature on all indoor units."""
    for device in nasa.devices.values():
        if isinstance(device, IndoorNasaDevice):
            if device.climate_controller:
                await device.climate_controller.set_target_temperature(temperature)
                print(f"Set {device.address} to {temperature}°C")

Device Information Display

def print_device_summary(device):
    print(f"Device: {device.address}")
    print(f"  Type: {device.device_type}")
    print(f"  Attributes: {len(device.attributes)}")
    print(f"  Last update: {device.last_packet_time}")

    if hasattr(device, 'outdoor_temperature'):
        print(f"  Outdoor temp: {device.outdoor_temperature}°C")

    if hasattr(device, 'climate_controller') and device.climate_controller:
        cc = device.climate_controller
        print(f"  Climate power: {cc.power}")
        print(f"  Current mode: {cc.current_mode}")
        print(f"  Target temp: {cc.f_target_temperature}°C")

for device in nasa.devices.values():
    print_device_summary(device)
    print()

Troubleshooting Device Issues

Device Not Responding

async def check_device_health(device):
    """Check if a device is responding."""
    if device.last_packet_time is None:
        print(f"{device.address}: Never received data")
        return False

    from datetime import datetime, timezone, timedelta
    elapsed = datetime.now(timezone.utc) - device.last_packet_time

    if elapsed > timedelta(minutes=5):
        print(f"{device.address}: No update for {elapsed.total_seconds():.0f}s")
        return False

    print(f"{device.address}: OK (updated {elapsed.total_seconds():.0f}s ago)")
    return True

for device in nasa.devices.values():
    await check_device_health(device)

Missing Attributes

def check_attributes(device):
    """Verify expected attributes exist."""
    expected = {0x4203: "Current Temperature", 0x4201: "Target Temperature"}

    for msg_id, name in expected.items():
        if msg_id in device.attributes:
            print(f"✓ {name} present")
        else:
            print(f"✗ {name} MISSING")

    # Request configuration to fill missing values
    if len(device.attributes) < len(expected):
        print("Requesting configuration...")
        await device.get_configuration()

await check_attributes(indoor)

Next Steps