Hi,
This is my ongoing project. It has a lot of improvements to make. Any suggestions are welcome. I’m not a graphic designer, so all graphics are from internet. Also, I’m quite new on HA programming.
Gif Showing it working (too big to upload here):
[tela-aquario.gif - Google Drive]
I’m trying to make a dashboard to monitor and control my fishtank. I have some sensors, but I’m also developing a device to monitor temperature, water flux from the canister, pH and Water level, all in one peace.
All controls are executed clicking on the corresponding device on the picture. And the state is shown on the device:
-
The water level is shown with fluid-level and reflects the sensor that’s installed on the aquarium. There’s the possibility to make automatic the refill (I don’t have).
-
Canister flux is shown as a fan with the value below. I defined some severities so that it will be red/green/orange if it’s too slow.
-
Clicking on the circulation pump activates it and a fan spins green.
-
Clicking on the frog (I hava a “bubble frog”), activates the air comprassor connected to a frog in my aquarium. The water on the fliud changes, full with bubbles.
-
The CO2 shows the estimated level of gas. For this I created a helper to store the last fill and another that has the estimated duration. Clicking on the valve opens/closes the solenoid to liberate the gas. Clicking on the canister, the date is set to today, indicating the REFILL was done and the level is updated.
-
The light still has the basic on/of behavior, but I intend to reflect the intensity later.
-
UV light on/off clicking on it.
-
pH level will reflect the sensor. But I need a more representable gauge. I’m using the canvas because it was the closest I need, but it does not accept percentage to define the size. I will look for another one.
-
Temperature bar: I 'd like to make it the same size as the picture. And the number n vertical. I will search how can I do that. Still couldn’t find out how .
Todo:
-
Better light control, reflecting the brightness level, changing the opacity
-
better pH gauge.
-
Better positioning. Still learning how to do this correctly. I’m having issues when accessing in little screens, such as a phone.
-
Controls to turn on devices not in the picture, like heater,
or refill CO2. -
Adjust temperature bar
-
Show other parameters (amnonia, nitrite, nitrate, etc…)
Here are the codes (yes, it can be immproved):
- Aquaeye on the configurations refer to the device I’m developping.
- There are several helpers to calculate, but some are temporary, because aquaeye if not available yet (like ph, level, etc…).
templates.yaml
- sensor:
- name: "pH do Aquário da Sala"
unique_id: sala_ph
unit_of_measurement: "pH"
device_class: ph
icon: mdi:ph
state: "{{ (states('input_select.c_calib_ph9_10')| float) - ( (((states('input_number.v_calib_mv9') | float)-(states('sensor.aquaeye_sala_ph_ads') | float(0)))*((states('input_select.c_calib_ph7')| float)-(states('input_select.c_calib_ph9_10') | float))) / ((states('input_number.v_calib_mv7') | float)-(states('input_number.v_calib_mv9') | float)) ) | round(2) }}"
- name: "Nível do CO2 da Sala"
icon: mdi:co2
unique_id: co2_sala_nivel
state: >
{% set abastecimento = states('input_datetime.dia_reabastecimento_co2_sala') | as_datetime | as_local %}
{% set duracao = states('input_number.duracao_co2_sala') |int %}
{% set hoje = now() %}
{% set dias_passados = (hoje - abastecimento).days |int %}
{% set nivel = 100 - ((dias_passados * 100) / duracao) |int %}
{{ nivel | int }}
lovelace panel
type: picture-elements
image: /local/itens/aquario-fundo.png
elements:
- type: custom:fluid-level-background-card
entity: sensor.co2_sala_nivel
background_color: transparent
show_state: true
show_icon: false
full_value: 100
level_color: rgba(80, 80, 60, 1)
style:
z-index: 3
top: 78%
left: 10.4%
width: 6.3%
height: 60%
card_mod:
style: |
ha-card {
text-align: center;
--ha-card-border-color: transparent !important;
box-shadow: none !important;
background: none !important;
border-radius: 10px;
overflow: hidden;
}
#container, .container {
width: 100% !important;
height: 40% !important;
position: relative !important;
border-radius: 14px !important;
margin-left: 0%;
margin-top: 0%;
opacity: 0.4;
overflow: hidden;
}
card:
type: custom:button-card
entity: sensor.co2_sala_nivel
title_template: "{{ states('sensor.co2_sala_nivel')|round(0) }} %"
show_header_toggle: false
show_name: false
show_icon: false
show_title: true
tap_action:
action: call-service
confirmation:
text: Marcar hoje como dia de recarga ?
service: input_datetime.set_datetime
service_data:
entity_id: input_datetime.dia_reabastecimento_co2_sala
date: "[[[ return new Date().toLocaleDateString('en-CA') ]]]"
value: "off"
card_mod:
style: |
ha-card {
--ha-card-header-font-size: 20px;
height: 100px !important;
color: white;
font-weight: 800;
}
.card-header {
justify-content: center !important;
}
.name {
overflow: unset !important;
}
- type: image
entity: switch.aeracao_aquario
title: Aeração do Aquário
tap_action:
action: toggle
state_image:
"on": /local/itens/sapo-ligado.png
"off": /local/itens/sapo-desligado.png
style:
z-index: 2
left: 50%
top: 35%
transform: scale(0.2, 0.2) translate(-50%, -50%)
- type: image
entity: switch.energia_aquario_uv
title: Luz UV
tap_action:
action: toggle
state_image:
"on": /local/itens/uv-ligada.png
"off": /local/itens/uv-desligada.png
style:
z-index: 2
left: "-8%"
top: "-5%"
transform: scale(0.1, 0.1) translate(-50%, -50%)
- type: custom:canvas-gauge-card
entity: input_number.ph_temporario
title: pH
show_title: true
style:
z-index: 3
left: 50%
top: 75%
transform: translate(-50%, -50%)
gauge:
type: linear-gauge
barBeginCircle: 0
tickSide: left
numberSide: left
valueBox: true
width: 850
height: 100
minValue: 4
maxValue: 10
minorTicks: 4
colorBarProgressEnd: rgb(5, 115, 34)
colorMajorTicks: white
colorMinorTicks: white
colorStrokeTicks: white
colorTitle: white
colorUnits: white
colorNumbers: white
colorValueText: white
fontTitleSize: 250
fontTitleWeight: bolder
fontTitleStyle: normal
fontValueSize: 90
fontUnitsSize: 50
colorPlate: rgba(0,0,0,0)
borders: false
borderOuterWidth: 0
borderMiddleWidth: 0
borderInnerWidth: 0
majorTicks:
- "4"
- "4.5"
- "5"
- "5.5"
- "6"
- "6.5"
- "7"
- "7.5"
- "8"
- "8.5"
- "9"
- "9.5"
- "10"
highlights:
- from: 4
to: 5
color: rgb(255, 153, 66)
- from: 5
to: 6
color: rgb(255, 200, 2)
- from: 6
to: 7
color: rgb(225, 235, 52)
- from: 7
to: 8
color: rgb(108, 186, 90)
- from: 8
to: 9
color: rgb(20, 153, 53)
- from: 9
to: 10
color: rgb(5, 115, 34)
- type: custom:slider-entity-row
entity: light.luz_do_aquario
style:
z-index: 3
left: 50%
top: 9%
card_mod:
style: |
ha-card {
--ha-card-header-font-size: 20px;
height: 100px !important;
color: white;
font-weight: 800;
}
.card-header {
justify-content: center !important;
}
.name {
overflow: unset !important;
}
- type: image
entity: light.luz_do_aquario
tap_action: none
hold_action: none
state_image:
"on": /local/itens/luz-ligada.png
"off": /local/itens/luz-desligada.png
style:
z-index: 2
top: "-12%"
width: 100%
transform: scale(0.7, 0.7) translate(0%, 0%)
opacity: "{{ states['light.luz_do_aquario'].attributes.brightness / 255 }}"
- type: image
image: /local/itens/circulação.png
style:
z-index: 2
top: 65%
left: 80%
height: 28%
transform: scale(0.6, 0.6) translate(-50%, -50%)
- type: image
entity: switch.aquario_co2
title: CO2 - Clique na válvula para ligar/desligar
tap_action:
action: toggle
state_image:
"on": /local/itens/co2-cilindro-ON.png
"off": /local/itens/co2-cilindro-OFF.png
style:
z-index: 2
top: "-10%"
left: "-13%"
transform: scale(0.2, 0.2) translate(-50%, -50%)
- type: custom:button-card
entity: switch.circulacao_aquario
icon: mdi:fan
show_name: false
title: Liga/Desliga Circulação
style:
z-index: 3
top: 67.5%
left: 82%
height: 8%
styles:
icon:
- width: 40%
state:
- value: "on"
styles:
icon:
- animation: rotating 1s linear infinite
- color: green
- value: "off"
styles:
icon:
- animation: none
- color: red
card_mod:
style: |
ha-card {
text-align: center;
--ha-card-border-color: transparent !important;
box-shadow: none !important;
background: none !important;
border-radius: 10px;
overflow: hidden;
}
- type: custom:button-card
entity: input_number.fluxo_temporario
icon: mdi:fan
tap_action: none
tltle: Fluxo do Filtro
"show_label:": false
show_name: false
style:
z-index: 1
top: 23%
left: 74%
height: 8%
styles:
card:
- font-size: 15px
- font-weight: bold
grid:
- grid-template-areas: "\"i\" \"fluxo\""
- grid-template-columns: 1fr
custom_fields:
fluxo:
- align-self: middle
- color: white
icon:
- color: |
[[[
if (entity.state < 400) return 'red';
if (entity.state >= 400 && entity.state < 649) return 'orange';
else return 'green';
]]]
- width: 30%
- animation: rotating 1s linear infinite
custom_fields:
fluxo: |
[[[
return `<span>${entity.state}L/h</span>`
]]]
card_mod:
style: |
ha-card {
text-align: center;
--ha-card-border-color: transparent !important;
box-shadow: none !important;
background: none !important;
border-radius: 10px;
overflow: hidden;
}
- type: custom:bar-card
animation: "on"
bar-card-color: transparent
bar-card-border-radius: 0
direction: up
entity_row: true
icon: false
max: 32
width: 8%
unit_of_measurement: ºC
positions:
icon: "off"
name: "off"
value: outside
style:
z-index: 1
top: 38.5%
left: 17.3%
severity:
- color: Red
from: 0
to: 24
- color: Orange
from: 24.1
to: 25
- color: Green
from: 25.1
to: 27.9
- color: Red
from: 28
to: 31
card_mod:
style: |
ha-card {
--ha-card-border-width: 0px;
vertical-align: middle;
text-align: center;
}
bar-card-value {
margin-top: auto;
font-size: 13px;
font-weight: bold;
text-shadow: 1px 1px #0005;
text-orientation: mixed;
}
bar-card-max {
margin: 0px;
margin-left: auto;
margin-top: -20px;
top: 10px;
}
entities:
- entity: sensor.temp_bercario
- type: custom:fluid-level-background-card
entity: input_number.nivel_temporario
fill_entity: switch.aeracao_aquario
background_color: transparent
show_state: true
show_icon: false
camera_view: auto
level_color: rgba(82, 171, 255, 1)
style:
z-index: 2
top: 80%
left: 65%
width: 100%
height: 110%
card_mod:
style: |
ha-card {
text-align: center;
--ha-card-border-color: transparent !important;
box-shadow: none !important;
background: none !important;
border-radius: 10px;
overflow: hidden;
}
#container, .container {
width: 71% !important;
height: 40% !important;
position: relative !important;
border-radius: 14px !important;
margin-left: 0%;
margin-top: 0%;
opacity: 0.4;
overflow: hidden;
}
card:
type: custom:card-templater
card:
type: entity
entity: input_number.nivel_temporario
title_template: "{{ states(''input_number.nivel_temporario'')|round(0) }} %"
unit_of_measurement: "%"
show_header_toggle: false
show_name: false
show_icon: false
show_title: true
name: " "
positions:
value: "off"
card_mod:
style: |
ha-card {
--ha-card-header-font-size: 20px;
height: 100px !important;
color: white;
font-weight: 800;
}
.card-header {
justify-content: center !important;
}
.name {
overflow: unset !important;
}
Hope you like…