Closed devilliersjohnny closed 3 months ago
For point 2, you are setting the value to a string 'null', you can either try the primitive value of null, or better would be undefined.
For point 3, these values typically doesn't change often, so a sensor isn't required or typically provided by most inverters.HA doesn't have native templating within a card, but there are templating plugins you can install to use. But I suppose this one could follow the same logic as the batteries power (accept value ot sensor)
HI It looks like you are rendering your card in Firefox. For some reason it does not respect the layout options. Try using chrome or edge and the card will render as intended.
For point 1 I only display 1 decimal for prepaid units. (${this.toNum(state_prepaid_units.state, 1)}
) I don't really see the benefit of showing more than that but at the end of the day its a user preference.
For point 2 the card makes use of a toNum function to handle sensor data. If this is not a number (i.e. a string as you have it defined) it will return 0. I'll look at hiding this when set to 0 for the case of the temperature data.
toNum(val: string | number, decimals: number = -1, invert: boolean = false): number {
let numberValue = Number(val);
if (Number.isNaN(numberValue)) {
return 0;
}
if (decimals >= 0) {
numberValue = parseFloat(numberValue.toFixed(decimals));
}
if (invert) {
numberValue *= -1;
}
return numberValue;
}
For point 3. Some of these option accept sensor data (where it makes sense). Most of them are set through the values provided in the config. The documentation is long but it is mentioned there. If there are other options that would better be set through a sensor let me know and I'll take a look at adding it.
Hi thanks for the quick responses...
@Pho3niX90 -
Where you set the values and was hoping for a way to hook into the cards settings?
type: custom:stack-in-card
cards:
- type: vertical-stack
cards:
- type: horizontal-stack
cards:
- type: entities
entities:
- entity: input_select.edb_display_weather
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: entities
entities:
- entity: input_select.edb_display_load_shedding
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: custom:stack-in-card
cards:
- type: conditional
conditions:
- condition: state
entity: input_select.edb_display_weather
state: Current
card:
type: custom:stack-in-card
cards:
- type: horizontal-stack
cards:
- type: markdown
content: >-
<center><b><font size='3'> Weather - <font color =
'red'> CURRENT </font> </font></b></center>
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: weather-forecast
show_current: true
show_forecast: false
entity: weather.forecast_home
forecast_type: daily
secondary_info_attribute: wind_speed
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
margin: -30px 0px 0px 0px;
}
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: conditional
conditions:
- condition: state
entity: input_select.edb_display_weather
state: Forecast Hourly
card:
type: custom:stack-in-card
cards:
- type: horizontal-stack
cards:
- type: markdown
content: >-
<center><b><font size='3'> Weather - <font color =
'red' > HOURLY </font> Forecast </font></b></center>
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: weather-forecast
show_current: false
show_forecast: true
entity: weather.forecast_home
forecast_type: hourly
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
margin: -30px 0px 0px 0px;
}
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: conditional
conditions:
- condition: state
entity: input_select.edb_display_weather
state: Forecast Daily
card:
type: custom:stack-in-card
cards:
- type: horizontal-stack
cards:
- type: markdown
content: >-
<center><b><font size='3'> Weather - <font color
='red'> DAILY </font>Forecast </font></b></center>
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: weather-forecast
show_current: false
show_forecast: true
entity: weather.forecast_home
forecast_type: daily
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
margin: -30px 0px 0px 0px;
}
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: conditional
conditions:
- condition: state
entity: input_select.edb_display_load_shedding
state: Display
card:
type: custom:stack-in-card
cards:
- type: markdown
content: |-
<center><b><font size='4'>
<font color ='blue'> Load</font> - <font color ='red'>Shedding </font>
</font></b></center>
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: custom:mushroom-chips-card
chips:
- type: entity
entity: sensor.load_shedding_stage_eskom
- type: template
content: '{{state_attr(entity, "count")}}/{{state_attr(entity, "limit")}}'
entity: sensor.load_shedding_sepush_api_quota
icon: mdi:api
tap_action:
action: more-info
alignment: center
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: markdown
content: >
{% set stage_sensor = "sensor.load_shedding_stage_eskom" %} {% set
area_sensor = states("sensor.edb_load_shedding_area_sensor") %} {%
set area_schedule = state_attr(area_sensor, "forecast") %} {% if
area_schedule %}
{% set start_time = area_schedule[0].start_time %}
{% set end_time = area_schedule[0].end_time %}
{% if is_state(area_sensor, "off") %}
{% set starts_in = timedelta(minutes=state_attr(area_sensor, "starts_in")).total_seconds() | int // 60 %}
{% set mins = starts_in % 60 %}
{% set hrs = starts_in // 60 % 24 %}
{% set days = starts_in // 1440 %}
{% set alert = "Load Shedding starts in {d}d {h}h {m}m ({next})".format(d=days, m=mins, h=hrs, next=as_timestamp(start_time) | timestamp_custom("%H:%M", True)) %}
{% if starts_in > 1440 %}
<ha-alert alert-type="success">{{ states(stage_sensor) }}</ha-alert>
{% elif 60 < starts_in <= 1440 %}
<ha-alert alert-type="warning">{{ alert }}</ha-alert>
{% else %}
<ha-alert alert-type="error">{{ alert }}</ha-alert>
{% endif %}
{% else %}
{% set ends_in = timedelta(minutes=state_attr(area_sensor, "ends_in")).total_seconds() | int // 60 %}
{% set mins = ends_in % 60 %}
{% set hrs = ends_in // 60 % 24 %}
{% set days = ends_in // 1440 %}
{% set alert = "Load Shedding ends in {d}d {h}h {m}m ({next})".format(d=days, m=mins, h=hrs, next=as_timestamp(end_time) | timestamp_custom("%H:%M", True)) %}
<ha-alert alert-type="error">{{ alert }}</ha-alert>
{% endif %}
{% else %}
{% set stage = state_attr(stage_sensor, "next_stage") %}
{% set start_time = state_attr(stage_sensor, "next_start_time") %}
{% set end_time = state_attr(stage_sensor, "next_end_time") %}
{% set starts_in = timedelta(minutes=state_attr(stage_sensor, "starts_in")).total_seconds() | int // 60 %}
{% set mins = starts_in % 60 %}
{% set hrs = starts_in // 60 % 24 %}
{% set days = starts_in // 1440 %}
{% if (start_time == 0 or end_time == 0) %}
{% set alert = "No Load Shedding" %}
{% else %}
{% set alert = "Stage {stage} starts in {d}d {h}h {m}m ({next})".format(stage=stage, d=days, m=mins, h=hrs, next=as_timestamp(start_time) | timestamp_custom("%H:%M", True)) %}
{% endif %}
<ha-alert alert-type="success">{{ alert }}</ha-alert>
{% endif %}
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: custom:html-template-card
ignore_line_breaks: true
content: >
{% set area_sensor =
"sensor.load_shedding_area_tshwane_13_lynnwoodglen" %} {% set
number_of_days = 2 %} {% set show_day_borders = false %} {% set
show_end_times = true %} {% set timeslots = 48 %} <style>
@media (prefers-color-scheme: light) {
{% if show_day_borders %}
.day_container {
background-color: #fbeff3 !important;
}
{% endif %}
.current_time_indicator_text,
.current_slot_indicator_start_text,
.current_slot_indicator_end_text {
color: #785551 !important;
}
.current_time_indicator,
.current_slot_indicator_start,
.current_slot_indicator_end {
background-color: #785551 !important;
}
.slot {
background-color: #f5ddd9 !important;
}
}
.day_container {
{% if show_day_borders %}
background-color: #2b2120;
border-radius: 0.75rem;
{% endif %}
padding-top: 0.5rem;
padding-bottom: 1.75rem;
margin: 0.25rem 0;
}
h3.day_heading,
.current_time_indicator_text,
.current_slot_indicator_start_text,
.current_slot_indicator_end_text {
font-family: Roboto, Ubuntu, sans-serif;
font-weight: 600;
}
h3.day_heading {
font-size: 1.0rem;
margin: 0 0 0 1rem;
}
.slot_container {
display: grid;
grid-template-columns: repeat({{ timeslots }}, 1fr);
gap: 0.0625rem;
width: calc(100% - 2rem);
margin: 0 1rem;
line-height: 0.9375rem;
position: relative;
}
.slot_container .slot:first-of-type {
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
}
.slot_container .slot:last-of-type {
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
}
.slot {
border-radius: 15%;
background-color: #534341;
}
.active_slot_stage_1 {
background-color: #f6a829 !important;
}
.active_slot_stage_2 {
background-color: #f8980d !important;
}
.active_slot_stage_3 {
background-color: #e66e0e !important;
}
.active_slot_stage_4 {
background-color: #e3493f !important;
}
.active_slot_stage_5 {
background-color: #d93e3d !important;
}
.active_slot_stage_6 {
background-color: #cf3131 !important;
}
.active_slot_stage_7 {
background-color: #b21e1d !important;
}
.active_slot_stage_8 {
background-color: black !important;
}
div.active_slot {
background-color: black;
}
div.fade_slot {
opacity:0.2;
}
.current_time_indicator {
width: 0.125rem;
position: absolute;
height: 120%;
top: -10%;
border-radius: 15%;
transform: translate(-50%, 0);
background-color: #e6bdb7;
}
.current_time_indicator_text {
position: absolute;
bottom: 140%;
transform: translate(-50%, 0);
color: #e6bdb7;
}
.current_slot_indicator_start {
width: 0.125rem;
position: absolute;
height: 40%;
top: 100%;
border-radius: 15%;
transform: translate(-50%, 0);
background-color: #e6bdb7;
}
.current_slot_indicator_start_text {
position: absolute;
top: 150%;
transform: translate(-50%, 0);
color: #e6bdb7;
}
.current_slot_indicator_end {
width: 0.125rem;
position: absolute;
height: 40%;
bottom: 100%;
border-radius: 15%;
transform: translate(-50%, 0);
background-color: #e6bdb7;
}
.current_slot_indicator_end_text {
position: absolute;
bottom: 150%;
transform: translate(-50%, 0);
color: #e6bdb7;
}
</style> {% set area_schedule = state_attr(area_sensor, "forecast")
%} {% if area_schedule is none %}{% set area_schedule = [] %}{%
endif %} {% for day_offset_idx in range(number_of_days) %}
{% set today_datetime_midnight = now().replace(hour=0,minute=0,second=0,microsecond=0) + timedelta(days=day_offset_idx) %}
<div class="day_container">
<h3 class="day_heading"
style="{% if day_offset_idx == 0 or show_end_times %} margin-bottom: 1.5rem;
{% else %} margin-bottom: 0.5rem;
{% endif %}">{{ today_datetime_midnight.strftime("%A, %B %-d") }}</h3>
<div class="slot_container">
{% set ns = namespace(active_class_name="", last_slot_was_active=false, current_slot_was_activated=false) %}
{% for half_hour_time_slot_idx in range(timeslots) %}
{% set half_hour_time_slot = today_datetime_midnight + timedelta(minutes=30*half_hour_time_slot_idx) %}
{% set ns.active_class_name = "" %}
{% set ns.current_slot_was_activated = false %}
{% for loadshedding in area_schedule %}
{% if not ns.current_slot_was_activated %}
{% if loadshedding["start_time"] <= half_hour_time_slot < loadshedding["end_time"] %}
{% if not ns.last_slot_was_active %}
{% set percentage_of_region = (half_hour_time_slot_idx/timeslots)*100 %}
<span class="current_slot_indicator_start" style="left:{{ percentage_of_region }}%"> </span>
<span class="current_slot_indicator_start_text" style="left:{{ percentage_of_region }}%;
{% if half_hour_time_slot.hour == 0 %}transform: none;{% elif half_hour_time_slot.hour == 23 %}transform: translate(-100%,0);{% endif %}">{{ half_hour_time_slot.strftime("%H:%M") }}</span>
{% endif %}
{% set ns.current_slot_was_activated = true %}
{% set ns.last_slot_was_active = true %}
{% set ns.active_class_name = "active_slot active_slot_" + loadshedding['stage']|lower|replace(' ','_') %}
{% endif %}
{% endif %}
{% endfor %}
{% if not ns.current_slot_was_activated %}
{% if show_end_times and ns.last_slot_was_active %}
{% set percentage_of_region = (half_hour_time_slot_idx/timeslots)*100 %}
<span class="current_slot_indicator_end"
style="left:{{ percentage_of_region }}%"> </span>
<span class="current_slot_indicator_end_text"
style="left:{{ percentage_of_region }}%;
{% if half_hour_time_slot.hour == 0 %}transform: none;{% elif half_hour_time_slot.hour == 23 %}transform: translate(-100%,0);{% endif %}">{{ half_hour_time_slot.strftime("%H:%M") }}</span>
{% endif %}
{% set ns.last_slot_was_active = false %}
{% endif %}
<div class="slot {% if now() > half_hour_time_slot + timedelta(minutes=30) %}fade_slot{% endif %} {{ ns.active_class_name }}"> </div>
{% endfor %}
{% if day_offset_idx == 0 %}
{% set current_time_indicator_progress = now().hour*2 + now().minute/30 %}
{% set percentage_of_region = (current_time_indicator_progress/timeslots)*100 %}
<span class="current_time_indicator"
style="left:{{ percentage_of_region }}%"> </span>
{% if not show_end_times %}
<span class="current_time_indicator_text"
style="left:{{ percentage_of_region }}%">Now</span>
{% endif %}
{% endif %}
</div>
</div>
{% endfor %}
card_mod:
style: |
ha-card
{background: transparent;
border-style: none;
}
- type: custom:atomic-calendar-revive
enableModeChange: true
firstDayOfWeek: 1
refreshInterval: 1800
entities:
- calendar.load_shedding_forecast
showCurrentEventLine: false
showMonth: true
showWeekDay: true
disableEventLink: true
showNoEventsForToday: true
disableLocationLink: true
showFullDayProgress: false
showEventIcon: false
showHiddenText: false
showCalendarName: false
calShowDescription: false
showLastCalendarWeek: true
disableCalEventLink: true
disableCalLocationLink: true
disableCalLink: true
showDescription: false
dateFormat: LL
showDate: false
sortByStartTime: false
showRelativeTime: true
showProgressBar: true
showLocation: true
showDeclined: true
showMultiDayEventParts: false
showMultiDay: false
showLoader: false
maxDaysToShow: 3
card_mod:
style: |
ha-card {
background: transparent;
border-style: none;
}
card_mod:
style: |
ha-card {
background: transparent;
border-style: none;
}
- type: markdown
content: >-
<center><b><font size='6'> <font color = 'blue' > POWER </font><font color
= 'grey' >flow</font><font color = 'lime' > OVERVIEW
</font></font></b></center>
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
- type: custom:sunsynk-power-flow-card
cardstyle: lite
title_colour: blue
title: null
show_solar: true
battery:
shutdown_soc: 20
show_daily: true
auto_scale: false
show_remaining_energy: true
invert_power: true
show_absolute: true
hide_soc: true
animation_speed: 8
max_power: 12000
energy: 12800
solar:
show_daily: true
mppts: 2
auto_scale: false
dynamic_colour: true
display_mode: 1
animation_speed: 8
max_power: 10000
load:
show_daily: true
auto_scale: false
dynamic_colour: true
dynamic_icon: true
show_daily_aux: true
essential_name: Essential
additional_loads: 0
load1_name: a
load1_icon: mdi:account
load2_name: b
load2_icon: mdi:account
load3_name: c
load3_icon: mdi:account
load4_name: d
load4_icon: mdi:account
animation_speed: 8
max_power: 10000
show_aux: true
aux_name: aux
aux_type: mdi:account
invert_aux: true
show_absolute_aux: true
aux_loads: 2
aux_load1_name: a
aux_load1_icon: mdi:account
aux_load2_name: b
aux_load2_icon: mdi:account
grid:
show_daily_buy: true
show_daily_sell: true
show_nonessential: true
auto_scale: false
invert_grid: false
energy_cost_decimals: 2
additional_loads: 3
nonessential_name: Non Essential
nonessential_icon: mdi:account
load1_name: '1'
load1_icon: mdi:account
load2_name: '2'
load2_icon: mdi:account
load3_name: '3'
load3_icon: mdi:account
animation_speed: 8
max_power: 8000
show_battery: true
show_grid: true
inverter:
three_phase: false
autarky: power
auto_scale: false
modern: true
large_font: false
panel_mode: true
entities:
day_pv_energy_108: sensor.edb_pv_total_energy_daily_output
pv1_power_186: sensor.edb_pv1_power
pv1_voltage_109: sensor.edb_pv1_voltage
pv1_current_110: sensor.edb_pv1_current
pv2_power_187: sensor.edb_pv2_power
pv2_voltage_111: sensor.edb_pv2_voltage
pv2_current_112: sensor.edb_pv2_current
pv3_power_188: sensor.edb_pv3_power
pv3_current_114: sensor.edb_pv3_current
pv3_voltage_113: sensor.edb_pv3_voltage
pv4_power_189: sensor.edb_pv4_power
pv4_current_116: sensor.edb_pv4_current
pv4_voltage_115: sensor.edb_pv4_voltage
solar_sell_247: null
remaining_solar: sensor.edb_remaining_solar
environment_temp: null
battery_power_190: sensor.edb_battery_power
battery_current_191: sensor.edb_battery_current
battery_voltage_183: sensor.edb_battery_voltage
battery_temp_182: sensor.edb_battery_temperature
battery_soc_184: sensor.edb_battery_soc
inverter_voltage_154: sensor.edb_inverter_voltage
inverter_voltage_L2: sensor.edb_inverter_voltage_l2
inverter_voltage_L3: sensor.edb_inverter_voltage_l3
load_frequency_192: sensor.edb_inverter_load_frequency
inverter_current_164: sensor.edb_inverter_current
inverter_current_L2: sensor.edb_inverter_current_l2
inverter_current_L3: sensor.edb_inverter_current_l3
grid_power_169: sensor.edb_inverter_grid_power
dc_transformer_temp_90: sensor.edb_inverter_dc_transformer_temperature
radiator_temp_91: sensor.edb_inverter_radiator_temperature
day_load_energy_84: sensor.edb_load_day_load_energy
day_aux_energy: sensor.edb_load_aux_day_energy
essential_power: sensor.edb_load_essential_power_total
essential_load1: sensor.edb_load_essential_1
essential_load2: sensor.edb_load_essential_2
essential_load3: sensor.edb_load_essential_3
essential_load4: sensor.edb_load_essential_4
essential_load1_extra: sensor.edb_load_essential_1_extra
essential_load2_extra: sensor.edb_load_essential_2_extra
load_power_L1: sensor.edb_load_power_l1
load_power_L2: sensor.edb_load_power_l2
load_power_L3: sensor.edb_load_power_l3
aux_power_166: sensor.edb_load_aux_power
aux_load1: sensor.edb_load_aux_load_1
aux_load2: sensor.edb_load_aux_load_2
aux_load1_extra: sensor.edb_load_load_1_extra
aux_load2_extra: sensor.edb_load_aux_load_2_extra
aux_connected_status: null
day_grid_import_76: sensor.edb_grid_day_import_energy
day_grid_export_77: sensor.edb_grid_day_export_energy
grid_ct_power_172: sensor.edb_grid_ct_power_l1
grid_ct_power_L2: sensor.edb_grid_ct_power_l2
grid_ct_power_L3: sensor.edb_grid_ct_power_l3
grid_ct_power_total: sensor.edb_grid_ct_power_total
grid_voltage: sensor.edb_grid_voltage
nonessential_power: null
nonessential_load1: null
nonessential_load2: null
nonessential_load3: null
grid_connected_status_194: sensor.edb_grid_connected_status
energy_cost_buy: null
energy_cost_sell: null
prepaid_units: null
priority_load_243: sensor.edb_inverter_priority_load
inverter_power_175: sensor.edb_inverter_power
pv_total: sensor.edb_pv_total_power_output
day_battery_charge_70: sensor.edb_battery_energy_in_daily
day_battery_discharge_71: sensor.edb_battery_energy_out_daily
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
card_mod:
style: |
ha-card {
--ha-card-background: transparent;
border-style: none;
}
@slipx06 - Thanks for getting back to me
If I understand the function correctly it's saying that a string will be tested to see if its a number, if it is it will be cast as a float? Or are you saying that I should ensure that it is a number by pre-casting it? If so how do I do that?
Please refer to the post just above with the code... HA does not allow UI config in this case... So I was hoping that I could plug into the card at certain points with my templates?
Thank you both for your responses @slipx06 @Pho3niX90
@slipx06 I am wondering if we shouldn't use the state object to determine if an entity should be used, rather than a set value? Would need to identify which sensors would be applicable for this, and perhaps, even use a conditional such as ((state == None || available == None) && timeSince > 1 minute).
@devilliersjohnny Come to think of it, can you set your templates states to None?
Re the battery temperature and not having a numerical value to the sensor, can't you just use 'float(0)' so it defaults to 0 if no reading in available?
I do this for the derived sensors for Huawei inverters configurations, that also works for multiple inverters/batteries (setup for 2 in example configs). Here's a card with the example config applied and NO battery attached. Battery sensors show zero and no issues/errors:
@slipx06 like your thinking!
Tested it out...
It however does not yield the result of none in the "Developer Tools >> STATES" Tab, tested it with a few different strings and setting it to none seems to be the only one that returns a different value 'unknown'
Could you do anything with that?
As far as I can determine it is probably because of the way the template is set up... ie. the template includes "unit_of_measurement" and "device_class" probably forcing it into the field of being a number, but 'None' seems to be a special type within the code?
Apologies my head is all over the place today!
@Roving-Ronin the idea behind what I wanted to achieve is that the sensor is hidden when it does not have a value so setting the value to 0 would result in there being a reading when there should be?! It is a valid hypothesis but the idea @Pho3niX90 came up with would allow for the hiding of the entity when misconfigured? That is if he could use what I told him above!
Apologies my head is all over the place today!
@Roving-Ronin the idea behind what I wanted to achieve is that the sensor is hidden when it does not have a value so setting the value to 0 would result in there being a reading when there should be?! It is a valid hypothesis but the idea @Pho3niX90 came up with would allow for the hiding of the entity when misconfigured? That is if he could use what I told him above!
That should be fine. the unknown would actually work perfectly. I believe you can set it to a primitive unknown as well.
Which items would you like to be able to hide? Only battery or others?
Edit. Come to think of it, if you handle this with your frontend config, are you not able to seitch the show battery option to false when the value isn't a number?
@Pho3niX90 addressing the edit first, the option that I cam looking to hide is the temperature not the entire battery... and there is no option to switch for that! But along those lines it would probably force you to create a whole lot of additional switches/entities to handle all the new options and the card setup page would become over crowded.
Setting 'Unknown' to the primitive... as I mentioned above 'None' is the only one that sets the state to 'Unknown' where as 'Unknown' sets to to 'Unavailable' which is not unique as almost all other strings do the same
Would it be possible to code for all entities that read 'Unknown' to be hidden? ( I know its a big ask )
so we could in theory add a hidden config item, named dynamicConfig
for example, to enable hiding items when the value is invalid (unknown). There are use cases when a sensor could realistically return a state of None or unknown, (during startup, battery shutdown/sleep), so not sure if this should be default behavior.
@slipx06 what do you think?
@Pho3niX90 makes sense but this should not be default behavior. How many other examples besides battery temp are there? Seems like quite a bit of effort with little benefit and would require updating all the CSS display properties?
Hi folks apologies have been AFK for the past few days... So @slipx06 to answer the question above, all of the temperature sensors follow the same pattern ( Battery, Transformer, Radiator and Environmental ). Think about it, the daily grid buy and sell should also follow this pattern??? But then this would open a larger can of worms as to most if not all of your energy totals ( Daily Solar, load, battery charges ans grid buy/sell ) so it might reach further than just the battery temp?
Edit
You might then even be able to automatically detect solar, batteries, grid, aux loads and then all the rest as well?! I apologize in advance if I made a lot of work for you!
I often want to see power and energy values that are 0
.
I will apply this to the temp sensors as a start and we can then proceed on a case by case basis.
Its not the ability to set them to 0 that should disable them... its the states of thereof that should point to the disabling of the device! Remember that temperatures can be 0 and even go into the negatives so the numerical value should not be the deciding factor
@Pho3niX90 we could update the convertToCustomEntity function
isValid: () => entity?.state !== null && entity.state !== undefined && entity.state !== 'unknown' || false,
and then for each of the entities we want to check
//Check for unknown states
let isValidStateBatteryTemp = stateBatteryTemp.isValid
and finally update the CSS display property
display="${!config.show_battery || !data.isValidStateBatteryTemp ? 'none' : ''}"
@Pho3niX90 we could update the convertToCustomEntity function
isValid: () => entity?.state !== null && entity.state !== undefined && entity.state !== 'unknown' || false,
and then for each of the entities we want to check
//Check for unknown states let isValidStateBatteryTemp = stateBatteryTemp.isValid
and finally update the CSS display property
display="${!config.show_battery || !data.isValidStateBatteryTemp ? 'none' : ''}"
That sounds perfect.
Will quickly have a look today. I want to introduce some unit tests as well so we can easily test new changes.
So changes have been done to the compact card, if you could test it out. https://github.com/slipx06/sunsynk-power-flow-card/pull/309/files#diff-6332f9abe6bcdb8a677cd02890c286fe03ad412b0109c49a6f5fcfc5c3d00c45
@devilliersjohnny please test https://github.com/slipx06/sunsynk-power-flow-card/releases/tag/v4.24.1
@slipx06 @Pho3niX90 Thank you! Is working beautifully! Even those that aren't temperature based are disappearing with the 'None' option! What would you guys think about the card auto configuring it self? I mean that if there are entities present it will auto fill the options, for example lets say that you only have two mppts configured, the card then automatically sets the mppt count to two?
@slipx06 @Pho3niX90 Thank you! Is working beautifully! Even those that aren't temperature based are disappearing with the 'None' option! What would you guys think about the card auto configuring it self? I mean that if there are entities present it will auto fill the options, for example lets say that you only have two mppts configured, the card then automatically sets the mppt count to two?
I syppose we have enough sensors per brand to attempt something like this, wince they are split into their own classes as well now.
At first setup, and upon choosing the desired brand, we can do a quick check on 3 sensors if it returns data. If so, use that template.
@Pho3niX90 I'm not quite following?! Apologies but I haven't looked art the source code yet, therefore I cannot say that I am familiar with the workings of the card...
Is there an existing issue for this?
Current Behavior
Not to sure if the first point goes under feature request or bug, but the rest are feature requests so all are going to be listed here
Hooks or a way to manipulate second level items that aren't entities
How would one go about inputting a value from back end into these?
Expected behaviour
Possible Solutions
No response
Mode
lite
Context / Reason
My reasoning behind this would be that you would be able to set up a template and therewith modify the cards front end with the like of
stack-in-card
'card-mod' 'template-card' which do not have front end editors allowing you to create beautiful dashboards, this would mean that where you would have to dig through the .yaml front code to modify anything you could simply locate the correct template and modify its sensor?