1- import type { CSSResultGroup , PropertyValues , TemplateResult } from "lit" ;
1+ import type { CSSResultGroup , PropertyValues } from "lit" ;
22import { LitElement , css , html , nothing } from "lit" ;
33import { mdiPencil , mdiDownload } from "@mdi/js" ;
44import { customElement , property , state } from "lit/decorators" ;
55import "../../components/ha-menu-button" ;
66import "../../components/ha-icon-button-arrow-prev" ;
77import "../../components/ha-list-item" ;
88import "../../components/ha-top-app-bar-fixed" ;
9+ import "../../components/ha-alert" ;
910import type { LovelaceConfig } from "../../data/lovelace/config/types" ;
1011import { haStyle } from "../../resources/styles" ;
1112import type { HomeAssistant } from "../../types" ;
@@ -21,6 +22,7 @@ import type {
2122 GasSourceTypeEnergyPreference ,
2223 WaterSourceTypeEnergyPreference ,
2324 DeviceConsumptionEnergyPreference ,
25+ EnergyCollection ,
2426} from "../../data/energy" ;
2527import {
2628 computeConsumptionData ,
@@ -30,12 +32,27 @@ import {
3032import { fileDownload } from "../../util/file_download" ;
3133import type { StatisticValue } from "../../data/recorder" ;
3234
35+ export const DEFAULT_ENERGY_COLLECTION_KEY = "energy_dashboard" ;
36+
3337const ENERGY_LOVELACE_CONFIG : LovelaceConfig = {
3438 views : [
3539 {
3640 strategy : {
37- type : "energy" ,
41+ type : "energy-overview" ,
42+ collection_key : DEFAULT_ENERGY_COLLECTION_KEY ,
43+ } ,
44+ } ,
45+ {
46+ strategy : {
47+ type : "energy-electricity" ,
48+ collection_key : DEFAULT_ENERGY_COLLECTION_KEY ,
3849 } ,
50+ path : "electricity" ,
51+ } ,
52+ {
53+ type : "panel" ,
54+ path : "setup" ,
55+ cards : [ { type : "custom:energy-setup-wizard-card" } ] ,
3956 } ,
4057 ] ,
4158} ;
@@ -46,13 +63,30 @@ class PanelEnergy extends LitElement {
4663
4764 @property ( { type : Boolean , reflect : true } ) public narrow = false ;
4865
49- @state ( ) private _viewIndex = 0 ;
50-
5166 @state ( ) private _lovelace ?: Lovelace ;
5267
5368 @state ( ) private _searchParms = new URLSearchParams ( window . location . search ) ;
5469
55- public willUpdate ( changedProps : PropertyValues ) {
70+ @state ( ) private _error ?: string ;
71+
72+ @property ( { attribute : false } ) public route ?: {
73+ path : string ;
74+ prefix : string ;
75+ } ;
76+
77+ private _energyCollection ?: EnergyCollection ;
78+
79+ get _viewPath ( ) : string | undefined {
80+ const viewPath : string | undefined = this . route ! . path . split ( "/" ) [ 1 ] ;
81+ return viewPath ? decodeURI ( viewPath ) : undefined ;
82+ }
83+
84+ public connectedCallback ( ) {
85+ super . connectedCallback ( ) ;
86+ this . _loadPrefs ( ) ;
87+ }
88+
89+ public async willUpdate ( changedProps : PropertyValues ) {
5690 if ( ! this . hasUpdated ) {
5791 this . hass . loadFragmentTranslation ( "lovelace" ) ;
5892 }
@@ -62,22 +96,71 @@ class PanelEnergy extends LitElement {
6296 const oldHass = changedProps . get ( "hass" ) as this[ "hass" ] ;
6397 if ( oldHass ?. locale !== this . hass . locale ) {
6498 this . _setLovelace ( ) ;
65- }
66- if ( oldHass && oldHass . localize !== this . hass . localize ) {
99+ } else if ( oldHass && oldHass . localize !== this . hass . localize ) {
67100 this . _reloadView ( ) ;
68101 }
69102 }
70103
104+ private async _loadPrefs ( ) {
105+ if ( this . _viewPath === "setup" ) {
106+ await import ( "./cards/energy-setup-wizard-card" ) ;
107+ } else {
108+ this . _energyCollection = getEnergyDataCollection ( this . hass , {
109+ key : DEFAULT_ENERGY_COLLECTION_KEY ,
110+ } ) ;
111+ try {
112+ // Have to manually refresh here as we don't want to subscribe yet
113+ await this . _energyCollection . refresh ( ) ;
114+ } catch ( err : any ) {
115+ if ( err . code === "not_found" ) {
116+ navigate ( "/energy/setup" ) ;
117+ }
118+ this . _error = err . message ;
119+ return ;
120+ }
121+ const prefs = this . _energyCollection . prefs ! ;
122+ if (
123+ prefs . device_consumption . length === 0 &&
124+ prefs . energy_sources . length === 0
125+ ) {
126+ // No energy sources available, start from scratch
127+ navigate ( "/energy/setup" ) ;
128+ }
129+ }
130+ }
131+
71132 private _back ( ev ) {
72133 ev . stopPropagation ( ) ;
73134 goBack ( ) ;
74135 }
75136
76- protected render ( ) : TemplateResult {
137+ protected render ( ) {
138+ if ( ! this . _energyCollection ?. prefs ) {
139+ // Still loading
140+ return html `<div class= "centered" >
141+ <ha- spinner size= "large" > </ ha- spinner>
142+ </ div> ` ;
143+ }
144+ const { prefs } = this . _energyCollection ;
145+ const isSingleView = prefs . energy_sources . every ( ( source ) =>
146+ [ "grid" , "solar" , "battery" ] . includes ( source . type )
147+ ) ;
148+ let viewPath = this . _viewPath ;
149+ if ( isSingleView ) {
150+ // if only electricity sources, show electricity view directly
151+ viewPath = "electricity" ;
152+ }
153+ const viewIndex = Math . max (
154+ ENERGY_LOVELACE_CONFIG . views . findIndex ( ( view ) => view . path === viewPath ) ,
155+ 0
156+ ) ;
157+ const showBack =
158+ this . _searchParms . has ( "historyBack" ) || ( ! isSingleView && viewIndex > 0 ) ;
159+
77160 return html `
78161 <div class= "header" >
79162 <div class= "toolbar" >
80- ${ this . _searchParms . has ( "historyBack" )
163+ ${ showBack
81164 ? html `
82165 <ha- icon- butto n- arrow- prev
83166 @click = ${ this . _back }
@@ -99,7 +182,7 @@ class PanelEnergy extends LitElement {
99182
100183 <hui- energy- period- selector
101184 .hass = ${ this . hass }
102- collection - key = "energy_dashboard"
185+ . collectionKey = ${ DEFAULT_ENERGY_COLLECTION_KEY }
103186 >
104187 ${ this . hass . user ?. is_admin
105188 ? html ` <ha- lis t- item
@@ -127,12 +210,21 @@ class PanelEnergy extends LitElement {
127210 .hass = ${ this . hass }
128211 @reload-energy-panel = ${ this . _reloadView }
129212 >
130- <hui- view
131- .hass = ${ this . hass }
132- .narrow = ${ this . narrow }
133- .lovelace = ${ this . _lovelace }
134- .index = ${ this . _viewIndex }
135- > </ hui- view>
213+ ${ this . _error
214+ ? html `<div class= "centered" >
215+ <ha- alert alert- type= "error" >
216+ An error occurred while fetching your energy preferences :
217+ ${ this . _error }
218+ </ ha- alert>
219+ </ div> `
220+ : this . _lovelace
221+ ? html `<hui- view
222+ .hass = ${ this . hass }
223+ .narrow = ${ this . narrow }
224+ .lovelace = ${ this . _lovelace }
225+ .index = ${ viewIndex }
226+ > </ hui- view> `
227+ : nothing }
136228 </ hui- view- container>
137229 ` ;
138230 }
@@ -160,9 +252,7 @@ class PanelEnergy extends LitElement {
160252
161253 private async _dumpCSV ( ev ) {
162254 ev . stopPropagation ( ) ;
163- const energyData = getEnergyDataCollection ( this . hass , {
164- key : "energy_dashboard" ,
165- } ) ;
255+ const energyData = this . _energyCollection ! ;
166256
167257 if ( ! energyData . prefs || ! energyData . state . stats ) {
168258 return ;
@@ -459,11 +549,11 @@ class PanelEnergy extends LitElement {
459549 }
460550
461551 private _reloadView ( ) {
462- // Force strategy to be re-run by make a copy of the view
552+ // Force strategy to be re-run by making a copy of the view
463553 const config = this . _lovelace ! . config ;
464554 this . _lovelace = {
465555 ...this . _lovelace ! ,
466- config : { ...config , views : [ { ...config . views [ 0 ] } ] } ,
556+ config : { ...config , views : config . views . map ( ( view ) => ( { ...view } ) ) } ,
467557 } ;
468558 }
469559
@@ -565,6 +655,13 @@ class PanelEnergy extends LitElement {
565655 flex : 1 1 100% ;
566656 max-width : 100% ;
567657 }
658+ .centered {
659+ width : 100% ;
660+ height : 100% ;
661+ display : flex;
662+ align-items : center;
663+ justify-content : center;
664+ }
568665 ` ,
569666 ] ;
570667 }
0 commit comments