nwp500.models package

Submodules

nwp500.models.device module

class nwp500.models.device.Device(*, deviceInfo: DeviceInfo, location: Location)[source]

Bases: NavienBaseModel

Complete device information including location.

device_info: DeviceInfo
location: Location
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

with_info(info: DeviceInfo) Self[source]

Return a new Device instance with updated DeviceInfo.

class nwp500.models.device.DeviceInfo(*, homeSeq: int = 0, macAddress: str = '', additionalValue: str = '', deviceType: DeviceType | int = DeviceType.NPF700_WIFI, deviceName: str = 'Unknown', connected: ConnectionStatus, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.enum_validator.<locals>.validate, json_schema_input_type=PydanticUndefined)] = ConnectionStatus.DISCONNECTED, installType: str | None = None)[source]

Bases: NavienBaseModel

Device information from API.

additional_value: str
connected: ConnectionStatusField
device_name: str
device_type: DeviceType | int
home_seq: int
install_type: str | None
mac_address: str
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class nwp500.models.device.FirmwareInfo(*, macAddress: str = '', additionalValue: str = '', deviceType: DeviceType | int = DeviceType.NPF700_WIFI, curSwCode: int = 0, curVersion: int = 0, downloadedVersion: int | None = None, deviceGroup: str | None = None)[source]

Bases: NavienBaseModel

Firmware information for a device.

additional_value: str
cur_sw_code: int
cur_version: int
device_group: str | None
device_type: DeviceType | int
downloaded_version: int | None
mac_address: str
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class nwp500.models.device.Location(*, state: str | None = None, city: str | None = None, address: str | None = None, latitude: float | None = None, longitude: float | None = None, altitude: float | None = None)[source]

Bases: NavienBaseModel

Location information for a device.

address: str | None
altitude: float | None
city: str | None
latitude: float | None
longitude: float | None
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

state: str | None

nwp500.models.energy module

class nwp500.models.energy.EnergyUsageBase(*, hpUsage: int = 0, heUsage: int = 0, hpTime: int = 0, heTime: int = 0)[source]

Bases: NavienBaseModel

Base energy usage fields common to daily and total responses.

heat_element_time: int
heat_element_usage: int
heat_pump_time: int
heat_pump_usage: int
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property total_usage: int
class nwp500.models.energy.EnergyUsageDay(*, hpUsage: int = 0, heUsage: int = 0, hpTime: int = 0, heTime: int = 0)[source]

Bases: EnergyUsageBase

Daily energy usage data.

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class nwp500.models.energy.EnergyUsageResponse(*, total: EnergyUsageTotal, usage: list[MonthlyEnergyData])[source]

Bases: NavienBaseModel

Response for energy usage query.

get_month_data(year: int, month: int) MonthlyEnergyData | None[source]

Get energy usage data for a specific month.

Parameters:
  • year – Year (e.g., 2025)

  • month – Month (1-12)

Returns:

MonthlyEnergyData for that month, or None if not found

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

total: EnergyUsageTotal
usage: list[MonthlyEnergyData]
class nwp500.models.energy.EnergyUsageTotal(*, hpUsage: int = 0, heUsage: int = 0, hpTime: int = 0, heTime: int = 0)[source]

Bases: EnergyUsageBase

Total energy usage data.

property heat_element_percentage: float
property heat_pump_percentage: float
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property total_time: int
class nwp500.models.energy.MonthlyEnergyData(*, year: int, month: int, data: list[EnergyUsageDay])[source]

Bases: NavienBaseModel

Monthly energy usage data grouping.

data: list[EnergyUsageDay]
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

month: int
year: int

nwp500.models.feature module

class nwp500.models.feature.DeviceFeature(*, temperatureType: ~nwp500.enums.TemperatureType = TemperatureType.FAHRENHEIT, macAddress: str | None = None, countryCode: int, modelTypeCode: ~nwp500.enums.UnitType | int, controlTypeCode: int, volumeCode: ~typing.Annotated[~nwp500.enums.VolumeCode, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.enum_validator.<locals>.validate, json_schema_input_type=PydanticUndefined)], controllerSwVersion: int, panelSwVersion: int, wifiSwVersion: int, controllerSwCode: int, panelSwCode: int, wifiSwCode: int, recircSwVersion: int, recircModelTypeCode: int, controllerSerialNumber: str, powerUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, holidayUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, programReservationUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, dhwUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, dhwTemperatureSettingUse: ~nwp500.enums.DHWControlTypeFlag, smartDiagnosticUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, wifiRssiUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, tempFormulaType: ~nwp500.enums.TempFormulaType = TempFormulaType.ASYMMETRIC, energyUsageUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, freezeProtectionUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, mixingValveUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, drSettingUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, antiLegionellaSettingUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, hpwhUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, dhwRefillUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, ecoUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, electricUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, heatpumpUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, energySaverUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, highDemandUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, recirculationUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, recircReservationUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, title24Use: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, dhwTemperatureMin: int = None, dhwTemperatureMax: int = None, freezeProtectionTempMin: int = None, freezeProtectionTempMax: int = None, recircTemperatureMin: int = None, recircTemperatureMax: int = None)[source]

Bases: NavienBaseModel

Device capabilities, configuration, and firmware info.

anti_legionella_setting_use: CapabilityFlag
control_type_code: int
controller_serial_number: str
controller_sw_code: int
controller_sw_version: int
country_code: int
dhw_refill_use: CapabilityFlag
property dhw_temperature_max: float
dhw_temperature_max_raw: int
property dhw_temperature_min: float
dhw_temperature_min_raw: int
dhw_temperature_setting_use: DHWControlTypeFlag
dhw_use: CapabilityFlag
dr_setting_use: CapabilityFlag
eco_use: CapabilityFlag
electric_use: CapabilityFlag
energy_saver_use: CapabilityFlag
energy_usage_use: CapabilityFlag
property freeze_protection_temp_max: float
freeze_protection_temp_max_raw: int
property freeze_protection_temp_min: float
freeze_protection_temp_min_raw: int
freeze_protection_use: CapabilityFlag
get_field_unit(field_name: str) str[source]

Get the correct unit suffix based on temperature preference.

Resolves dynamic units for temperature, flow rate, and volume fields that change based on unit system context override or the device’s temperature_type setting (Celsius or Fahrenheit).

Parameters:

field_name – Name of the field to get the unit for

Returns:

Unit string (e.g., “ °C”, “ LPM”, “ L”) or empty if field not found

heatpump_use: CapabilityFlag
high_demand_use: CapabilityFlag
holiday_use: CapabilityFlag
hpwh_use: CapabilityFlag
mac_address: str | None
mixing_valve_use: CapabilityFlag
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_type_code: UnitType | int
panel_sw_code: int
panel_sw_version: int
power_use: CapabilityFlag
program_reservation_use: CapabilityFlag
recirc_model_type_code: int
recirc_reservation_use: CapabilityFlag
recirc_sw_version: int
property recirc_temperature_max: float
recirc_temperature_max_raw: int
property recirc_temperature_min: float
recirc_temperature_min_raw: int
recirculation_use: CapabilityFlag
smart_diagnostic_use: CapabilityFlag
temp_formula_type: TempFormulaType
temperature_type: TemperatureType
title24_use: CapabilityFlag
volume_code: VolumeCodeField
wifi_rssi_use: CapabilityFlag
wifi_sw_code: int
wifi_sw_version: int

nwp500.models.mqtt_models module

class nwp500.models.mqtt_models.MqttCommand(*, clientID: str, sessionID: str, requestTopic: str, responseTopic: str, request: MqttRequest | dict[str, Any], protocolVersion: int = 2)[source]

Bases: NavienBaseModel

Represents an MQTT command message.

client_id: str
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

protocol_version: int
request: MqttRequest | dict[str, Any]
request_topic: str
response_topic: str
session_id: str
class nwp500.models.mqtt_models.MqttRequest(*, command: int, deviceType: DeviceType | int, macAddress: str, additionalValue: str = '...', mode: str | None = None, param: list[int | float] = <factory>, paramStr: str = '', month: list[int] | None = None, year: int | None = None)[source]

Bases: NavienBaseModel

MQTT command request payload.

additional_value: str
command: int
device_type: DeviceType | int
mac_address: str
mode: str | None
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

month: list[int] | None
param: list[int | float]
param_str: str
year: int | None

nwp500.models.schedule module

class nwp500.models.schedule.OtaCommitPayload(*, swCode: int, swVersion: int)[source]

Bases: NavienBaseModel

Payload for committing a firmware component update.

Used with the OTA_COMMIT command (33554442). This command uses a special commitOta structure instead of the standard mode/param format.

Parameters:
  • sw_code – Software component code identifying which firmware to commit. 1 = Controller, 2 = Panel, 4 = WiFi/communication module.

  • sw_version – Version number to commit (as reported by the OTA check).

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

sw_code: int
sw_version: int
class nwp500.models.schedule.RecirculationSchedule(*, schedule: list[RecirculationScheduleEntry] = <factory>)[source]

Bases: NavienBaseModel

Complete recirculation pump schedule (RECIR_RESERVATION command).

Used with command code 33554444 to configure timed recirculation pump operation windows.

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

schedule: list[RecirculationScheduleEntry]
class nwp500.models.schedule.RecirculationScheduleEntry(*, enable: int = 2, week: int = 0, startHour: int = 0, startMin: int = 0, endHour: int = 0, endMin: int = 0, mode: int = 1)[source]

Bases: NavienBaseModel

A single entry in a recirculation pump schedule.

Used with the RECIR_RESERVATION command (33554444) to set timed recirculation cycles. Each entry defines a time window and pump mode.

Fields:
  • enable: 2=enabled, 1=disabled (device boolean)

  • week: bitfield of active days (Sun=bit7, Mon=bit6, …, Sat=bit1)

  • start_hour: 0-23

  • start_min: 0-59

  • end_hour: 0-23

  • end_min: 0-59

  • mode: recirculation mode (1=Constant, 2=Timer, 3=Temperature, 4=Sensor)

property days: list[str]

Weekday names for this entry.

enable: int
property enabled: bool

2=on, 1=off).

Type:

Whether this entry is active (device bool

end_hour: int
end_min: int
property end_time: str

MM).

Type:

Formatted end time string (HH

mode: int
property mode_name: str

Human-readable recirculation mode name.

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

start_hour: int
start_min: int
property start_time: str

MM).

Type:

Formatted start time string (HH

week: int
class nwp500.models.schedule.ReservationEntry(*, enable: int = 2, week: int = 0, hour: int = 0, min: int = 0, mode: int = 1, param: int = 0)[source]

Bases: NavienBaseModel

A single scheduled reservation entry.

Wraps the raw 6-byte protocol fields and provides computed properties for display-ready values including unit-aware temperature conversion.

The raw protocol fields are:
  • enable: 2=enabled, 1=disabled (device boolean)

  • week: bitfield of active days (Sun=bit7, Mon=bit6, …, Sat=bit1)

  • hour: 0-23

  • min: 0-59

  • mode: DHW operation mode ID (1-6)

  • param: temperature in half-degrees Celsius

property days: list[str]

Weekday names for this reservation.

enable: int
property enabled: bool

2=on, 1=off).

Type:

Whether this reservation is active (device bool

hour: int
min: int
mode: int
property mode_name: str

Human-readable operation mode name.

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

param: int
property temperature: float

Temperature in the user’s preferred unit.

property time: str

MM).

Type:

Formatted time string (HH

property unit: str

Temperature unit symbol.

week: int
class nwp500.models.schedule.ReservationSchedule(*, reservationUse: int = 0, reservation: list[ReservationEntry] = <factory>)[source]

Bases: NavienBaseModel

Complete reservation schedule from the device.

Can be constructed from raw MQTT response data. The reservation field accepts either a hex string (from GET responses) or a list of dicts/ReservationEntry objects.

property enabled: bool

Whether the reservation system is globally enabled.

Device bool convention: 2=on, 1=off.

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

reservation: list[ReservationEntry]
reservation_use: int
class nwp500.models.schedule.WeeklyReservationEntry(*, enable: int = 2, week: int = 0, hour: int = 0, min: int = 0, mode: int = 1, param: int = 0)[source]

Bases: NavienBaseModel

A single entry in a weekly temperature reservation schedule.

Similar to ReservationEntry but used with the RESERVATION_WEEKLY command (33554438), which configures a separate weekly temperature schedule independent of the timed reservation system.

The raw protocol fields mirror the standard reservation format:
  • enable: 2=enabled, 1=disabled (device boolean)

  • week: bitfield of active days (Sun=bit7, Mon=bit6, …, Sat=bit1)

  • hour: 0-23

  • min: 0-59

  • mode: DHW operation mode ID (1-6)

  • param: temperature in half-degrees Celsius

property days: list[str]

Weekday names for this entry.

enable: int
property enabled: bool

2=on, 1=off).

Type:

Whether this entry is active (device bool

hour: int
min: int
mode: int
property mode_name: str

Human-readable operation mode name.

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

param: int
property temperature: float

Temperature in the user’s preferred unit.

property time: str

MM).

Type:

Formatted time string (HH

property unit: str

Temperature unit symbol.

week: int
class nwp500.models.schedule.WeeklyReservationSchedule(*, reservationUse: int = 0, reservation: list[WeeklyReservationEntry] = <factory>)[source]

Bases: NavienBaseModel

Complete weekly reservation schedule (RESERVATION_WEEKLY command).

Used with command code 33554438 to configure a temperature schedule that repeats weekly. Accepts the same hex-encoded format as the standard reservation schedule.

property enabled: bool

Whether the weekly reservation system is globally enabled.

Device bool convention: 2=on, 1=off.

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

reservation: list[WeeklyReservationEntry]
reservation_use: int

nwp500.models.status module

class nwp500.models.status.DeviceStatus(*, temperatureType: TemperatureType = TemperatureType.FAHRENHEIT, macAddress: str | None = None, command: int, specialFunctionStatus: int, errorCode: ErrorCode = ErrorCode.NO_ERROR, subErrorCode: int, smartDiagnostic: int, faultStatus1: int, faultStatus2: int, wifiRssi: int = None, dhwChargePer: float, drEventStatus: DREvent = DREvent.UNKNOWN, vacationDaySetting: int, vacationDayElapsed: int, antiLegionellaPeriod: int, programReservationType: int, tempFormulaType: TempFormulaType, outsideTemperature: int = None, currentStatenum: int, targetFanRpm: int, currentFanRpm: int, fanPwm: int, mixingRate: float, eevStep: int, airFilterAlarmPeriod: int, airFilterAlarmElapsed: int, cumulatedOpTimeEvaFan: int, cumulatedDhwFlowRate: int, touStatus: Annotated[bool, BeforeValidator(func=bool, json_schema_input_type=PydanticUndefined)], drOverrideStatus: int, touOverrideStatus: Annotated[bool, BeforeValidator(func=tou_override_to_python, json_schema_input_type=PydanticUndefined)], totalEnergyCapacity: Annotated[float, BeforeValidator(func=mul_10, json_schema_input_type=PydanticUndefined)], availableEnergyCapacity: Annotated[float, BeforeValidator(func=mul_10, json_schema_input_type=PydanticUndefined)], recircOperationMode: RecirculationMode, recircPumpOperationStatus: int, recircHotBtnReady: int, recircOperationReason: int, recircErrorStatus: int, currentInstPower: float, didReload: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], operationBusy: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], freezeProtectionUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], dhwUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], dhwUseSustained: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], dhwOperationBusy: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, programReservationUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], ecoUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], compUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], eevUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], evaFanUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], shutOffValveUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], conOvrSensorUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], wtrOvrSensorUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], antiLegionellaUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], antiLegionellaOperationBusy: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], errorBuzzerUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], currentHeatUse: HeatSource, heatUpperUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], heatLowerUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], scaldUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], airFilterAlarmUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], recircOperationBusy: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], recircReservationUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], dhwTemperature: int = None, dhwTemperatureSetting: int = None, dhwTargetTemperatureSetting: int = None, freezeProtectionTemperature: int = None, dhwTemperature2: int = None, hpUpperOnTempSetting: int = None, hpUpperOffTempSetting: int = None, hpLowerOnTempSetting: int = None, hpLowerOffTempSetting: int = None, heUpperOnTempSetting: int = None, heUpperOffTempSetting: int = None, heLowerOnTempSetting: int = None, heLowerOffTempSetting: int = None, heatMinOpTemperature: int = None, recircTempSetting: int = None, recircTemperature: int = None, recircFaucetTemperature: int = None, currentInletTemperature: int = None, currentDhwFlowRate: int, hpUpperOnDiffTempSetting: int, hpUpperOffDiffTempSetting: int, hpLowerOnDiffTempSetting: int, hpLowerOffDiffTempSetting: int, heUpperOnDiffTempSetting: int, heUpperOffDiffTempSetting: int, heLowerOnTDiffempSetting: int, heLowerOffDiffTempSetting: int, recircDhwFlowRate: int, tankUpperTemperature: int = None, tankLowerTemperature: int = None, dischargeTemperature: int = None, suctionTemperature: int = None, evaporatorTemperature: int = None, ambientTemperature: int = None, targetSuperHeat: int = None, currentSuperHeat: int = None, operationMode: CurrentOperationMode = CurrentOperationMode.STANDBY, dhwOperationSetting: DhwOperationSetting = DhwOperationSetting.ENERGY_SAVER, freezeProtectionTempMin: int = 43, freezeProtectionTempMax: int = 65)[source]

Bases: NavienBaseModel

Represents the status of the Navien water heater device.

air_filter_alarm_elapsed: int
air_filter_alarm_period: int
air_filter_alarm_use: DeviceBool
property ambient_temperature: float
ambient_temperature_raw: int
anti_legionella_operation_busy: DeviceBool
anti_legionella_period: int
anti_legionella_use: DeviceBool
available_energy_capacity: TenWhToWh
command: int
comp_use: DeviceBool
con_ovr_sensor_use: DeviceBool
property cumulated_dhw_flow_rate: float
cumulated_dhw_flow_rate_raw: int
cumulated_op_time_eva_fan: int
property current_dhw_flow_rate: float
current_dhw_flow_rate_raw: int
current_fan_rpm: int
current_heat_use: HeatSource
property current_inlet_temperature: float
current_inlet_temperature_raw: int
current_inst_power: float
current_statenum: int
property current_super_heat: float
current_super_heat_raw: int
dhw_charge_per: float
dhw_operation_busy: DeviceBool
dhw_operation_setting: DhwOperationSetting
property dhw_target_temperature_setting: float
dhw_target_temperature_setting_raw: int
property dhw_temperature: float
property dhw_temperature2: float
dhw_temperature2_raw: int
dhw_temperature_raw: int
property dhw_temperature_setting: float
dhw_temperature_setting_raw: int
dhw_use: DeviceBool
dhw_use_sustained: DeviceBool
did_reload: DeviceBool
property discharge_temperature: float
discharge_temperature_raw: int
dr_event_status: DREvent
dr_override_status: int
eco_use: DeviceBool
eev_step: int
eev_use: DeviceBool
error_buzzer_use: DeviceBool
error_code: ErrorCode
eva_fan_use: DeviceBool
property evaporator_temperature: float
evaporator_temperature_raw: int
fan_pwm: int
fault_status1: int
fault_status2: int
property freeze_protection_temp_max: float
freeze_protection_temp_max_raw: int
property freeze_protection_temp_min: float
freeze_protection_temp_min_raw: int
property freeze_protection_temperature: float
freeze_protection_temperature_raw: int
freeze_protection_use: DeviceBool
get_field_unit(field_name: str) str[source]

Get the correct unit suffix based on temperature preference.

Resolves dynamic units for temperature, flow rate, and volume fields that change based on unit system context override or the device’s temperature_type setting (Celsius or Fahrenheit).

Parameters:

field_name – Name of the field to get the unit for

Returns:

Unit string (e.g., “ °C”, “ LPM”, “ L”) or empty if field not found

property he_lower_off_diff_temp_setting: float
he_lower_off_diff_temp_setting_raw: int
property he_lower_off_temp_setting: float
he_lower_off_temp_setting_raw: int
property he_lower_on_diff_temp_setting: float
he_lower_on_diff_temp_setting_raw: int
property he_lower_on_temp_setting: float
he_lower_on_temp_setting_raw: int
property he_upper_off_diff_temp_setting: float
he_upper_off_diff_temp_setting_raw: int
property he_upper_off_temp_setting: float
he_upper_off_temp_setting_raw: int
property he_upper_on_diff_temp_setting: float
he_upper_on_diff_temp_setting_raw: int
property he_upper_on_temp_setting: float
he_upper_on_temp_setting_raw: int
heat_lower_use: DeviceBool
property heat_min_op_temperature: float
heat_min_op_temperature_raw: int
heat_upper_use: DeviceBool
property hp_lower_off_diff_temp_setting: float
hp_lower_off_diff_temp_setting_raw: int
property hp_lower_off_temp_setting: float
hp_lower_off_temp_setting_raw: int
property hp_lower_on_diff_temp_setting: float
hp_lower_on_diff_temp_setting_raw: int
property hp_lower_on_temp_setting: float
hp_lower_on_temp_setting_raw: int
property hp_upper_off_diff_temp_setting: float
hp_upper_off_diff_temp_setting_raw: int
property hp_upper_off_temp_setting: float
hp_upper_off_temp_setting_raw: int
property hp_upper_on_diff_temp_setting: float
hp_upper_on_diff_temp_setting_raw: int
property hp_upper_on_temp_setting: float
hp_upper_on_temp_setting_raw: int
mac_address: str | None
mixing_rate: float
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

operation_busy: DeviceBool
operation_mode: CurrentOperationMode
property outside_temperature: float
outside_temperature_raw: int
program_reservation_type: int
program_reservation_use: DeviceBool
property recirc_dhw_flow_rate: float
recirc_dhw_flow_rate_raw: int
recirc_error_status: int
property recirc_faucet_temperature: float
recirc_faucet_temperature_raw: int
recirc_hot_btn_ready: int
recirc_operation_busy: DeviceBool
recirc_operation_mode: RecirculationMode
recirc_operation_reason: int
recirc_pump_operation_status: int
recirc_reservation_use: DeviceBool
property recirc_temp_setting: float
recirc_temp_setting_raw: int
property recirc_temperature: float
recirc_temperature_raw: int
scald_use: DeviceBool
shut_off_valve_use: DeviceBool
smart_diagnostic: int
special_function_status: int
sub_error_code: int
property suction_temperature: float
suction_temperature_raw: int
property tank_lower_temperature: float
tank_lower_temperature_raw: int
property tank_upper_temperature: float
tank_upper_temperature_raw: int
target_fan_rpm: int
property target_super_heat: float
target_super_heat_raw: int
temp_formula_type: TempFormulaType
temperature_type: TemperatureType
total_energy_capacity: TenWhToWh
tou_override_status: TouOverride
tou_status: TouStatus
vacation_day_elapsed: int
vacation_day_setting: int
wifi_rssi: int
wtr_ovr_sensor_use: DeviceBool

nwp500.models.tou module

class nwp500.models.tou.ConvertedTOUPlan(*, utility: str = '', name: str = '', schedule: list[TOUSchedule] = <factory>)[source]

Bases: NavienBaseModel

A rate plan converted by the Navien backend from OpenEI format.

Returned by POST /device/tou/convert. Contains the utility name, plan name, and device-ready schedule with season/week bitfields and scaled pricing.

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str
schedule: list[TOUSchedule]
utility: str
class nwp500.models.tou.TOUInfo(*, registerPath: str = '', sourceType: str = '', controllerId: str = '', manufactureId: str = '', name: str = '', utility: str = '', zipCode: int = 0, schedule: list[TOUSchedule] = <factory>)[source]

Bases: NavienBaseModel

Time of Use information.

controller_id: str
manufacture_id: str
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str
register_path: str
schedule: list[TOUSchedule]
source_type: str
utility: str
zip_code: int
class nwp500.models.tou.TOUPeriod(*, season: int = 0, week: int = 0, startHour: int = 0, startMinute: int = 0, endHour: int = 0, endMinute: int = 0, priceMin: int = 0, priceMax: int = 0, decimalPoint: int = 5)[source]

Bases: NavienBaseModel

A single TOU pricing period from an MQTT tou/rd response.

Each period defines a time window, active season/week bitfields, and the pricing range for that window.

Fields use camelCase aliases to match the raw MQTT payload:
  • season: bitfield of active months (bit N-1 set for month N)

  • week: bitfield of active weekdays (Sun=bit7, …, Sat=bit1)

  • startHour / startMinute: start of the time window (0-23 / 0-59)

  • endHour / endMinute: end of the time window (0-23 / 0-59)

  • priceMin / priceMax: encoded integer prices (divide by 10^decimalPoint)

  • decimalPoint: number of decimal places for price values

decimal_point: int
property decoded_price_max: float

Maximum price decoded to a float (price_max / 10^decimal_point).

property decoded_price_min: float

Minimum price decoded to a float (price_min / 10^decimal_point).

end_hour: int
end_min: int
property end_time: str

MM).

Type:

Formatted end time (HH

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

price_max: int
price_min: int
season: int
start_hour: int
start_min: int
property start_time: str

MM).

Type:

Formatted start time (HH

week: int
class nwp500.models.tou.TOUReservationSchedule(*, reservationUse: int = 0, reservation: list[TOUPeriod] = <factory>)[source]

Bases: NavienBaseModel

TOU schedule as returned by the MQTT tou/rd response topic.

This model matches the raw MQTT payload for both request_tou_settings() read responses and configure_tou_schedule() write confirmations — both use CommandCode.TOU_RESERVATION and the tou/rd response topic.

The payload structure is:

{
    "reservationUse": 2,          # 0=disabled, 2=enabled
    "reservation": [              # list of TOU period dicts
        {
            "season": 4095, "week": 254,
            "startHour": 0, "startMinute": 0,
            "endHour": 23, "endMinute": 59,
            "priceMin": 10, "priceMax": 25,
            "decimalPoint": 2
        },
        ...
    ]
}
property enabled: bool

Whether TOU scheduling is globally enabled.

Protocol convention: 0=disabled, 2=enabled.

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

reservation: list[TOUPeriod]
reservation_use: int
class nwp500.models.tou.TOUSchedule(*, season: int = 0, interval: list[dict[str, ~typing.Any]]=<factory>)[source]

Bases: NavienBaseModel

Time of Use schedule information.

intervals: list[dict[str, Any]]
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

season: int

Module contents

Data models for Navien NWP500 water heater communication.

This module defines data classes for representing data structures used in the Navien NWP500 water heater communication protocol.

These models are based on the MQTT message formats and API responses.

class nwp500.models.ConvertedTOUPlan(*, utility: str = '', name: str = '', schedule: list[TOUSchedule] = <factory>)[source]

Bases: NavienBaseModel

A rate plan converted by the Navien backend from OpenEI format.

Returned by POST /device/tou/convert. Contains the utility name, plan name, and device-ready schedule with season/week bitfields and scaled pricing.

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str
schedule: list[TOUSchedule]
utility: str
class nwp500.models.Device(*, deviceInfo: DeviceInfo, location: Location)[source]

Bases: NavienBaseModel

Complete device information including location.

device_info: DeviceInfo
location: Location
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

with_info(info: DeviceInfo) Self[source]

Return a new Device instance with updated DeviceInfo.

class nwp500.models.DeviceFeature(*, temperatureType: ~nwp500.enums.TemperatureType = TemperatureType.FAHRENHEIT, macAddress: str | None = None, countryCode: int, modelTypeCode: ~nwp500.enums.UnitType | int, controlTypeCode: int, volumeCode: ~typing.Annotated[~nwp500.enums.VolumeCode, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.enum_validator.<locals>.validate, json_schema_input_type=PydanticUndefined)], controllerSwVersion: int, panelSwVersion: int, wifiSwVersion: int, controllerSwCode: int, panelSwCode: int, wifiSwCode: int, recircSwVersion: int, recircModelTypeCode: int, controllerSerialNumber: str, powerUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, holidayUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, programReservationUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, dhwUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, dhwTemperatureSettingUse: ~nwp500.enums.DHWControlTypeFlag, smartDiagnosticUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, wifiRssiUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, tempFormulaType: ~nwp500.enums.TempFormulaType = TempFormulaType.ASYMMETRIC, energyUsageUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, freezeProtectionUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, mixingValveUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, drSettingUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, antiLegionellaSettingUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, hpwhUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, dhwRefillUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, ecoUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, electricUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, heatpumpUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, energySaverUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, highDemandUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, recirculationUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, recircReservationUse: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, title24Use: ~typing.Annotated[bool, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, dhwTemperatureMin: int = None, dhwTemperatureMax: int = None, freezeProtectionTempMin: int = None, freezeProtectionTempMax: int = None, recircTemperatureMin: int = None, recircTemperatureMax: int = None)[source]

Bases: NavienBaseModel

Device capabilities, configuration, and firmware info.

anti_legionella_setting_use: CapabilityFlag
control_type_code: int
controller_serial_number: str
controller_sw_code: int
controller_sw_version: int
country_code: int
dhw_refill_use: CapabilityFlag
property dhw_temperature_max: float
dhw_temperature_max_raw: int
property dhw_temperature_min: float
dhw_temperature_min_raw: int
dhw_temperature_setting_use: DHWControlTypeFlag
dhw_use: CapabilityFlag
dr_setting_use: CapabilityFlag
eco_use: CapabilityFlag
electric_use: CapabilityFlag
energy_saver_use: CapabilityFlag
energy_usage_use: CapabilityFlag
property freeze_protection_temp_max: float
freeze_protection_temp_max_raw: int
property freeze_protection_temp_min: float
freeze_protection_temp_min_raw: int
freeze_protection_use: CapabilityFlag
get_field_unit(field_name: str) str[source]

Get the correct unit suffix based on temperature preference.

Resolves dynamic units for temperature, flow rate, and volume fields that change based on unit system context override or the device’s temperature_type setting (Celsius or Fahrenheit).

Parameters:

field_name – Name of the field to get the unit for

Returns:

Unit string (e.g., “ °C”, “ LPM”, “ L”) or empty if field not found

heatpump_use: CapabilityFlag
high_demand_use: CapabilityFlag
holiday_use: CapabilityFlag
hpwh_use: CapabilityFlag
mac_address: str | None
mixing_valve_use: CapabilityFlag
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_type_code: UnitType | int
panel_sw_code: int
panel_sw_version: int
power_use: CapabilityFlag
program_reservation_use: CapabilityFlag
recirc_model_type_code: int
recirc_reservation_use: CapabilityFlag
recirc_sw_version: int
property recirc_temperature_max: float
recirc_temperature_max_raw: int
property recirc_temperature_min: float
recirc_temperature_min_raw: int
recirculation_use: CapabilityFlag
smart_diagnostic_use: CapabilityFlag
temp_formula_type: TempFormulaType
temperature_type: TemperatureType
title24_use: CapabilityFlag
volume_code: VolumeCodeField
wifi_rssi_use: CapabilityFlag
wifi_sw_code: int
wifi_sw_version: int
class nwp500.models.DeviceInfo(*, homeSeq: int = 0, macAddress: str = '', additionalValue: str = '', deviceType: DeviceType | int = DeviceType.NPF700_WIFI, deviceName: str = 'Unknown', connected: ConnectionStatus, ~pydantic.functional_validators.BeforeValidator(func=~nwp500.converters.enum_validator.<locals>.validate, json_schema_input_type=PydanticUndefined)] = ConnectionStatus.DISCONNECTED, installType: str | None = None)[source]

Bases: NavienBaseModel

Device information from API.

additional_value: str
connected: ConnectionStatusField
device_name: str
device_type: DeviceType | int
home_seq: int
install_type: str | None
mac_address: str
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class nwp500.models.DeviceStatus(*, temperatureType: TemperatureType = TemperatureType.FAHRENHEIT, macAddress: str | None = None, command: int, specialFunctionStatus: int, errorCode: ErrorCode = ErrorCode.NO_ERROR, subErrorCode: int, smartDiagnostic: int, faultStatus1: int, faultStatus2: int, wifiRssi: int = None, dhwChargePer: float, drEventStatus: DREvent = DREvent.UNKNOWN, vacationDaySetting: int, vacationDayElapsed: int, antiLegionellaPeriod: int, programReservationType: int, tempFormulaType: TempFormulaType, outsideTemperature: int = None, currentStatenum: int, targetFanRpm: int, currentFanRpm: int, fanPwm: int, mixingRate: float, eevStep: int, airFilterAlarmPeriod: int, airFilterAlarmElapsed: int, cumulatedOpTimeEvaFan: int, cumulatedDhwFlowRate: int, touStatus: Annotated[bool, BeforeValidator(func=bool, json_schema_input_type=PydanticUndefined)], drOverrideStatus: int, touOverrideStatus: Annotated[bool, BeforeValidator(func=tou_override_to_python, json_schema_input_type=PydanticUndefined)], totalEnergyCapacity: Annotated[float, BeforeValidator(func=mul_10, json_schema_input_type=PydanticUndefined)], availableEnergyCapacity: Annotated[float, BeforeValidator(func=mul_10, json_schema_input_type=PydanticUndefined)], recircOperationMode: RecirculationMode, recircPumpOperationStatus: int, recircHotBtnReady: int, recircOperationReason: int, recircErrorStatus: int, currentInstPower: float, didReload: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], operationBusy: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], freezeProtectionUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], dhwUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], dhwUseSustained: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], dhwOperationBusy: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)] = False, programReservationUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], ecoUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], compUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], eevUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], evaFanUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], shutOffValveUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], conOvrSensorUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], wtrOvrSensorUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], antiLegionellaUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], antiLegionellaOperationBusy: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], errorBuzzerUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], currentHeatUse: HeatSource, heatUpperUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], heatLowerUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], scaldUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], airFilterAlarmUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], recircOperationBusy: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], recircReservationUse: Annotated[bool, BeforeValidator(func=device_bool_to_python, json_schema_input_type=PydanticUndefined)], dhwTemperature: int = None, dhwTemperatureSetting: int = None, dhwTargetTemperatureSetting: int = None, freezeProtectionTemperature: int = None, dhwTemperature2: int = None, hpUpperOnTempSetting: int = None, hpUpperOffTempSetting: int = None, hpLowerOnTempSetting: int = None, hpLowerOffTempSetting: int = None, heUpperOnTempSetting: int = None, heUpperOffTempSetting: int = None, heLowerOnTempSetting: int = None, heLowerOffTempSetting: int = None, heatMinOpTemperature: int = None, recircTempSetting: int = None, recircTemperature: int = None, recircFaucetTemperature: int = None, currentInletTemperature: int = None, currentDhwFlowRate: int, hpUpperOnDiffTempSetting: int, hpUpperOffDiffTempSetting: int, hpLowerOnDiffTempSetting: int, hpLowerOffDiffTempSetting: int, heUpperOnDiffTempSetting: int, heUpperOffDiffTempSetting: int, heLowerOnTDiffempSetting: int, heLowerOffDiffTempSetting: int, recircDhwFlowRate: int, tankUpperTemperature: int = None, tankLowerTemperature: int = None, dischargeTemperature: int = None, suctionTemperature: int = None, evaporatorTemperature: int = None, ambientTemperature: int = None, targetSuperHeat: int = None, currentSuperHeat: int = None, operationMode: CurrentOperationMode = CurrentOperationMode.STANDBY, dhwOperationSetting: DhwOperationSetting = DhwOperationSetting.ENERGY_SAVER, freezeProtectionTempMin: int = 43, freezeProtectionTempMax: int = 65)[source]

Bases: NavienBaseModel

Represents the status of the Navien water heater device.

air_filter_alarm_elapsed: int
air_filter_alarm_period: int
air_filter_alarm_use: DeviceBool
property ambient_temperature: float
ambient_temperature_raw: int
anti_legionella_operation_busy: DeviceBool
anti_legionella_period: int
anti_legionella_use: DeviceBool
available_energy_capacity: TenWhToWh
command: int
comp_use: DeviceBool
con_ovr_sensor_use: DeviceBool
property cumulated_dhw_flow_rate: float
cumulated_dhw_flow_rate_raw: int
cumulated_op_time_eva_fan: int
property current_dhw_flow_rate: float
current_dhw_flow_rate_raw: int
current_fan_rpm: int
current_heat_use: HeatSource
property current_inlet_temperature: float
current_inlet_temperature_raw: int
current_inst_power: float
current_statenum: int
property current_super_heat: float
current_super_heat_raw: int
dhw_charge_per: float
dhw_operation_busy: DeviceBool
dhw_operation_setting: DhwOperationSetting
property dhw_target_temperature_setting: float
dhw_target_temperature_setting_raw: int
property dhw_temperature: float
property dhw_temperature2: float
dhw_temperature2_raw: int
dhw_temperature_raw: int
property dhw_temperature_setting: float
dhw_temperature_setting_raw: int
dhw_use: DeviceBool
dhw_use_sustained: DeviceBool
did_reload: DeviceBool
property discharge_temperature: float
discharge_temperature_raw: int
dr_event_status: DREvent
dr_override_status: int
eco_use: DeviceBool
eev_step: int
eev_use: DeviceBool
error_buzzer_use: DeviceBool
error_code: ErrorCode
eva_fan_use: DeviceBool
property evaporator_temperature: float
evaporator_temperature_raw: int
fan_pwm: int
fault_status1: int
fault_status2: int
property freeze_protection_temp_max: float
freeze_protection_temp_max_raw: int
property freeze_protection_temp_min: float
freeze_protection_temp_min_raw: int
property freeze_protection_temperature: float
freeze_protection_temperature_raw: int
freeze_protection_use: DeviceBool
get_field_unit(field_name: str) str[source]

Get the correct unit suffix based on temperature preference.

Resolves dynamic units for temperature, flow rate, and volume fields that change based on unit system context override or the device’s temperature_type setting (Celsius or Fahrenheit).

Parameters:

field_name – Name of the field to get the unit for

Returns:

Unit string (e.g., “ °C”, “ LPM”, “ L”) or empty if field not found

property he_lower_off_diff_temp_setting: float
he_lower_off_diff_temp_setting_raw: int
property he_lower_off_temp_setting: float
he_lower_off_temp_setting_raw: int
property he_lower_on_diff_temp_setting: float
he_lower_on_diff_temp_setting_raw: int
property he_lower_on_temp_setting: float
he_lower_on_temp_setting_raw: int
property he_upper_off_diff_temp_setting: float
he_upper_off_diff_temp_setting_raw: int
property he_upper_off_temp_setting: float
he_upper_off_temp_setting_raw: int
property he_upper_on_diff_temp_setting: float
he_upper_on_diff_temp_setting_raw: int
property he_upper_on_temp_setting: float
he_upper_on_temp_setting_raw: int
heat_lower_use: DeviceBool
property heat_min_op_temperature: float
heat_min_op_temperature_raw: int
heat_upper_use: DeviceBool
property hp_lower_off_diff_temp_setting: float
hp_lower_off_diff_temp_setting_raw: int
property hp_lower_off_temp_setting: float
hp_lower_off_temp_setting_raw: int
property hp_lower_on_diff_temp_setting: float
hp_lower_on_diff_temp_setting_raw: int
property hp_lower_on_temp_setting: float
hp_lower_on_temp_setting_raw: int
property hp_upper_off_diff_temp_setting: float
hp_upper_off_diff_temp_setting_raw: int
property hp_upper_off_temp_setting: float
hp_upper_off_temp_setting_raw: int
property hp_upper_on_diff_temp_setting: float
hp_upper_on_diff_temp_setting_raw: int
property hp_upper_on_temp_setting: float
hp_upper_on_temp_setting_raw: int
mac_address: str | None
mixing_rate: float
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

operation_busy: DeviceBool
operation_mode: CurrentOperationMode
property outside_temperature: float
outside_temperature_raw: int
program_reservation_type: int
program_reservation_use: DeviceBool
property recirc_dhw_flow_rate: float
recirc_dhw_flow_rate_raw: int
recirc_error_status: int
property recirc_faucet_temperature: float
recirc_faucet_temperature_raw: int
recirc_hot_btn_ready: int
recirc_operation_busy: DeviceBool
recirc_operation_mode: RecirculationMode
recirc_operation_reason: int
recirc_pump_operation_status: int
recirc_reservation_use: DeviceBool
property recirc_temp_setting: float
recirc_temp_setting_raw: int
property recirc_temperature: float
recirc_temperature_raw: int
scald_use: DeviceBool
shut_off_valve_use: DeviceBool
smart_diagnostic: int
special_function_status: int
sub_error_code: int
property suction_temperature: float
suction_temperature_raw: int
property tank_lower_temperature: float
tank_lower_temperature_raw: int
property tank_upper_temperature: float
tank_upper_temperature_raw: int
target_fan_rpm: int
property target_super_heat: float
target_super_heat_raw: int
temp_formula_type: TempFormulaType
temperature_type: TemperatureType
total_energy_capacity: TenWhToWh
tou_override_status: TouOverride
tou_status: TouStatus
vacation_day_elapsed: int
vacation_day_setting: int
wifi_rssi: int
wtr_ovr_sensor_use: DeviceBool
class nwp500.models.EnergyUsageBase(*, hpUsage: int = 0, heUsage: int = 0, hpTime: int = 0, heTime: int = 0)[source]

Bases: NavienBaseModel

Base energy usage fields common to daily and total responses.

heat_element_time: int
heat_element_usage: int
heat_pump_time: int
heat_pump_usage: int
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property total_usage: int
class nwp500.models.EnergyUsageDay(*, hpUsage: int = 0, heUsage: int = 0, hpTime: int = 0, heTime: int = 0)[source]

Bases: EnergyUsageBase

Daily energy usage data.

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class nwp500.models.EnergyUsageResponse(*, total: EnergyUsageTotal, usage: list[MonthlyEnergyData])[source]

Bases: NavienBaseModel

Response for energy usage query.

get_month_data(year: int, month: int) MonthlyEnergyData | None[source]

Get energy usage data for a specific month.

Parameters:
  • year – Year (e.g., 2025)

  • month – Month (1-12)

Returns:

MonthlyEnergyData for that month, or None if not found

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

total: EnergyUsageTotal
usage: list[MonthlyEnergyData]
class nwp500.models.EnergyUsageTotal(*, hpUsage: int = 0, heUsage: int = 0, hpTime: int = 0, heTime: int = 0)[source]

Bases: EnergyUsageBase

Total energy usage data.

property heat_element_percentage: float
property heat_pump_percentage: float
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property total_time: int
class nwp500.models.FirmwareInfo(*, macAddress: str = '', additionalValue: str = '', deviceType: DeviceType | int = DeviceType.NPF700_WIFI, curSwCode: int = 0, curVersion: int = 0, downloadedVersion: int | None = None, deviceGroup: str | None = None)[source]

Bases: NavienBaseModel

Firmware information for a device.

additional_value: str
cur_sw_code: int
cur_version: int
device_group: str | None
device_type: DeviceType | int
downloaded_version: int | None
mac_address: str
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class nwp500.models.Location(*, state: str | None = None, city: str | None = None, address: str | None = None, latitude: float | None = None, longitude: float | None = None, altitude: float | None = None)[source]

Bases: NavienBaseModel

Location information for a device.

address: str | None
altitude: float | None
city: str | None
latitude: float | None
longitude: float | None
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

state: str | None
class nwp500.models.MonthlyEnergyData(*, year: int, month: int, data: list[EnergyUsageDay])[source]

Bases: NavienBaseModel

Monthly energy usage data grouping.

data: list[EnergyUsageDay]
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

month: int
year: int
class nwp500.models.MqttCommand(*, clientID: str, sessionID: str, requestTopic: str, responseTopic: str, request: MqttRequest | dict[str, Any], protocolVersion: int = 2)[source]

Bases: NavienBaseModel

Represents an MQTT command message.

client_id: str
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

protocol_version: int
request: MqttRequest | dict[str, Any]
request_topic: str
response_topic: str
session_id: str
class nwp500.models.MqttRequest(*, command: int, deviceType: DeviceType | int, macAddress: str, additionalValue: str = '...', mode: str | None = None, param: list[int | float] = <factory>, paramStr: str = '', month: list[int] | None = None, year: int | None = None)[source]

Bases: NavienBaseModel

MQTT command request payload.

additional_value: str
command: int
device_type: DeviceType | int
mac_address: str
mode: str | None
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

month: list[int] | None
param: list[int | float]
param_str: str
year: int | None
class nwp500.models.NavienBaseModel[source]

Bases: BaseModel

Base model for all Navien models.

Provides: - camelCase alias generation (to_camel) for JSON compatibility - populate_by_name=True so Python snake_case names work too - extra="ignore" to tolerate unknown protocol fields - use_enum_values=False to keep enum objects during validation - Custom model_dump that converts enums to their .name string

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_dump(**kwargs: Any) dict[str, Any][source]

Dump model to dict with enums serialised as their name strings.

class nwp500.models.OtaCommitPayload(*, swCode: int, swVersion: int)[source]

Bases: NavienBaseModel

Payload for committing a firmware component update.

Used with the OTA_COMMIT command (33554442). This command uses a special commitOta structure instead of the standard mode/param format.

Parameters:
  • sw_code – Software component code identifying which firmware to commit. 1 = Controller, 2 = Panel, 4 = WiFi/communication module.

  • sw_version – Version number to commit (as reported by the OTA check).

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

sw_code: int
sw_version: int
class nwp500.models.RecirculationSchedule(*, schedule: list[RecirculationScheduleEntry] = <factory>)[source]

Bases: NavienBaseModel

Complete recirculation pump schedule (RECIR_RESERVATION command).

Used with command code 33554444 to configure timed recirculation pump operation windows.

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

schedule: list[RecirculationScheduleEntry]
class nwp500.models.RecirculationScheduleEntry(*, enable: int = 2, week: int = 0, startHour: int = 0, startMin: int = 0, endHour: int = 0, endMin: int = 0, mode: int = 1)[source]

Bases: NavienBaseModel

A single entry in a recirculation pump schedule.

Used with the RECIR_RESERVATION command (33554444) to set timed recirculation cycles. Each entry defines a time window and pump mode.

Fields:
  • enable: 2=enabled, 1=disabled (device boolean)

  • week: bitfield of active days (Sun=bit7, Mon=bit6, …, Sat=bit1)

  • start_hour: 0-23

  • start_min: 0-59

  • end_hour: 0-23

  • end_min: 0-59

  • mode: recirculation mode (1=Constant, 2=Timer, 3=Temperature, 4=Sensor)

property days: list[str]

Weekday names for this entry.

enable: int
property enabled: bool

2=on, 1=off).

Type:

Whether this entry is active (device bool

end_hour: int
end_min: int
property end_time: str

MM).

Type:

Formatted end time string (HH

mode: int
property mode_name: str

Human-readable recirculation mode name.

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

start_hour: int
start_min: int
property start_time: str

MM).

Type:

Formatted start time string (HH

week: int
class nwp500.models.ReservationEntry(*, enable: int = 2, week: int = 0, hour: int = 0, min: int = 0, mode: int = 1, param: int = 0)[source]

Bases: NavienBaseModel

A single scheduled reservation entry.

Wraps the raw 6-byte protocol fields and provides computed properties for display-ready values including unit-aware temperature conversion.

The raw protocol fields are:
  • enable: 2=enabled, 1=disabled (device boolean)

  • week: bitfield of active days (Sun=bit7, Mon=bit6, …, Sat=bit1)

  • hour: 0-23

  • min: 0-59

  • mode: DHW operation mode ID (1-6)

  • param: temperature in half-degrees Celsius

property days: list[str]

Weekday names for this reservation.

enable: int
property enabled: bool

2=on, 1=off).

Type:

Whether this reservation is active (device bool

hour: int
min: int
mode: int
property mode_name: str

Human-readable operation mode name.

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

param: int
property temperature: float

Temperature in the user’s preferred unit.

property time: str

MM).

Type:

