Advertisement
dckiller

linky-card1

Nov 22nd, 2020
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.03 KB | None | 0 0
  1. const LitElement = Object.getPrototypeOf(
  2. customElements.get("ha-panel-lovelace")
  3. );
  4. const html = LitElement.prototype.html;
  5. const css = LitElement.prototype.css;
  6.  
  7. function hasConfigOrEntityChanged(element, changedProps) {
  8. if (changedProps.has("config")) {
  9. return true;
  10. }
  11.  
  12. const oldHass = changedProps.get("hass");
  13. if (oldHass) {
  14. return (
  15. oldHass.states[element.config.entity] !==
  16. element.hass.states[element.config.entity]
  17. );
  18. }
  19.  
  20. return true;
  21. }
  22.  
  23. class LinkyCard1 extends LitElement {
  24. static get properties() {
  25. return {
  26. config: {},
  27. hass: {}
  28. };
  29. }
  30.  
  31. render() {
  32. if (!this.config || !this.hass) {
  33. return html``;
  34. }
  35.  
  36. const stateObj = this.hass.states[this.config.entity];
  37.  
  38. if (!stateObj) {
  39. return html`
  40. <ha-card>
  41. <div class="card">
  42. <div id="states">
  43. <div class="name">
  44. <ha-icon id="icon" icon="mdi:flash" data-state="unavailable" data-domain="connection" style="color: var(--state-icon-unavailable-color)"></ha-icon>
  45. <span style="margin-right:2em">Linky : donnees inaccessible</span>
  46. </div>
  47. </div>
  48. </div>
  49. </ha-card>
  50. `
  51. }
  52.  
  53. const attributes = stateObj.attributes;
  54.  
  55. if (stateObj) {
  56. return html`
  57. <ha-card>
  58. <div class="card">
  59. <div class="main-info">
  60. <div class="icon-block">
  61. <span class="linky-icon bigger" style="background: none, url(/local/plugins/linky-card1/linky.png) no-repeat; background-size: contain;"></span>
  62. </div>
  63. ${this.config.showPeakOffPeak
  64. ? html`
  65. <div class="hp-hc-block">
  66. <span class="conso-hc">${this.toFloat(attributes.offpeak_hours)}</span><span class="conso-unit-hc"> ${attributes.unit_of_measurement} <span class="more-unit">(en HC)</span></span><br />
  67. <span class="conso-hp">${this.toFloat(attributes.peak_hours)}</span><span class="conso-unit-hp"> ${attributes.unit_of_measurement} <span class="more-unit">(en HP)</span></span>
  68. </div>`
  69. : html`
  70. <div class="cout-block">
  71. <span class="cout">${this.toFloat(stateObj.state)}</span>
  72. <span class="cout-unit">${attributes.unit_of_measurement}</span>
  73. </div>`
  74. }
  75. <div class="cout-block">
  76. <span class="cout" title="Coût journalier">${this.toFloat(attributes.daily_cost, 2)}</span><span class="cout-unit"> €</span>
  77. </div>
  78. </div>
  79. <div class="variations">
  80. <span class="variations-linky">
  81. <span class="ha-icon">
  82. <ha-icon icon="mdi:arrow-right" style="transform: rotate(${(attributes.monthly_evolution < 0) ? '45' : ((attributes.monthly_evolution == 0) ? "0" : "-45")}deg)">
  83. </ha-icon>
  84. </span>
  85. ${Math.round(attributes.monthly_evolution)}<span class="unit"> %</span><span class="previous-month">par rapport à ${this.previousMonth()}</span>
  86. </span>
  87. ${this.config.showPeakOffPeak
  88. ? html `
  89. <span class="variations-linky">
  90. <span class="ha-icon">
  91. <ha-icon icon="mdi:flash"></ha-icon>
  92. </span>
  93. ${Math.round(attributes.peak_offpeak_percent)}<span class="unit"> % HP</span>
  94. </span>`
  95. : html ``
  96. }
  97.  
  98. </div>
  99. ${this.renderHistory(attributes.daily, attributes.unit_of_measurement, this.config)}
  100. </div>
  101. <ha-card>`
  102. }
  103. }
  104.  
  105. renderHistory(daily, unit_of_measurement, config) {
  106. if (this.config.showHistory === true) {
  107. return html
  108. `
  109. <div class="week-history">
  110. ${daily.slice(0, 7).reverse().map((day, index) => this.renderDay(day, 7-index, unit_of_measurement, config))}
  111. </div>
  112. `
  113. }
  114. }
  115.  
  116. renderDay(day, dayNumber, unit_of_measurement, config) {
  117. return html
  118. `
  119. <div class="day">
  120. <span class="dayname">${new Date(new Date().setDate(new Date().getDate()-(Number.parseInt(dayNumber)))).toLocaleDateString('fr-FR', {weekday: "long"}).split(' ')[0]}</span>
  121. <br><span class="cons-val">${this.toFloat(day)}
  122. ${this.config.showInTableUnit
  123. ? html `
  124. ${unit_of_measurement}`
  125. : html ``
  126. }</span>
  127. ${this.renderDayPrice(day, config)}
  128. </div>
  129. `
  130. }
  131.  
  132. renderDayPrice(value, config) {
  133. if (config.showPeakOffPeak === false && config.kWhPrice) {
  134. return html
  135. `
  136. <br><span class="cons-val">${this.toFloat(value * config.kWhPrice, 2)} €</span>
  137. `;
  138. }
  139. }
  140.  
  141. setConfig(config) {
  142. if (!config.entity) {
  143. throw new Error('You need to define an entity');
  144. }
  145.  
  146. if (config.kWhPrice && isNaN(config.kWhPrice)) {
  147. throw new Error('kWhPrice should be a number')
  148. }
  149.  
  150. const defaultConfig = {
  151. showHistory : true,
  152. showPeakOffPeak: true,
  153. showInTableUnit : false,
  154. kWhPrice: undefined,
  155. }
  156.  
  157. this.config = {
  158. ...defaultConfig,
  159. ...config
  160. };
  161. }
  162.  
  163. shouldUpdate(changedProps) {
  164. return hasConfigOrEntityChanged(this, changedProps);
  165. }
  166.  
  167. // @TODO: This requires more intelligent logic
  168. getCardSize() {
  169. return 3;
  170. }
  171.  
  172. toFloat(value, decimals = 1) {
  173. return Number.parseFloat(value).toFixed(decimals);
  174. }
  175.  
  176. previousMonth() {
  177. //return new Date((new Date().getTime()) - 365*60*60*24*1000)
  178. var d = new Date();
  179. d.setMonth(d.getMonth()-1) ;
  180. d.setFullYear(d.getFullYear()-1 );
  181.  
  182. return d.toLocaleDateString('fr-FR', {month: "long", year: "numeric"});
  183. }
  184.  
  185.  
  186. static get styles() {
  187. return css`
  188. .card {
  189. margin: auto;
  190. padding: 1.5em 1em 1em 1em;
  191. position: relative;
  192. }
  193.  
  194. .main-info {
  195. display: flex;
  196. justify-content: space-between;
  197. }
  198.  
  199. .ha-icon {
  200. margin-right: 5px;
  201. color: var(--paper-item-icon-color);
  202. }
  203.  
  204. .cout-block {
  205. }
  206.  
  207. .cout {
  208. font-weight: 300;
  209. font-size: 4em;
  210. }
  211.  
  212. .cout-unit {
  213. font-weight: 300;
  214. font-size: 1.5em;
  215. display: inline-block;
  216. vertical-align: 1.2em;
  217. }
  218.  
  219. .conso-hp, .conso-hc {
  220. font-weight: 200;
  221. font-size: 2em;
  222. margin-left: -5em;
  223. }
  224.  
  225. .conso-unit-hc, .conso-unit-hp {
  226. font-weight: 100;
  227. font-size: 1em;
  228. }
  229.  
  230. .more-unit {
  231. font-style: italic;
  232. font-size: 0.8em;
  233. }
  234.  
  235. .variations {
  236. display: flex;
  237. justify-content: space-between;
  238. }
  239.  
  240. .variations-linky {
  241. display: inline-block;
  242. font-weight: 300;
  243. margin: 1em;
  244. }
  245.  
  246. .unit {
  247. font-size: .8em;
  248. }
  249.  
  250. .week-history {
  251. display: flex;
  252. }
  253.  
  254. .day {
  255. flex: auto;
  256. text-align: center;
  257. border-right: .1em solid var(--divider-color);
  258. line-height: 2;
  259. box-sizing: border-box;
  260. }
  261.  
  262. .dayname {
  263. text-transform: uppercase;
  264. }
  265.  
  266. .week-history .day:last-child {
  267. border-right: none;
  268. }
  269.  
  270. .cons-val {
  271. font-weight: bold;
  272. }
  273.  
  274. .previous-month {
  275. font-size: 0.8em;
  276. font-style: italic;
  277. margin-left: 5px;
  278. }
  279.  
  280. .icon-block {
  281. }
  282.  
  283. .linky-icon.bigger {
  284. width: 6em;
  285. height: 5em;
  286. margin-top: -1em;
  287. margin-left: 1em;
  288. display: inline-block;
  289. }
  290. `;
  291. }
  292. }
  293.  
  294. customElements.define('linky-card1', LinkyCard1);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement