Skip to content

Commit

Permalink
Submodule for custom-cards-lovelace
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerben ten Hove committed Dec 2, 2018
1 parent 75f9d3d commit 5a249e2
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 1 deletion.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2018 Gerben ten Hove

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Custom-cards-lovelace
===
My custom cards for the [Lovelace UI](https://www.home-assistant.io/lovelace) of [Home Assistant](https://www.home-assistant.io/).

* [power-wheel-card](./power-wheel-card)

## License
All custom cards are licensed under the [Apache License 2.0](./LICENSE).
120 changes: 120 additions & 0 deletions power-wheel-card/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
power-wheel-card
====

## Features
Features of the custom power-wheel-card:
* Calculates the current power that your home is consuming: home power.
Input for the calculation is the (produced) solar power and the (consumed or produced) grid power.
* Displays the three power values (solar, grid and home) in 'a wheel'.
* Displays the transition between these powers as arrows.
E.g. if your solar power panels produce power, the arrow from solar to home turns active.
And if your solar power panels produce enough power to deliver some back to the grid, the arrow from solar to grid turns active.
* Works for default theme and custom themes that use [standard CSS vars](https://github.com/home-assistant/home-assistant-polymer/blob/master/src/resources/ha-style.js).

![example1](./example-card.gif "The power-wheel-card in Default theme")
![example2](./example-card-dark.gif "The power-wheel-card in a random dark theme")

## Requirements
1. You need to have a working sensor for your solar power. Write down the entity id of this sensor. This is *YOUR_SOLAR_POWER_SENSOR* in the instructions below.
- This sensor has a `unit_of_measurement` set up, e.g. `'W'` or `'kW'`.
- The sensor value should be of type *int* or *float*.
- The sensor value should be positive.
- The sensor could have an icon (optional) that will override the icon in the power-wheel-card.
1. You need to have a working sensor for your grid power. This is *YOUR_GRID_POWER_SENSOR* in the instructions below.
- This sensor has the `unit_of_measurement` set up as the sensor for solar power.
- The sensor value should be of type *int* or *float*.
- The sensor value should be **negative** for **producing** power to the grid and **positive** for **consuming** power of the grid.
- The sensor could have an icon (optional) that will override the icon in the power-wheel-card.

### Example requirements configuration
This is not the configuration of the power-wheel-card itself, but an example configuration that's needed to have input sensors for the power-wheel-card.
An example configuration in `configuration.yaml` to comply to the requirements:

```yaml
sensor:
- platform: template
sensors:
solar_power:
friendly_name: 'Solar power production'
unit_of_measurement: 'W'
value_template: '{{ states.sensor.youless.attributes.pwr }}'
grid_power:
friendly_name: 'Grid power consumption'
unit_of_measurement: 'W'
value_template: '{{ (1000 * (states.sensor.power_consumption.state | float - states.sensor.power_production.state | float)) | int }}'
```
In this example the sensors names for *YOUR_SOLAR_POWER_SENSOR* and *YOUR_GRID_POWER_SENSOR* are `solar_power` resp. `grid_power`.

Not visible in the example above, but of course you have to have installed the hardware and configured it to feed your sensors.
In the example above I used a [rest sensor](https://www.home-assistant.io/components/sensor.rest/) for my [Youless](http://youless.nl/winkel/product/ls120.html) for the solar power.
For the grid power I used a [dsmr sensor](https://www.home-assistant.io/components/sensor.dsmr/) for my Iskra Smart Meter.
Because the dsmr sensor supplies 2 separate sensors for grid power consumption and grid power production, you have to combine them to one grid power sensor.
Because my solar power sensor and dsmr sensor don't report in the same unit of measurement, I had to convert that as well.

## Instructions
1. Check the requirements above. If you don't comply to the requirements, the card won't be much of use for you or just won't work.
1. Download the file [power-wheel-card.js](https://raw.githubusercontent.com/gurbyz/custom-cards-lovelace/master/power-wheel-card/power-wheel-card.js).
1. Save the file in the `www` folder inside your Home Assistant config folder.
1. Include the card code in your `ui-lovelace.yaml` file:

```yaml
resources:
- url: /local/power-wheel-card.js?v=1
type: module
```

> Note: You can increase the number in `v=1` whenever updating code to avoid having to manually clear the cache of yours browsers/apps.

5. Include a configuration for the power-wheel-card in your `ui-lovelace.yaml` file:

```yaml
views:
- id: example_view
cards:
- type: "custom:power-wheel-card"
solar_power_entity: sensor.YOUR_SOLAR_POWER_SENSOR
grid_power_entity: sensor.YOUR_GRID_POWER_SENSOR
```

## Options

| Option | Type | Mandatory? | Default | Description |
|--------|------|------------|---------|-------------|
|type|string|**required**||Type of the card. Use `"custom:power-wheel-card"`.|
|solar_power_entity|string|**required**||Entity id of your solar power sensor. E.g. `sensor.YOUR_SOLAR_POWER_SENSOR`. See requirements above.|
|grid_power_entity|string|**required**||Entity id of your grid power sensor. E.g. `sensor.YOUR_GRID_POWER_SENSOR`. See requirements above.|
|title|string|optional|`"Power wheel"`|Title of the card.|
|home_power_icon|string|optional|`"mdi:home"`|Icon for home power.|

### More icons
The icons for solar power and grid power are taken from your own sensors for solar power and grid power.
If you haven't set up icons default icons will be used. For solar power: `mdi:weather-sunny`; and for grid power: `mdi:flash-circle`.

An example for overriding the other two icons, to be put in `configuration.yaml`:

```yaml
homeassistant:
[...]
customize:
sensor.solar_power:
icon: mdi:white-balance-sunny
sensor.grid_power:
icon: mdi:flash-circle
```

## Advanced configuration example
A more advanced example for in the `ui-lovelace.yaml` file:
```yaml
- type: "custom:power-wheel-card"
title: "Power distribution"
solar_power_entity: sensor.YOUR_SOLAR_POWER_SENSOR
grid_power_entity: sensor.YOUR_GRID_POWER_SENSOR
home_power_icon: "mdi:home-assistant"
```

## License
This custom card is licensed under the [Apache License 2.0](https://github.com/gurbyz/custom-cards-lovelace/blob/master/LICENSE).

## Credits
* [gurbyz](https://github.com/gurbyz)
Binary file added power-wheel-card/example-card-dark.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added power-wheel-card/example-card.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
132 changes: 132 additions & 0 deletions power-wheel-card/power-wheel-card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import {
LitElement, html
} from 'https://unpkg.com/@polymer/lit-element@^0.5.2/lit-element.js?module';

class PowerWheelCard extends LitElement {
static get properties() {
return {
hass: Object,
config: Object,
}
}

_render({ hass, config }) {
const title = config.title ? config.title : 'Power wheel';

const solarPowerState = hass.states[config.solar_power_entity];
const solarPowerStateStr = solarPowerState ? solarPowerState.state : 'unavailable';
const solarPowerIcon = solarPowerState && solarPowerState.attributes.icon
? solarPowerState.attributes.icon : 'mdi:weather-sunny';

const gridPowerState = hass.states[config.grid_power_entity];
const gridPowerStateStr = gridPowerState ? gridPowerState.state : 'unavailable';
const gridPowerIcon = gridPowerState && gridPowerState.attributes.icon
? gridPowerState.attributes.icon : 'mdi:flash-circle';

const homePowerStateStr = solarPowerState && gridPowerState
? parseFloat(solarPowerState.state) + parseFloat(gridPowerState.state) : 'unavailable';
const homePowerIcon = config.home_power_icon ? config.home_power_icon : 'mdi:home';

const unitStr = solarPowerState && gridPowerState
&& solarPowerState.attributes.unit_of_measurement && gridPowerState.attributes.unit_of_measurement
&& solarPowerState.attributes.unit_of_measurement == gridPowerState.attributes.unit_of_measurement
? solarPowerState.attributes.unit_of_measurement : 'unknown unit';

const solar2gridClass = gridPowerState && parseFloat(gridPowerState.state) < 0 ? 'active' : 'inactive';
const solar2homeClass = solarPowerState && parseFloat(solarPowerState.state) > 0
&& gridPowerState && parseFloat(homePowerStateStr) != 0 ? 'active' : 'inactive';
const grid2homeClass = gridPowerState && parseFloat(gridPowerState.state) > 0
&& solarPowerState && parseFloat(homePowerStateStr) != 0 ? 'active' : 'inactive';

return html`
<style>
ha-card {
padding: 16px;
}
ha-card .header {
font-family: var(--paper-font-headline_-_font-family);
-webkit-font-smoothing: var(--paper-font-headline_-_-webkit-font-smoothing);
font-size: var(--paper-font-headline_-_font-size);
font-weight: var(--paper-font-headline_-_font-weight);
letter-spacing: var(--paper-font-headline_-_letter-spacing);
line-height: var(--paper-font-headline_-_line-height);
color: var(--primary-text-color);
padding: 4px 0 12px;
display: flex;
justify-content: space-between;
}
ha-card .row {
display: flex;
justify-content: center;
padding: 8px;
align-items: center;
height: 60px;
}
ha-card .cell {
text-align: center;
width: 150px;
}
ha-icon {
transition: color 0.3s ease-in-out, filter 0.3s ease-in-out;
color: var(--paper-item-icon-color, #44739e);
width: 48px;
height: 48px;
}
ha-icon.active {
color: var(--paper-item-icon-active-color, #fdd835);
}
ha-icon.inactive {
color: var(--state-icon-unavailable-color, #bdbdbd);
}
</style>
<ha-card>
<div class="header">
${title}
</div>
<div class="row">
<div class="cell">
<ha-icon icon="${solarPowerIcon}"></ha-icon>
<br/>${solarPowerStateStr} ${unitStr}
</div>
</div>
<div class="row">
<div class="cell">
<ha-icon class$="${solar2gridClass}" icon="mdi:arrow-bottom-left"></ha-icon>
</div>
<div class="cell">
<ha-icon class$="${solar2homeClass}" icon="mdi:arrow-bottom-right"></ha-icon>
</div>
</div>
<div class="row">
<div class="cell">
<ha-icon icon="${gridPowerIcon}"></ha-icon>
<br/>${gridPowerStateStr} ${unitStr}
</div>
<div class="cell">
<ha-icon class$="${grid2homeClass}" icon="mdi:arrow-right"></ha-icon>
</div>
<div class="cell">
<ha-icon icon="${homePowerIcon}"></ha-icon>
<br/>${homePowerStateStr} ${unitStr}
</div>
</div>
</ha-card>
`;
}

setConfig(config) {
if (!config.solar_power_entity) {
throw new Error('You need to define a solar_power_entity');
}
if (!config.grid_power_entity) {
throw new Error('You need to define a grid_power_entity');
}
this.config = config;
}

getCardSize() {
return 5;
}
}

customElements.define('power-wheel-card', PowerWheelCard);

0 comments on commit 5a249e2

Please sign in to comment.