voorkant / voorkant-core

https://voorkant.org/
MIT License
2 stars 3 forks source link

minimal implementation of UIApexCard #68

Closed Habbie closed 1 month ago

Habbie commented 3 months ago

TODO:

Habbie commented 3 months ago

clang-format just suggested:

-  if(entity) entity->attach((IObserver*)this);
+  if (entity)
+    entity->attach((IObserver*)this);

and it (or tidy) should also enforce {} around the body

cyclops1982 commented 3 months ago

With this PR, we've realized that cards in HA can have/show data from multiple entities. In the current state of the PR, this is 'hacked' to work by providing a nullptr to the parent constructor of the UIApexCard. We never realized before that a HA Card can have multiple entities and this was a bit silly because lots of people use the entities card. For example:

type: entities
entities:
  - entity: light.master_bedroom_dimmer_2
    icon: mdi:ceiling-light
    name: Main lamp
    secondary_info: brightness
  - entity: switch.smart_meter_switch_master_bedroom
    secondary_info: none
    name: Small lamp
    icon: mdi:floor-lamp
  - entity: switch.0x847127fffed34d29_l1
    name: Socket 1
    icon: mdi:power-socket-uk
    secondary_info: last-changed
  - entity: switch.0x847127fffed34d29_l2
    icon: mdi:power-socket-uk
    secondary_info: last-updated
    name: Socket 2
  - entity: climate.0x50325ffffe770853
    icon: mdi:radiator-disabled
    name: Radiator valve
    secondary_info: last-updated
  - entity: light.esp_wakeup_1_neopixel_light
  - entity: light.wled
title: Master bedroom
state_color: false
footer:
  type: graph
  entity: sensor.ble_mon_2_037e_temperature
  detail: 2

In apexcharts, we also have examples like:

type: custom:apexcharts-card
header:
  show: true
  title: Electricity price forecast (in pence)
  show_states: false
show:
  last_updated: true
span:
  start: day
graph_span: 48h
apex_config:
  legend:
    show: false
  chart:
    zoom:
      type: x
      enabled: true
      autoScaleYaxis: false
    toolbar:
      show: true
      autoSelected: zoom
    xaxis.type: datetime
now:
  show: true
  label: now
yaxis:
  - id: current
    max: ~35
    min: ~0
  - id: next
    max: ~35
    min: ~0
    opposite: true
all_series_config:
  unit: p
  type: column
  stroke_width: 2
series:
  - entity: >-
      event.octopus_energy_electricity_16m0094068_1900026031712_current_day_rates
    data_generator: |
      return entity.attributes.rates.map((item) => {
        return [new Date(item.start), item.value_inc_vat * 100];
      });
    name: pence per kWh
    yaxis_id: current
  - entity: event.octopus_energy_electricity_16m0094068_1900026031712_next_day_rates
    data_generator: |
      return entity.attributes.rates.map((item) => {
        return [new Date(item.start), item.value_inc_vat * 100];
      });
    name: pence per kWh
    yaxis_id: next

This simply means that a card is not bound to one entity, and thus (for us) one uicomponent should not have one HAEntity.

The solution here would be to make a collection (vector/list/whatever) out of the HAEntity in our UIEntity base class. This would have impact in a few places, but this can be handled. The observer pattern we use would now also benefit from understanding which HAentity called it. The construction of uicomponents would also have to change, as the constructor no longer receives one HAEntity (a create + add(haentity) might work well).