|
2 | 2 | from __future__ import annotations |
3 | 3 |
|
4 | 4 | import logging |
5 | | -from typing import Any, Final |
| 5 | +from typing import Final, TypedDict |
6 | 6 |
|
7 | 7 | LOGGER = logging.getLogger(__name__) |
8 | 8 |
|
|
406 | 406 | # P1 related measurements: |
407 | 407 | HOME_MEASUREMENTS: Final[dict[str, dict[str, str]]] = { |
408 | 408 | "electricity_consumed": { |
409 | | - ATTR_TYPE: "power", |
410 | 409 | ATTR_UNIT_OF_MEASUREMENT: POWER_WATT, |
411 | 410 | }, |
412 | 411 | "electricity_produced": { |
413 | | - ATTR_TYPE: "power", |
414 | 412 | ATTR_UNIT_OF_MEASUREMENT: POWER_WATT, |
415 | 413 | }, |
416 | 414 | "gas_consumed": { |
417 | | - ATTR_TYPE: "gas", |
418 | 415 | ATTR_UNIT_OF_MEASUREMENT: VOLUME_CUBIC_METERS, |
419 | 416 | }, |
420 | 417 | } |
|
423 | 420 | # Excluded: |
424 | 421 | # zone_thermosstat: 'temperature_offset' |
425 | 422 | # radiator_valve: 'uncorrected_temperature', 'temperature_offset' |
426 | | -DEVICE_MEASUREMENTS: Final[dict[str, dict[str, str | None]]] = { |
| 423 | +DEVICE_MEASUREMENTS: Final[dict[str, dict[str, str]]] = { |
427 | 424 | # HA Core thermostat current_temperature |
428 | 425 | "temperature": {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}, |
429 | 426 | # HA Core thermostat setpoint |
|
444 | 441 | # Specific for a Plug |
445 | 442 | "electricity_consumed": {ATTR_UNIT_OF_MEASUREMENT: POWER_WATT}, |
446 | 443 | "electricity_produced": {ATTR_UNIT_OF_MEASUREMENT: POWER_WATT}, |
447 | | - "relay": {ATTR_UNIT_OF_MEASUREMENT: None}, |
| 444 | + "relay": {ATTR_UNIT_OF_MEASUREMENT: NONE}, |
448 | 445 | # Added measurements from actuator_functionalities/thermostat_functionality |
449 | 446 | "lower_bound": {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}, |
450 | 447 | "upper_bound": {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}, |
451 | 448 | "resolution": {ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}, |
452 | | - "regulation_mode": {ATTR_UNIT_OF_MEASUREMENT: None}, |
453 | | - "maximum_boiler_temperature": {ATTR_UNIT_OF_MEASUREMENT: None}, |
| 449 | + "regulation_mode": {ATTR_UNIT_OF_MEASUREMENT: NONE}, |
| 450 | + "maximum_boiler_temperature": {ATTR_UNIT_OF_MEASUREMENT: NONE}, |
454 | 451 | } |
455 | 452 |
|
456 | 453 | # Heater Central related measurements |
457 | | -HEATER_CENTRAL_MEASUREMENTS: Final[dict[str, dict[str, str | None]]] = { |
| 454 | +HEATER_CENTRAL_MEASUREMENTS: Final[dict[str, dict[str, str]]] = { |
458 | 455 | "boiler_temperature": { |
459 | 456 | ATTR_NAME: "water_temperature", |
460 | 457 | ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS, |
461 | 458 | }, |
462 | 459 | "domestic_hot_water_comfort_mode": { |
463 | 460 | ATTR_NAME: "dhw_cm_switch", |
464 | | - ATTR_UNIT_OF_MEASUREMENT: None, |
| 461 | + ATTR_UNIT_OF_MEASUREMENT: NONE, |
465 | 462 | }, |
466 | 463 | "domestic_hot_water_state": { |
467 | 464 | ATTR_NAME: "dhw_state", |
|
472 | 469 | }, # Non-zero when heating, zero when dhw-heating |
473 | 470 | "central_heating_state": { |
474 | 471 | ATTR_NAME: "c_heating_state", |
475 | | - ATTR_UNIT_OF_MEASUREMENT: None, |
| 472 | + ATTR_UNIT_OF_MEASUREMENT: NONE, |
476 | 473 | }, # For Elga (heatpump) use this instead of intended_central_heating_state |
477 | 474 | "intended_central_heating_state": { |
478 | 475 | ATTR_NAME: "heating_state", |
479 | | - ATTR_UNIT_OF_MEASUREMENT: None, |
| 476 | + ATTR_UNIT_OF_MEASUREMENT: NONE, |
480 | 477 | }, # This key shows in general the heating-behavior better than c-h_state. except when connected to a heatpump |
481 | 478 | "modulation_level": {ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE}, |
482 | 479 | "return_water_temperature": { |
483 | 480 | ATTR_NAME: "return_temperature", |
484 | 481 | ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS, |
485 | 482 | }, |
486 | 483 | # Used with the Elga heatpump - marcelveldt |
487 | | - "compressor_state": {ATTR_UNIT_OF_MEASUREMENT: None}, |
488 | | - "cooling_state": {ATTR_UNIT_OF_MEASUREMENT: None}, |
| 484 | + "compressor_state": {ATTR_UNIT_OF_MEASUREMENT: NONE}, |
| 485 | + "cooling_state": {ATTR_UNIT_OF_MEASUREMENT: NONE}, |
489 | 486 | # Next 2 keys are used to show the state of the gas-heater used next to the Elga heatpump - marcelveldt |
490 | | - "slave_boiler_state": {ATTR_UNIT_OF_MEASUREMENT: None}, |
| 487 | + "slave_boiler_state": {ATTR_UNIT_OF_MEASUREMENT: NONE}, |
491 | 488 | "flame_state": { |
492 | | - ATTR_UNIT_OF_MEASUREMENT: None |
| 489 | + ATTR_UNIT_OF_MEASUREMENT: NONE |
493 | 490 | }, # Also present when there is a single gas-heater |
494 | 491 | "central_heater_water_pressure": { |
495 | 492 | ATTR_NAME: "water_pressure", |
496 | 493 | ATTR_UNIT_OF_MEASUREMENT: PRESSURE_BAR, |
497 | 494 | }, |
498 | 495 | # Legacy Anna: similar to flame-state on Anna/Adam |
499 | | - "boiler_state": {ATTR_NAME: "flame_state", ATTR_UNIT_OF_MEASUREMENT: None}, |
| 496 | + "boiler_state": {ATTR_NAME: "flame_state", ATTR_UNIT_OF_MEASUREMENT: NONE}, |
500 | 497 | # Legacy Anna: shows when heating is active, we don't show dhw_state, cannot be determined reliably |
501 | 498 | "intended_boiler_state": { |
502 | 499 | ATTR_NAME: "heating_state", |
503 | | - ATTR_UNIT_OF_MEASUREMENT: None, |
| 500 | + ATTR_UNIT_OF_MEASUREMENT: NONE, |
504 | 501 | }, |
505 | 502 | # Outdoor temperature from APPLIANCES - present for a heatpump |
506 | 503 | "outdoor_temperature": { |
|
510 | 507 | } |
511 | 508 |
|
512 | 509 | # Known types of Smiles and Stretches |
513 | | -SMILES: Final[dict[str, dict[str, Any]]] = { |
| 510 | +SMILES: Final[dict[str, dict[str, str]]] = { |
514 | 511 | "smile_open_therm_v3": { |
515 | 512 | "type": "thermostat", |
516 | 513 | "friendly_name": "Adam", |
|
530 | 527 | "smile_thermo_v1": { |
531 | 528 | "type": "thermostat", |
532 | 529 | "friendly_name": "Anna", |
533 | | - "legacy": True, |
| 530 | + "legacy": "true", |
534 | 531 | }, |
535 | 532 | "smile_v4": { |
536 | 533 | "type": "power", |
|
543 | 540 | "smile_v2": { |
544 | 541 | "type": "power", |
545 | 542 | "friendly_name": "P1", |
546 | | - "legacy": True, |
| 543 | + "legacy": "true", |
547 | 544 | }, |
548 | | - "stretch_v3": {"type": "stretch", "friendly_name": "Stretch", "legacy": True}, |
549 | | - "stretch_v2": {"type": "stretch", "friendly_name": "Stretch", "legacy": True}, |
| 545 | + "stretch_v3": {"type": "stretch", "friendly_name": "Stretch", "legacy": "true"}, |
| 546 | + "stretch_v2": {"type": "stretch", "friendly_name": "Stretch", "legacy": "true"}, |
550 | 547 | } |
551 | 548 |
|
552 | 549 |
|
|
608 | 605 | "lock", |
609 | 606 | "relay", |
610 | 607 | ] |
| 608 | + |
| 609 | + |
| 610 | +class ApplianceData(TypedDict, total=False): |
| 611 | + """The Appliance Data class.""" |
| 612 | + |
| 613 | + dev_class: str |
| 614 | + firmware: str | None |
| 615 | + hardware: str |
| 616 | + location: str |
| 617 | + mac_address: str | None |
| 618 | + members: list[str] |
| 619 | + model: str |
| 620 | + name: str |
| 621 | + vendor: str |
| 622 | + zigbee_mac_address: str | None |
| 623 | + |
| 624 | + |
| 625 | +class GatewayData(TypedDict, total=False): |
| 626 | + """The Gateway Data class.""" |
| 627 | + |
| 628 | + smile_name: str |
| 629 | + gateway_id: str |
| 630 | + heater_id: str | None |
| 631 | + cooling_present: bool |
| 632 | + notifications: dict[str, str] |
| 633 | + |
| 634 | + |
| 635 | +class ModelData(TypedDict): |
| 636 | + """The ModelData class.""" |
| 637 | + |
| 638 | + contents: bool |
| 639 | + vendor_name: str | None |
| 640 | + vendor_model: str | None |
| 641 | + hardware_version: str | None |
| 642 | + firmware_version: str | None |
| 643 | + zigbee_mac_address: str | None |
| 644 | + |
| 645 | + |
| 646 | +class SmileBinarySensors(TypedDict, total=False): |
| 647 | + """Smile Binary Sensors class.""" |
| 648 | + |
| 649 | + compressor_state: bool |
| 650 | + cooling_state: bool |
| 651 | + dhw_state: bool |
| 652 | + flame_state: bool |
| 653 | + heating_state: bool |
| 654 | + plugwise_notification: bool |
| 655 | + slave_boiler_state: bool |
| 656 | + |
| 657 | + |
| 658 | +class SmileSensors(TypedDict, total=False): |
| 659 | + """Smile Sensors class.""" |
| 660 | + |
| 661 | + battery: float |
| 662 | + cooling_activation_outdoor_temperature: float |
| 663 | + cooling_deactivation_threshold: float |
| 664 | + temperature: float |
| 665 | + electricity_consumed: float |
| 666 | + electricity_consumed_interval: float |
| 667 | + electricity_consumed_off_peak_cumulative: float |
| 668 | + electricity_consumed_off_peak_interval: int |
| 669 | + electricity_consumed_off_peak_point: int |
| 670 | + electricity_consumed_peak_cumulative: float |
| 671 | + electricity_consumed_peak_interval: int |
| 672 | + electricity_consumed_peak_point: int |
| 673 | + electricity_consumed_point: float |
| 674 | + electricity_produced: float |
| 675 | + electricity_produced_interval: float |
| 676 | + electricity_produced_off_peak_cumulative: float |
| 677 | + electricity_produced_off_peak_interval: int |
| 678 | + electricity_produced_off_peak_point: int |
| 679 | + electricity_produced_peak_cumulative: float |
| 680 | + electricity_produced_peak_interval: int |
| 681 | + electricity_produced_peak_point: int |
| 682 | + electricity_produced_point: float |
| 683 | + gas_consumed_cumulative: float |
| 684 | + gas_consumed_interval: float |
| 685 | + humidity: float |
| 686 | + illuminance: float |
| 687 | + intended_boiler_temperature: float |
| 688 | + modulation_level: float |
| 689 | + net_electricity_cumulative: float |
| 690 | + net_electricity_point: int |
| 691 | + outdoor_air_temperature: float |
| 692 | + outdoor_temperature: float |
| 693 | + return_temperature: float |
| 694 | + setpoint: float |
| 695 | + temperature_difference: float |
| 696 | + valve_position: float |
| 697 | + water_pressure: float |
| 698 | + water_temperature: float |
| 699 | + |
| 700 | + |
| 701 | +class SmileSwitches(TypedDict, total=False): |
| 702 | + """Smile Switches class.""" |
| 703 | + |
| 704 | + dhw_cm_switch: bool |
| 705 | + lock: bool |
| 706 | + relay: bool |
| 707 | + |
| 708 | + |
| 709 | +class ThermoLoc(TypedDict, total=False): |
| 710 | + """Thermo Location class.""" |
| 711 | + |
| 712 | + name: str |
| 713 | + master: str | None |
| 714 | + master_prio: int |
| 715 | + slaves: set[str] |
| 716 | + |
| 717 | + |
| 718 | +class DeviceDataPoints( |
| 719 | + SmileBinarySensors, SmileSensors, SmileSwitches, TypedDict, total=False |
| 720 | +): |
| 721 | + """The class covering all possible collected data points.""" |
| 722 | + |
| 723 | + # Gateway |
| 724 | + regulation_mode: str |
| 725 | + regulation_modes: list[str] |
| 726 | + |
| 727 | + # Heater Central |
| 728 | + maximum_boiler_temperature: float |
| 729 | + |
| 730 | + # Master Thermostats |
| 731 | + lower_bound: float |
| 732 | + upper_bound: float |
| 733 | + resolution: float |
| 734 | + |
| 735 | + preset_modes: list[str] | None |
| 736 | + active_preset: str | None |
| 737 | + |
| 738 | + available_schedules: list[str] |
| 739 | + selected_schedule: str |
| 740 | + last_used: str | None |
| 741 | + schedule_temperature: float | None |
| 742 | + |
| 743 | + mode: str |
| 744 | + |
| 745 | + # Extra for Adam Master Thermostats |
| 746 | + control_state: str | bool |
| 747 | + |
| 748 | + # For temporary use |
| 749 | + c_heating_state: str |
| 750 | + |
| 751 | + |
| 752 | +class DeviceData(ApplianceData, DeviceDataPoints, TypedDict, total=False): |
| 753 | + """The Device Data class, covering the collected and ordere output-data per device.""" |
| 754 | + |
| 755 | + binary_sensors: SmileBinarySensors |
| 756 | + sensors: SmileSensors |
| 757 | + switches: SmileSwitches |
0 commit comments