Formatted time string (HH

property unit: str

Temperature unit symbol.

week: int
class nwp500.models.ReservationSchedule(*, reservationUse: int = 0, reservation: list[ReservationEntry] = <factory>)[source]

Bases: NavienBaseModel

Complete reservation schedule from the device.

Can be constructed from raw MQTT response data. The reservation field accepts either a hex string (from GET responses) or a list of dicts/ReservationEntry objects.

property enabled: bool

Whether the reservation system is globally enabled.

Device bool convention: 2=on, 1=off.

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

reservation: list[ReservationEntry]
reservation_use: int
class nwp500.models.TOUInfo(*, registerPath: str = '', sourceType: str = '', controllerId: str = '', manufactureId: str = '', name: str = '', utility: str = '', zipCode: int = 0, schedule: list[TOUSchedule] = <factory>)[source]

Bases: NavienBaseModel

Time of Use information.

controller_id: str
manufacture_id: str
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str
register_path: str
schedule: list[TOUSchedule]
source_type: str
utility: str
zip_code: int
class nwp500.models.TOUPeriod(*, season: int = 0, week: int = 0, startHour: int = 0, startMinute: int = 0, endHour: int = 0, endMinute: int = 0, priceMin: int = 0, priceMax: int = 0, decimalPoint: int = 5)[source]

Bases: NavienBaseModel

A single TOU pricing period from an MQTT tou/rd response.

Each period defines a time window, active season/week bitfields, and the pricing range for that window.

Fields use camelCase aliases to match the raw MQTT payload:
  • season: bitfield of active months (bit N-1 set for month N)

  • week: bitfield of active weekdays (Sun=bit7, …, Sat=bit1)

  • startHour / startMinute: start of the time window (0-23 / 0-59)

  • endHour / endMinute: end of the time window (0-23 / 0-59)

  • priceMin / priceMax: encoded integer prices (divide by 10^decimalPoint)

  • decimalPoint: number of decimal places for price values

decimal_point: int
property decoded_price_max: float

Maximum price decoded to a float (price_max / 10^decimal_point).

property decoded_price_min: float

Minimum price decoded to a float (price_min / 10^decimal_point).

end_hour: int
end_min: int
property end_time: str

MM).

Type:

Formatted end time (HH

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

price_max: int
price_min: int
season: int
start_hour: int
start_min: int
property start_time: str

MM).

Type:

Formatted start time (HH

week: int
class nwp500.models.TOUReservationSchedule(*, reservationUse: int = 0, reservation: list[TOUPeriod] = <factory>)[source]

Bases: NavienBaseModel

TOU schedule as returned by the MQTT tou/rd response topic.

This model matches the raw MQTT payload for both request_tou_settings() read responses and configure_tou_schedule() write confirmations — both use CommandCode.TOU_RESERVATION and the tou/rd response topic.

The payload structure is:

{
    "reservationUse": 2,          # 0=disabled, 2=enabled
    "reservation": [              # list of TOU period dicts
        {
            "season": 4095, "week": 254,
            "startHour": 0, "startMinute": 0,
            "endHour": 23, "endMinute": 59,
            "priceMin": 10, "priceMax": 25,
            "decimalPoint": 2
        },
        ...
    ]
}
property enabled: bool

Whether TOU scheduling is globally enabled.

Protocol convention: 0=disabled, 2=enabled.

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

reservation: list[TOUPeriod]
reservation_use: int
class nwp500.models.TOUSchedule(*, season: int = 0, interval: list[dict[str, ~typing.Any]]=<factory>)[source]

Bases: NavienBaseModel

Time of Use schedule information.

intervals: list[dict[str, Any]]
model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

season: int
class nwp500.models.WeeklyReservationEntry(*, enable: int = 2, week: int = 0, hour: int = 0, min: int = 0, mode: int = 1, param: int = 0)[source]

Bases: NavienBaseModel

A single entry in a weekly temperature reservation schedule.

Similar to ReservationEntry but used with the RESERVATION_WEEKLY command (33554438), which configures a separate weekly temperature schedule independent of the timed reservation system.

The raw protocol fields mirror the standard reservation format:
  • enable: 2=enabled, 1=disabled (device boolean)

  • week: bitfield of active days (Sun=bit7, Mon=bit6, …, Sat=bit1)

  • hour: 0-23

  • min: 0-59

  • mode: DHW operation mode ID (1-6)

  • param: temperature in half-degrees Celsius

property days: list[str]

Weekday names for this entry.

enable: int
property enabled: bool

2=on, 1=off).

Type:

Whether this entry is active (device bool

hour: int
min: int
mode: int
property mode_name: str

Human-readable operation mode name.

model_config = {'alias_generator': <function to_camel>, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

param: int
property temperature: float

Temperature in the user’s preferred unit.

property time: str

MM).

Type:

Formatted time string (HH

property unit: str

Temperature unit symbol.

week: int
class nwp500.models.WeeklyReservationSchedule(*, reservationUse: int = 0, reservation: list[WeeklyReservationEntry] = <factory>)[source]

Bases: NavienBaseModel

Complete weekly reservation schedule (RESERVATION_WEEKLY command).

Used with command code 33554438 to configure a temperature schedule that repeats weekly. Accepts the same hex-encoded format as the standard reservation schedule.

property enabled: bool

Whether the weekly reservation system is globally enabled.

Device bool convention: 2=on, 1=off.

model_config = {'alias_generator': None, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': False, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

reservation: list[WeeklyReservationEntry]
reservation_use: int
nwp500.models.fahrenheit_to_half_celsius(fahrenheit: float) int[source]

Convert Fahrenheit to half-degrees Celsius (for device commands).

Parameters:

fahrenheit – Temperature in Fahrenheit.

Returns:

Raw device value in half-Celsius format.

Example

>>> fahrenheit_to_half_celsius(140.0)
120
nwp500.models.preferred_to_half_celsius(temperature: float) int[source]

Convert temperature from preferred unit to half-degrees Celsius.

Converts temperature from the user’s preferred unit (Celsius or Fahrenheit, based on global unit system context) to the half-Celsius format used by the device for commands and reservations.

Parameters:

temperature – Temperature in user’s preferred unit (Celsius or Fahrenheit).

Returns:

Raw device value in half-Celsius format.

Example

>>> # With us_customary unit system
>>> preferred_to_half_celsius(140.0)  # 140°F
120
>>> # With metric unit system
>>> preferred_to_half_celsius(60.0)  # 60°C
120
nwp500.models.reservation_param_to_preferred(param: int) float[source]

Convert reservation param to user’s preferred temperature unit.

Device returns reservation temperatures as half-degrees Celsius (param). This converts them to the user’s preferred unit (Celsius or Fahrenheit) based on the global unit system context.

Parameters:

param – Raw device value in half-Celsius format.

Returns:

Temperature in user’s preferred unit (Celsius or Fahrenheit).

Example

>>> # With metric (Celsius) unit system
>>> reservation_param_to_preferred(120)
60.0
>>> # With us_customary (Fahrenheit) unit system
>>> reservation_param_to_preferred(120)
140.0