mirror of
https://github.com/joBr99/nspanel-lovelace-ui.git
synced 2025-12-23 07:54:25 +01:00
inital support for alternating icons
This commit is contained in:
@@ -39,7 +39,8 @@ icons = [
|
|||||||
"battery-medium",
|
"battery-medium",
|
||||||
"shield-home",
|
"shield-home",
|
||||||
"door-open",
|
"door-open",
|
||||||
"door-closed"
|
"door-closed",
|
||||||
|
"window-closed"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ for icon_name in icons:
|
|||||||
icon_name_list.append(icon_name)
|
icon_name_list.append(icon_name)
|
||||||
|
|
||||||
# write mapping lib for python
|
# write mapping lib for python
|
||||||
with open(os.path.join(__location__, "../../../apps/nspanel-lovelace-ui", "icon_mapper.py"), 'w') as f:
|
with open(os.path.join(__location__, "../../../apps/nspanel-lovelace-ui", "icon_mapping.py"), 'w') as f:
|
||||||
f.write("icons = {\n")
|
f.write("icons = {\n")
|
||||||
for idx, val in enumerate(icon_name_list):
|
for idx, val in enumerate(icon_name_list):
|
||||||
f.write(f" '{val}': {idx},\n")
|
f.write(f" '{val}': {idx},\n")
|
||||||
|
|||||||
@@ -42,3 +42,4 @@ ID | MD Icon Name | Icon
|
|||||||
35 | shield-home | 
|
35 | shield-home | 
|
||||||
36 | door-open | 
|
36 | door-open | 
|
||||||
37 | door-closed | 
|
37 | door-closed | 
|
||||||
|
38 | window-closed | 
|
||||||
|
|||||||
BIN
HMI/nspanel.HMI
BIN
HMI/nspanel.HMI
Binary file not shown.
BIN
HMI/nspanel.tft
BIN
HMI/nspanel.tft
Binary file not shown.
@@ -37,6 +37,7 @@ icons = {
|
|||||||
'shield-home': 35,
|
'shield-home': 35,
|
||||||
'door-open': 36,
|
'door-open': 36,
|
||||||
'door-closed': 37,
|
'door-closed': 37,
|
||||||
|
'window-closed': 38,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_icon_id(ma_name):
|
def get_icon_id(ma_name):
|
||||||
64
apps/nspanel-lovelace-ui/icons.py
Normal file
64
apps/nspanel-lovelace-ui/icons.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
from icon_mapping import get_icon_id
|
||||||
|
|
||||||
|
weather_mapping = {
|
||||||
|
'clear-night': 'weather-night',
|
||||||
|
'cloudy': 'weather-cloudy',
|
||||||
|
'exceptional': 'alert-circle-outline',
|
||||||
|
'fog': 'weather-fog',
|
||||||
|
'hail': 'weather-hail',
|
||||||
|
'lightning': 'weather-lightning',
|
||||||
|
'lightning-rainy': 'weather-lightning-rainy',
|
||||||
|
'partlycloudy': 'weather-partly-cloudy',
|
||||||
|
'pouring': 'weather-pouring',
|
||||||
|
'rainy': 'weather-rainy',
|
||||||
|
'snowy': 'weather-snowy',
|
||||||
|
'snowy-rainy': 'weather-snowy-rainy',
|
||||||
|
'sunny': 'weather-sunny',
|
||||||
|
'windy': 'weather-windy',
|
||||||
|
'windy-variant': 'weather-windy-variant'
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor_mapping_on = {
|
||||||
|
"door": "door-open",
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor_mapping_off = {
|
||||||
|
"door": "door-closed",
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor_mapping = {
|
||||||
|
"temperature": "thermometer",
|
||||||
|
"power": "flash"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def map_to_mdi_name(ha_type, state=None, device_class=None):
|
||||||
|
if ha_type == "weather":
|
||||||
|
return weather_mapping[state] if state in weather_mapping else "alert-circle-outline"
|
||||||
|
if ha_type == "button":
|
||||||
|
return "gesture-tap-button"
|
||||||
|
if ha_type == "scene":
|
||||||
|
return "palette"
|
||||||
|
if ha_type == "switch":
|
||||||
|
return "flash"
|
||||||
|
if ha_type == "light":
|
||||||
|
return "lightbulb"
|
||||||
|
if ha_type == "input_boolean":
|
||||||
|
return "check-circle-outline" if entity.state == "on" else "close-circle-outline"
|
||||||
|
if ha_type == "cover":
|
||||||
|
return "window-open" if entity.state == "open" else "window-closed"
|
||||||
|
|
||||||
|
elif ha_type == "sensor":
|
||||||
|
if state == "on":
|
||||||
|
return sensor_mapping_on[device_class] if device_class in sensor_mapping_on else "alert-circle-outline"
|
||||||
|
elif state == "off":
|
||||||
|
return sensor_mapping_off[device_class] if device_class in sensor_mapping_off else "alert-circle-outline"
|
||||||
|
else:
|
||||||
|
return sensor_mapping[device_class] if device_class in sensor_mapping else "alert-circle-outline"
|
||||||
|
|
||||||
|
return "alert-circle-outline"
|
||||||
|
|
||||||
|
def get_icon_id_ha(ha_name, state=None, device_class=None, overwrite=None):
|
||||||
|
if overwrite is not None:
|
||||||
|
return get_icon_id(overwrite)
|
||||||
|
return get_icon_id(map_to_mdi_name(ha_name, state, device_class))
|
||||||
@@ -2,8 +2,8 @@ import json
|
|||||||
import datetime
|
import datetime
|
||||||
import hassapi as hass
|
import hassapi as hass
|
||||||
from helper import scale, pos_to_color, rgb_dec565, rgb_brightness
|
from helper import scale, pos_to_color, rgb_dec565, rgb_brightness
|
||||||
from icon_mapper import get_icon_id
|
from icon_mapping import get_icon_id
|
||||||
|
from icons import get_icon_id_ha
|
||||||
# check Babel
|
# check Babel
|
||||||
import importlib
|
import importlib
|
||||||
babel_spec = importlib.util.find_spec("babel")
|
babel_spec = importlib.util.find_spec("babel")
|
||||||
@@ -320,43 +320,30 @@ class LovelaceUIPanel:
|
|||||||
we = self.api.get_entity(self.config["weatherEntity"])
|
we = self.api.get_entity(self.config["weatherEntity"])
|
||||||
unit = "°C"
|
unit = "°C"
|
||||||
|
|
||||||
# this maps possible states from ha to material design icon names
|
icon_cur = get_icon_id_ha("weather", state=we.state)
|
||||||
weathericons = {
|
text_cur = f"{we.attributes.temperature}{unit}"
|
||||||
'clear-night': 'weather-night',
|
icon_cur_detail = get_icon_id("water-percent")
|
||||||
'cloudy': 'weather-cloudy',
|
text_cur_detail = f"{we.attributes.humidity} %"
|
||||||
'exceptional': 'alert-circle-outline',
|
|
||||||
'fog': 'weather-fog',
|
|
||||||
'hail': 'weather-hail',
|
|
||||||
'lightning': 'weather-lightning',
|
|
||||||
'lightning-rainy': 'weather-lightning-rainy',
|
|
||||||
'partlycloudy': 'weather-partly-cloudy',
|
|
||||||
'pouring': 'weather-pouring',
|
|
||||||
'rainy': 'weather-rainy',
|
|
||||||
'snowy': 'weather-snowy',
|
|
||||||
'snowy-rainy': 'weather-snowy-rainy',
|
|
||||||
'sunny': 'weather-sunny',
|
|
||||||
'windy': 'weather-windy',
|
|
||||||
'windy-variant': 'weather-windy-variant'
|
|
||||||
}
|
|
||||||
|
|
||||||
i1 = get_icon_id(weathericons[we.attributes.forecast[0]['condition']])
|
up1 = we.attributes.forecast[0]['datetime']
|
||||||
u1 = we.attributes.forecast[0]['temperature']
|
up1 = datetime.datetime.fromisoformat(up1)
|
||||||
i2 = get_icon_id(weathericons[we.attributes.forecast[1]['condition']])
|
icon1 = get_icon_id_ha("weather", state=we.attributes.forecast[0]['condition'])
|
||||||
u2 = we.attributes.forecast[1]['temperature']
|
down1 = we.attributes.forecast[0]['temperature']
|
||||||
|
|
||||||
|
up2 = we.attributes.forecast[1]['datetime']
|
||||||
|
up2 = datetime.datetime.fromisoformat(up2)
|
||||||
|
icon2 = get_icon_id_ha("weather", state=we.attributes.forecast[1]['condition'])
|
||||||
|
down2 = we.attributes.forecast[1]['temperature']
|
||||||
|
|
||||||
o1 = we.attributes.forecast[0]['datetime']
|
|
||||||
o1 = datetime.datetime.fromisoformat(o1)
|
|
||||||
o2 = we.attributes.forecast[1]['datetime']
|
|
||||||
o2 = datetime.datetime.fromisoformat(o2)
|
|
||||||
global babel_spec
|
global babel_spec
|
||||||
if babel_spec is not None:
|
if babel_spec is not None:
|
||||||
o1 = babel.dates.format_date(o1, "E", locale=self.config["locale"])
|
up1 = babel.dates.format_date(up1, "E", locale=self.config["locale"])
|
||||||
o2 = babel.dates.format_date(o2, "E", locale=self.config["locale"])
|
up2 = babel.dates.format_date(up2, "E", locale=self.config["locale"])
|
||||||
else:
|
else:
|
||||||
o1 = o1.strftime("%a")
|
up1 = up1.strftime("%a")
|
||||||
o2 = o2.strftime("%a")
|
up2 = up2.strftime("%a")
|
||||||
|
|
||||||
self.send_mqtt_msg(f"weatherUpdate,?{get_icon_id(weathericons[we.state])}?{we.attributes.temperature}{unit}?{26}?{we.attributes.humidity} %?{o1}?{i1}?{u1}?{o2}?{i2}?{u2}")
|
self.send_mqtt_msg(f"weatherUpdate,?{icon_cur}?{text_cur}?{icon_cur_detail}?{text_cur_detail}?{up1}?{icon1}?{down1}?{up2}?{icon2}?{down2}")
|
||||||
|
|
||||||
|
|
||||||
def handle_button_press(self, entity_id, btype, optVal=None):
|
def handle_button_press(self, entity_id, btype, optVal=None):
|
||||||
@@ -474,48 +461,34 @@ class LovelaceUIPanel:
|
|||||||
name = entity.attributes.friendly_name
|
name = entity.attributes.friendly_name
|
||||||
|
|
||||||
if item_type == "cover":
|
if item_type == "cover":
|
||||||
icon_id = get_icon_id('window-open') if icon is None else get_icon_id(icon)
|
icon_id = get_icon_id_ha("cover", state=entity.state overwrite=icon)
|
||||||
return f",shutter,{item},{icon_id},17299,{name},"
|
return f",shutter,{item},{icon_id},17299,{name},"
|
||||||
|
|
||||||
if item_type == "light":
|
if item_type == "light":
|
||||||
switch_val = 1 if entity.state == "on" else 0
|
switch_val = 1 if entity.state == "on" else 0
|
||||||
icon_color = self.getEntityColor(entity)
|
icon_color = self.getEntityColor(entity)
|
||||||
icon_id = get_icon_id('lightbulb') if icon is None else get_icon_id(icon)
|
icon_id = get_icon_id_ha("light", overwrite=icon)
|
||||||
return f",{item_type},{item},{icon_id},{icon_color},{name},{switch_val}"
|
return f",{item_type},{item},{icon_id},{icon_color},{name},{switch_val}"
|
||||||
|
|
||||||
if item_type == "switch" or item_type == "input_boolean":
|
if item_type == "switch" or item_type == "input_boolean":
|
||||||
|
icon_id = get_icon_id_ha(item_type, overwrite=icon)
|
||||||
switch_val = 1 if entity.state == "on" else 0
|
switch_val = 1 if entity.state == "on" else 0
|
||||||
icon_id = get_icon_id('flash') if icon is None else get_icon_id(icon)
|
|
||||||
icon_color = self.getEntityColor(entity)
|
icon_color = self.getEntityColor(entity)
|
||||||
if item_type == "input_boolean":
|
|
||||||
icon_id = get_icon_id("check-circle-outline") if switch_val == 1 else get_icon_id("close-circle-outline")
|
|
||||||
return f",switch,{item},{icon_id},{icon_color},{name},{switch_val}"
|
return f",switch,{item},{icon_id},{icon_color},{name},{switch_val}"
|
||||||
|
|
||||||
if item_type in ["sensor", "binary_sensor"]:
|
if item_type in ["sensor", "binary_sensor"]:
|
||||||
# maps ha device classes to material design icons
|
device_class = self.get_safe_ha_attribute(entity.attributes, "device_class", "")
|
||||||
icon_mapping = {
|
icon_id = get_icon_id_ha("sensor", state=entity.state, device_class=device_class, overwrite=icon)
|
||||||
"temperature": "thermometer",
|
|
||||||
"power": "flash"
|
|
||||||
}
|
|
||||||
if "device_class" in entity.attributes:
|
|
||||||
if entity.attributes.device_class in icon_mapping:
|
|
||||||
icon_id = icon_mapping[entity.attributes.device_class]
|
|
||||||
else:
|
|
||||||
self.api.log("No Icon found for device_class: %s. Please open a issue on github to report the missing mapping.", entity.attributes.device_class)
|
|
||||||
icon_id = get_icon_id('alert-circle-outline')
|
|
||||||
else:
|
|
||||||
icon_id = get_icon_id('alert-circle-outline')
|
|
||||||
|
|
||||||
unit_of_measurement = self.get_safe_ha_attribute(entity.attributes, "unit_of_measurement", "")
|
unit_of_measurement = self.get_safe_ha_attribute(entity.attributes, "unit_of_measurement", "")
|
||||||
value = entity.state + " " + unit_of_measurement
|
value = entity.state + " " + unit_of_measurement
|
||||||
return f",text,{item},{icon_id},17299,{name},{value}"
|
return f",text,{item},{icon_id},17299,{name},{value}"
|
||||||
|
|
||||||
if item_type in ["button", "input_button"]:
|
if item_type in ["button", "input_button"]:
|
||||||
icon_id = get_icon_id('gesture-tap-button') if icon is None else get_icon_id(icon)
|
icon_id = get_icon_id_ha("button", overwrite=icon)
|
||||||
return f",button,{item},{icon_id},17299,{name},PRESS"
|
return f",button,{item},{icon_id},17299,{name},PRESS"
|
||||||
|
|
||||||
if item_type == "scene":
|
if item_type == "scene":
|
||||||
icon_id = get_icon_id('palette') if icon is None else get_icon_id(icon)
|
icon_id = get_icon_id_ha("scene", overwrite=icon)
|
||||||
return f",button,{item},{icon_id},17299,{name},ACTIVATE"
|
return f",button,{item},{icon_id},17299,{name},ACTIVATE"
|
||||||
|
|
||||||
def generate_entities_page(self, items):
|
def generate_entities_page(self, items):
|
||||||
|
|||||||
Reference in New Issue
Block a user