mirror of
https://github.com/joBr99/nspanel-lovelace-ui.git
synced 2025-12-20 22:47:01 +01:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a94cf0cef3 | ||
|
|
d01ccede57 | ||
|
|
65be5ffeb0 | ||
|
|
d53afb0b20 | ||
|
|
9822870fc9 | ||
|
|
8a54d1422c | ||
|
|
3f573557f0 | ||
|
|
c2ca3b26d1 | ||
|
|
476a252a92 | ||
|
|
0af779973b | ||
|
|
8e0609a781 | ||
|
|
5dab816259 | ||
|
|
5f8409f5f1 | ||
|
|
3d85e86a95 | ||
|
|
85de880cda | ||
|
|
98269b19aa | ||
|
|
d77382ee88 | ||
|
|
e925d133d2 | ||
|
|
5ef3e8132b | ||
|
|
662b79a389 | ||
|
|
c984ff53a3 | ||
|
|
f8b748a418 | ||
|
|
bc31670760 | ||
|
|
cbf6abf4dd | ||
|
|
5c85e4a6e1 | ||
|
|
cbede2412e | ||
|
|
82d22743cc | ||
|
|
640d0dfa14 | ||
|
|
ccc62d1e6a | ||
|
|
6cec0245a3 | ||
|
|
f3c98adf06 | ||
|
|
f4487e4285 | ||
|
|
8e2780b2cb | ||
|
|
0372221973 | ||
|
|
947ef2d592 | ||
|
|
a1f39236c4 | ||
|
|
4cdd1ed586 | ||
|
|
1836d29931 | ||
|
|
fca29cfbd8 | ||
|
|
b27910c1af | ||
|
|
f046ae6031 | ||
|
|
4475ab1277 | ||
|
|
9afdb71a7c | ||
|
|
c84d78551f | ||
|
|
5e2a4b17ae | ||
|
|
acdba468b3 | ||
|
|
5803a489f5 | ||
|
|
54c8d302a8 | ||
|
|
8059905579 |
4
.github/workflows/builder.yaml
vendored
4
.github/workflows/builder.yaml
vendored
@@ -92,7 +92,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
if: env.BUILD_ARGS != '--test'
|
if: env.BUILD_ARGS != '--test'
|
||||||
uses: docker/login-action@v3.3.0
|
uses: docker/login-action@v3.4.0
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
@@ -100,7 +100,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build ${{ matrix.addon }} add-on
|
- name: Build ${{ matrix.addon }} add-on
|
||||||
if: steps.check.outputs.build_arch == 'true'
|
if: steps.check.outputs.build_arch == 'true'
|
||||||
uses: home-assistant/builder@2024.08.2
|
uses: home-assistant/builder@2025.03.0
|
||||||
with:
|
with:
|
||||||
args: |
|
args: |
|
||||||
${{ env.BUILD_ARGS }} \
|
${{ env.BUILD_ARGS }} \
|
||||||
|
|||||||
@@ -334,6 +334,11 @@ class LuiController(object):
|
|||||||
apis.ha_api.get_entity(entity_id).call_service("return_to_base")
|
apis.ha_api.get_entity(entity_id).call_service("return_to_base")
|
||||||
elif entity_id.startswith('service'):
|
elif entity_id.startswith('service'):
|
||||||
apis.ha_api.call_service(entity_id.replace('service.', '', 1).replace('.','/', 1), **entity_config.data)
|
apis.ha_api.call_service(entity_id.replace('service.', '', 1).replace('.','/', 1), **entity_config.data)
|
||||||
|
elif entity_id.startswith('valve'):
|
||||||
|
if apis.ha_api.get_entity(entity_id).state == "open":
|
||||||
|
apis.ha_api.get_entity(entity_id).call_service("close_valve")
|
||||||
|
else:
|
||||||
|
apis.ha_api.get_entity(entity_id).call_service("open_valve")
|
||||||
|
|
||||||
# for media page
|
# for media page
|
||||||
if button_type == "media-next":
|
if button_type == "media-next":
|
||||||
|
|||||||
@@ -159,8 +159,8 @@ alarm_control_panel_mapping = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
climate_mapping = {
|
climate_mapping = {
|
||||||
'auto': 'calendar-sync',
|
'auto': 'fan-auto',
|
||||||
'heat_cool': 'calendar-sync',
|
'heat_cool': 'sun-snowflake-variant',
|
||||||
'heat': 'fire',
|
'heat': 'fire',
|
||||||
'off': 'power',
|
'off': 'power',
|
||||||
'cool': 'snowflake',
|
'cool': 'snowflake',
|
||||||
|
|||||||
@@ -309,6 +309,11 @@ class LuiPagesGen(object):
|
|||||||
unit_of_measurement = entity.attributes.get("unit_of_measurement", "")
|
unit_of_measurement = entity.attributes.get("unit_of_measurement", "")
|
||||||
value = entity.state
|
value = entity.state
|
||||||
|
|
||||||
|
try:
|
||||||
|
value = str(round(float(value), 1))
|
||||||
|
except:
|
||||||
|
print("An exception occurred")
|
||||||
|
|
||||||
# limit value to 4 chars on us-p
|
# limit value to 4 chars on us-p
|
||||||
if self._config.get("model") == "us-p" and cardType == "cardEntities":
|
if self._config.get("model") == "us-p" and cardType == "cardEntities":
|
||||||
value = entity.state[:4]
|
value = entity.state[:4]
|
||||||
@@ -382,20 +387,50 @@ class LuiPagesGen(object):
|
|||||||
elif entityType == "weather":
|
elif entityType == "weather":
|
||||||
entityTypePanel = "text"
|
entityTypePanel = "text"
|
||||||
unit = get_attr_safe(entity, "temperature_unit", "")
|
unit = get_attr_safe(entity, "temperature_unit", "")
|
||||||
if type(item.stype) == int and len(entity.attributes['forecast']) >= item.stype:
|
rt = None
|
||||||
fdate = dp.parse(entity.attributes['forecast'][item.stype]['datetime'])
|
if type(item.stype) == str and ":" in item.stype and len(item.stype.split(":")) == 2:
|
||||||
global babel_spec
|
spintstr = item.stype.split(":")
|
||||||
if babel_spec is not None:
|
rt = spintstr[0]
|
||||||
dateformat = "E" if item.nameOverride is None else item.nameOverride
|
item.stype = int(spintstr[1])
|
||||||
name = babel.dates.format_datetime(fdate.astimezone(), dateformat, locale=self._locale)
|
if type(item.stype) == int:
|
||||||
|
bits = get_attr_safe(entity, "supported_features", 0b0)
|
||||||
|
if not rt:
|
||||||
|
rt = "daily"
|
||||||
|
if bits & 0b001: #FORECAST_DAILY
|
||||||
|
rt = "daily"
|
||||||
|
elif bits & 0b010: #FORECAST_HOURLY
|
||||||
|
rt = "hourly"
|
||||||
|
elif bits & 0b100: #FORECAST_TWICE_DAILY
|
||||||
|
rt = "twice_daily"
|
||||||
|
|
||||||
|
results = apis.ha_api.call_service(
|
||||||
|
"weather/get_forecasts", target={"entity_id": entityId}, service_data={"type": rt}
|
||||||
|
)
|
||||||
|
forecast = results.get("result", {}).get("response", {}).get(entityId, {}).get('forecast') or entity.attributes.get('forecast', [])
|
||||||
|
if len(forecast) >= item.stype:
|
||||||
|
day_forecast = forecast[item.stype]
|
||||||
|
fdate = dp.parse(day_forecast['datetime'])
|
||||||
|
global babel_spec
|
||||||
|
if babel_spec is not None:
|
||||||
|
dateformat = "E" if item.nameOverride is None else item.nameOverride
|
||||||
|
name = babel.dates.format_datetime(fdate.astimezone(), dateformat, locale=self._locale)
|
||||||
|
else:
|
||||||
|
dateformat = "%a" if item.nameOverride is None else item.nameOverride
|
||||||
|
name = fdate.astimezone().strftime(dateformat)
|
||||||
|
icon_id = get_icon_ha(entityId, stateOverwrite=day_forecast['condition'])
|
||||||
|
value = f'{day_forecast.get("temperature", "")}{unit}'
|
||||||
|
color = self.get_entity_color(entity, ha_type=entityType, stateOverwrite=day_forecast['condition'], overwrite=colorOverride)
|
||||||
else:
|
else:
|
||||||
dateformat = "%a" if item.nameOverride is None else item.nameOverride
|
value = f'{get_attr_safe(entity, "temperature", "")}{unit}'
|
||||||
name = fdate.astimezone().strftime(dateformat)
|
|
||||||
icon_id = get_icon_ha(entityId, stateOverwrite=entity.attributes['forecast'][item.stype]['condition'])
|
|
||||||
value = f'{entity.attributes['forecast'][item.stype].get("temperature", "")}{unit}'
|
|
||||||
color = self.get_entity_color(entity, ha_type=entityType, stateOverwrite=entity.attributes['forecast'][item.stype]['condition'], overwrite=colorOverride)
|
|
||||||
else:
|
else:
|
||||||
value = f'{get_attr_safe(entity, "temperature", "")}{unit}'
|
value = f'{get_attr_safe(entity, "temperature", "")}{unit}'
|
||||||
|
elif entityType == "valve":
|
||||||
|
entityTypePanel = "valve"
|
||||||
|
value = get_translation(self._locale, f"backend.component.binary_sensor.state.door.{entity.state}")
|
||||||
|
if entity.state == "open":
|
||||||
|
icon_id = get_icon_id("valve-open")
|
||||||
|
else:
|
||||||
|
icon_id = get_icon_id("valve-closed")
|
||||||
else:
|
else:
|
||||||
name = "unsupported"
|
name = "unsupported"
|
||||||
# Overwrite for value
|
# Overwrite for value
|
||||||
@@ -1059,3 +1094,4 @@ class LuiPagesGen(object):
|
|||||||
self._send_mqtt_msg(f"pageType~popupNotify")
|
self._send_mqtt_msg(f"pageType~popupNotify")
|
||||||
self._send_mqtt_msg(f"entityUpdateDetail~{ident}~{heading}~65535~{b1}~65535~{b2}~65535~{msg}~65535~0")
|
self._send_mqtt_msg(f"entityUpdateDetail~{ident}~{heading}~65535~{b1}~65535~{b2}~65535~{msg}~65535~0")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class NsPanelLovelaceUIManager(ad.ADBase):
|
|||||||
|
|
||||||
desired_tasmota_driver_version = 8
|
desired_tasmota_driver_version = 8
|
||||||
desired_display_firmware_version = 53
|
desired_display_firmware_version = 53
|
||||||
version = "v4.3.3"
|
version = "v4.7.3"
|
||||||
|
|
||||||
model = cfg.get("model")
|
model = cfg.get("model")
|
||||||
if model == "us-l":
|
if model == "us-l":
|
||||||
|
|||||||
@@ -94,37 +94,3 @@ Now, to install NSPanel Lovelace UI Backend with HACS, follow these steps:
|
|||||||
proceed with the download
|
proceed with the download
|
||||||
7. The Backend Application is now installed, and HACS will inform you when updates are available
|
7. The Backend Application is now installed, and HACS will inform you when updates are available
|
||||||
|
|
||||||
# Workaround for HomeAssistant 2024.04
|
|
||||||
AppDaemon is using the old REST API that until AppDaemon moved on the the websocket API this woraround is needed to get weather forecast data from homeassistant. (https://github.com/AppDaemon/appdaemon/issues/1837)
|
|
||||||
|
|
||||||
To get the forecast data in appdaemon, there is a script needed in homeassistant's configuration.yaml:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
template:
|
|
||||||
- trigger:
|
|
||||||
- platform: time_pattern
|
|
||||||
hours: /1
|
|
||||||
- platform: homeassistant
|
|
||||||
event: start
|
|
||||||
action:
|
|
||||||
- service: weather.get_forecasts
|
|
||||||
data:
|
|
||||||
type: daily
|
|
||||||
target:
|
|
||||||
entity_id: weather.home # change to your weather entity
|
|
||||||
response_variable: daily
|
|
||||||
sensor:
|
|
||||||
- name: Weather Forecast Daily
|
|
||||||
unique_id: weather_forecast_daily
|
|
||||||
state: "{{ states('weather.home') }}" # # change to your weather entity in this line
|
|
||||||
attributes:
|
|
||||||
temperature: "{{ state_attr('weather.home', 'temperature') }}" # change to your weather entity
|
|
||||||
temperature_unit: "{{ state_attr('weather.home', 'temperature_unit') }}" # change to your weather entity
|
|
||||||
forecast: "{{ daily['weather.home'].forecast }}" # change to your weather entity
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
Adjust the entities in your apps.yaml that are accessing the forecast to the newly created trigger template:
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user