feat: pull two years worth of changes into release channel

Merge pull request #1059 from kalkih/dev
This commit is contained in:
akloeckner
2024-01-27 19:49:20 +01:00
committed by GitHub
19 changed files with 290 additions and 55 deletions

View File

@@ -5,6 +5,12 @@ lovelace:
type: module
default_config:
http: # support devcontainers/codespaces/gitpod
use_x_forwarded_for: true
trusted_proxies:
- 127.0.0.1
ip_ban_enabled: true
login_attempts_threshold: 5
demo:
@@ -38,3 +44,7 @@ sensor:
name: random_0_1000
minimum: 0
maximum: 1000
- platform: random
name: random_150_1000
minimum: 150
maximum: 1000

View File

@@ -31,5 +31,13 @@
"**/.hg/store/**": true,
"**/.rpt2_cache/**": true
}
}
},
"portsAttributes": {
"5000": {
"label": "rollup"
},
"8123": {
"label": "HA"
}
}
}

View File

@@ -3,19 +3,15 @@ views:
cards:
- type: custom:mini-graph-card
entities:
- sensor.humidity
- sensor.outside_humidity
- type: custom:mini-graph-card
entities:
- sensor.temperature
- type: custom:mini-graph-card
entities:
- sensor.pressure
- sensor.outside_temperature
show:
extrema: true
- type: custom:mini-graph-card
entities:
- entity: weather.home
attribute: pressure
- entity: sensor.outside_temperature
show:
extrema: true
- type: custom:mini-graph-card
@@ -48,17 +44,39 @@ views:
points: true
entities:
- entity: sensor.random_0_1000
name: log(0 - 1000) Gradients
name: log(150 - 1000) Gradients
aggregate_func: last
color_thresholds:
- value: 0
color: "#00ff00"
- value: 10
- value: 200
color: "#ffff00"
- value: 100
- value: 350
color: "#ff9900"
- value: 500
- value: 600
color: "#ff0000"
- type: custom:mini-graph-card
hours_to_show: 1
points_per_hour: 120
lower_bound: 0
upper_bound: 1000
# logarithmic: true
smoothing: false
height: 600
show:
extrema: true
# points: true
entities:
- entity: sensor.random_0_1000
name: log(150 - 1000) Simple
aggregate_func: last
color_thresholds:
- value: 0
color: green
- value: 200
color: red
- value: 1000
color: blue
- type: custom:mini-graph-card
entities:
- sensor.non_existant

View File

@@ -1,5 +1,4 @@
name: "Semantic PR"
description: Ensure your PR title matches the Conventional Commits spec (https://www.conventionalcommits.org/).
on:
pull_request_target:

View File

@@ -1,3 +1,41 @@
# [0.12.0-dev.4](https://github.com/kalkih/mini-graph-card/compare/v0.12.0-dev.3...v0.12.0-dev.4) (2023-08-10)
### Features
* Add support of attribute tree when available ([#996](https://github.com/kalkih/mini-graph-card/issues/996)) ([9c1c31e](https://github.com/kalkih/mini-graph-card/commit/9c1c31eaef3b81f45374441823a40b8f06196fc7))
# [0.12.0-dev.3](https://github.com/kalkih/mini-graph-card/compare/v0.12.0-dev.2...v0.12.0-dev.3) (2023-04-27)
### Bug Fixes
* retain the last out-of-bounds state ([#961](https://github.com/kalkih/mini-graph-card/issues/961)) ([8ebe173](https://github.com/kalkih/mini-graph-card/commit/8ebe173b8362e41b3287aaf04114d882aae78207)), closes [#881](https://github.com/kalkih/mini-graph-card/issues/881) [#960](https://github.com/kalkih/mini-graph-card/issues/960)
# [0.12.0-dev.2](https://github.com/kalkih/mini-graph-card/compare/v0.12.0-dev.1...v0.12.0-dev.2) (2023-04-22)
### Bug Fixes
* cards would always assume icon_image was set ([#957](https://github.com/kalkih/mini-graph-card/issues/957)) ([f376732](https://github.com/kalkih/mini-graph-card/commit/f376732f0a82251e3c66aa22500b377d1c7ef9b8))
# [0.12.0-dev.1](https://github.com/kalkih/mini-graph-card/compare/v0.11.0...v0.12.0-dev.1) (2023-04-22)
### Bug Fixes
* add first datapoint tooltip for line graph ([#882](https://github.com/kalkih/mini-graph-card/issues/882)) ([7576fe6](https://github.com/kalkih/mini-graph-card/commit/7576fe6460803546936c18fcadebf86a63c9ebfa))
* allow zero tooltip ([057a395](https://github.com/kalkih/mini-graph-card/commit/057a395ecbf8cfeb92ffa2805f1f8204778d7948)), closes [#805](https://github.com/kalkih/mini-graph-card/issues/805)
* drop out-of-bound coords in reducer ([#881](https://github.com/kalkih/mini-graph-card/issues/881)) ([527f005](https://github.com/kalkih/mini-graph-card/commit/527f005c902be8a9d572aabcb82993dfedd73572)), closes [#251](https://github.com/kalkih/mini-graph-card/issues/251)
* **documentation:** enquote html color ([dbdeab8](https://github.com/kalkih/mini-graph-card/commit/dbdeab86f987d74583fea37f57b0499bf474639f)), closes [#872](https://github.com/kalkih/mini-graph-card/issues/872)
* **stalebot:** issues should also use exemptLabels ([4d74c1f](https://github.com/kalkih/mini-graph-card/commit/4d74c1f103af7c830291c2c85a505adba9a9f4f9))
* **workflows:** remove invalid description field ([e755e24](https://github.com/kalkih/mini-graph-card/commit/e755e24efe37d53d8ba02852f2ba23ed8444f1da))
### Features
* **option:** override icon with an image URL ([#789](https://github.com/kalkih/mini-graph-card/issues/789)) ([2860a09](https://github.com/kalkih/mini-graph-card/commit/2860a094e782d8af3c80c46b56aa80e079b9755b))
# [0.11.0](https://github.com/kalkih/mini-graph-card/compare/v0.10.0...v0.11.0) (2022-01-22)

95
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,95 @@
# Guide for contributing to mini-graph-card
Welcome to `mini-graph-card` and thank you for contributing!
In this document, you will find information on
* [contributing](#contributing) to and
* [maintaining](#maintaining) the project.
# Contributing
## Issues
If you encounter any issues or have feature requests, please submit them via [GitHub Issues](https://github.com/kalkih/mini-graph-card/issues).
Before submitting a new issue, please check to see if a similar one has already been reported.
If you find an existing issue that describes the problem you're experiencing, please add a comment to the existing issue rather than creating a new one.
## HA Community Forum
Before posting on the HA community forum, please make sure to search the forum to see if your question or issue has already been addressed.
You can use [this link](https://community.home-assistant.io/search?q=mini-graph-card) to search for topics related to mini-graph-card.
If you don't find a relevant topic on the forum, feel free to create a new topic to discuss your question or issue.
Please provide as much detail as possible, including your configuration and any error messages you may be seeing, to help others understand and troubleshoot your issue.
## Important notes for pull requests
We are glad that you are planning to contribute to the project! :tada:
As the project maintainers are currently very limited in time, please discuss new features and enhancements via an issue first, to avoid getting your PR rejected after your hard work.
Refer to the [maintaining](#maintaining) section for more information and some general considerations on the types of changes that will likely be accepted at this time.
## Technical guidelines
The *base branch* for your contributions should be the `dev` branch to ensure compatibility with the latest code being validated.
*Documentation* should go to the `README.md`file.
Please make sure all features and options are documented correctly there.
If new options are added, mark them as `NEXT_VERSION` in the `since` column.
The release script will replace this with the correct version.
We follow *semantic versioning* conventions and enforce it using GitHub release actions.
This means, we require semantic commit messages, following the [angular conventional commit](https://www.conventionalcommits.org) style.
For PRs, this is ensured using a GitHub action.
The commit messages will also show up in the Release Notes, so take some time to get them right.
# Maintaining
## Current situation
Unfortunately, the project currently lacks maintainers with enough time at their hands to actively develop this project further.
Also, `mini-graph-card` is already very feature-rich and has grown quite a complex codebase.
Thus, we try to avoid introducing new features, especially if they add complexity to the code, or are in other ways prone to introducing new bugs.
We are, however, committed to making bug fixes available in a timely manner.
We will also invest in this project staying compatible with new releases of home assistant.
## Guide for merging PRs
*Bug fixes* are the priority.
They should either just fix the bug in very limited spots or, ideally, even reduce complexity.
When a bug fix is submitted, we should take some time to think about how things could be done in a better way.
PRs with only bug fixes may be merged by a single maintainer.
If major refactoring is involved, the following paragraphs might apply.
*Refactoring* code should be well justified, as it is prone to introduce side effects.
Good reasons could be reducing complexity or restoring compatibility with new releases of home assistant.
Refactoring code should be well tested before committing.
PRs including refactoring code should be approved at least by a maintainer and one other person.
Good candidates might be the authors of related issues or a second maintainer.
If you are not sure, don't hesitate to involve other maintainers.
Adding *new features* should in general be avoided, in order to maintain the stability of the codebase.
However, we may consider accepting new features if they have a minimal impact on the existing code and are not expected to cause any issues in the foreseeable future, particularly in terms of their interaction with existing features.
For instance, a new feature may be considered, if it can be implemented by improving a few lines of code or by using separate code that is clearly distinguished from the existing code.
Nonetheless, if there are third-party tools available that can solve a requested feature, we should generally choose to reject the feature request.
This is especially true for layout options, which can often be achieved using generic packages like `card-mod`.
PRs including new features should be approved in the same way as refactoring code.
## New releases
Releases are published using a GitHub action.
It must be triggered manually and it can be run on the `dev` branch for pre-releases or on the `master` branch for official releases.
We create frequent pre-releases (if there are changes) to ship improvements in a timely manner.

0
LICENSE Executable file → Normal file
View File

63
README.md Executable file → Normal file
View File

@@ -7,7 +7,7 @@ The card works with entities from within the **sensor** & **binary_sensor** doma
## Install
### HACS (recommended)
### HACS (recommended)
This card is available in [HACS](https://hacs.xyz/) (Home Assistant Community Store).
<small>*HACS is a third party community store and is not included in Home Assistant out of the box.*</small>
@@ -79,6 +79,7 @@ We recommend looking at the [Example usage section](#example-usage) to understan
| type ***(required)*** | string | | v0.0.1 | `custom:mini-graph-card`.
| entities ***(required)*** | list | | v0.2.0 | One or more sensor entities in a list, see [entities object](#entities-object) for additional entity options.
| icon | string | | v0.0.1 | Set a custom icon from any of the available mdi icons.
| icon_image | string | | NEXT_VERSION | Override icon with an image url
| name | string | | v0.0.1 | Set a custom name which is displayed beside the icon.
| unit | string | | v0.0.1 | Set a custom unit of measurement.
| tap_action | [action object](#action-object-options) | | v0.7.0 | Action on click/tap.
@@ -123,7 +124,7 @@ properties of the Entity object detailed in the following table (as per `sensor.
| Name | Type | Default | Description |
|------|:----:|:-------:|-------------|
| entity ***(required)*** | string | | Entity id of the sensor.
| attribute | string | | Retrieves an attribute instead of the state
| attribute | string | | Retrieves an attribute or [sub-attribute (attr1.attr2...)](#accessing-attributes-in-complex-structures) instead of the state
| name | string | | Set a custom display name, defaults to entity's friendly_name.
| color | string | | Set a custom color, overrides all other color options including thresholds.
| unit | string | | Set a custom unit of measurement, overrides `unit` set in base config.
@@ -202,6 +203,11 @@ color_thresholds:
- value: 4
color: "#0000ff"
```
The example above will result in the following colors of the graph: if value is
* between `0` (including this value) and `1.33333`, the color is `#ff0000`,
* between `1.33333` (including this value) and `2.666667`, the color is `#ffff00`,
* between `2.666667` (including this value) and `4`, the color is `#00ff00`,
* equal to or more than `4`, the color is `#0000ff`.
As a shorthand, you can just use a color string for the stops that you want interpolated:
@@ -442,7 +448,7 @@ entities:
- entity: sensor.outside_temp
aggregate_func: max
name: Max
color: #e74c3c
color: "#e74c3c"
- entity: sensor.outside_temp
aggregate_func: min
name: Min
@@ -518,6 +524,53 @@ show:
```
This method may be also used to add a calculated value with it's own `aggregate_func` option.
#### Accessing attributes in complex structures
When using the `attribute` option in the [entities object](#entities-object), you can access data in structured attributes, such as dictionaries and lists.
##### Accessing dictionary attributes
Suppose you have data stored inside a *dictionary* attribute named `dict_attribute`
```yaml
dict_attribute:
value_1: 53
value_2: 64
value_3: 72
```
Such data should be addressed as `dict_attribute.sub_attribute`:
```
type: custom:mini-graph-card
entities:
- entity: sensor.testing_object_data
attribute: dict_attribute.value_1
name: value_1 from dictionary attribute
```
![image](https://github.com/ildar170975/mini-graph-card/assets/71872483/0549afd5-901e-4e86-a144-edc4cd207440)
##### Accessing list attributes
Suppose you have data stored inside a *list* attribute named `list_attribute`:
```yaml
list_attribute:
- value_1: 67
value_2: 65
value_3: 93
- value_1: 134
value_2: 130
value_3: 186
- value_1: 201
value_2: 195
value_3: 279
```
Such data should be addressed as `list_attribute.index.sub_attribute`:
```
type: custom:mini-graph-card
entities:
- entity: sensor.testing_object_data_list
attribute: list_attribute.0.value_1
name: value_1 from first element of list attribute
```
![image](https://github.com/ildar170975/mini-graph-card/assets/71872483/eebd0cea-da93-4bf5-97a1-118edd2a9c5e)
## Development
@@ -562,7 +615,9 @@ $ npm run watch
*The new `mini-graph-card-bundle.js` will be build and ready inside `/dist`.*
**If you plan to submit a PR, please base it on the `dev` branch.**
Note that the `dev` branch is the most up-to-date and matches our beta releases.
Please refer to the [Contribution Guidelines](./CONTRIBUTING.md) if you're interested in contributing to the project. (And thanks for considering!)
## Getting errors?
Make sure you have `javascript_version: latest` in your `configuration.yaml` under `frontend:`.

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "mini-graph-card",
"version": "0.11.0",
"version": "0.12.0-dev.4",
"lockfileVersion": 2,
"requires": true,
"packages": {

2
package.json Executable file → Normal file
View File

@@ -1,6 +1,6 @@
{
"name": "mini-graph-card",
"version": "0.11.0",
"version": "0.12.0-dev.4",
"description": "A minimalistic and customizable graph card for Home Assistant Lovelace UI",
"keywords": [
"home-assistant",

0
rollup.config.js Executable file → Normal file
View File

0
src/buildConfig.js Executable file → Normal file
View File

0
src/const.js Executable file → Normal file
View File

63
src/graph.js Executable file → Normal file
View File

@@ -54,11 +54,6 @@ export default class Graph {
const histGroups = this._history.reduce((res, item) => this._reducer(res, item), []);
// drop potential out of bound entry's except one
if (histGroups[0] && histGroups[0].length) {
histGroups[0] = [histGroups[0][histGroups[0].length - 1]];
}
// extend length to fill missing history
const requiredNumOfPoints = Math.ceil(this.hours * this.points);
histGroups.length = requiredNumOfPoints;
@@ -71,29 +66,32 @@ export default class Graph {
_reducer(res, item) {
const age = this._endTime - new Date(item.last_changed).getTime();
const interval = (age / ONE_HOUR * this.points) - this.hours * this.points;
const key = interval < 0 ? Math.floor(Math.abs(interval)) : 0;
if (!res[key]) res[key] = [];
res[key].push(item);
if (interval < 0) {
const key = Math.floor(Math.abs(interval));
if (!res[key]) res[key] = [];
res[key].push(item);
} else {
res[0] = [item];
}
return res;
}
_calcPoints(history) {
const coords = [];
let xRatio = this.width / (this.hours * this.points - 1);
xRatio = Number.isFinite(xRatio) ? xRatio : this.width;
const first = history.filter(Boolean)[0];
let last = [this._calcPoint(first), this._lastValue(first)];
const getCoords = (item, i) => {
const x = xRatio * i + this.margin[X];
if (item)
last = [this._calcPoint(item), this._lastValue(item)];
return coords.push([x, 0, item ? last[0] : last[1]]);
};
for (let i = 0; i < history.length; i += 1)
getCoords(history[i], i);
const coords = [];
let last = history.filter(Boolean)[0];
let x;
for (let i = 0; i < history.length; i += 1) {
x = xRatio * i + this.margin[X];
if (history[i]) {
last = history[i];
coords.push([x, 0, this._calcPoint(last)]);
} else {
coords.push([x, 0, this._lastValue(last)]);
}
}
return coords;
}
@@ -118,17 +116,18 @@ export default class Graph {
coords[1] = [this.width + this.margin[X], 0, coords[0][V]];
}
coords = this._calcY(this.coords);
let next; let Z;
let last = coords[0];
coords.shift();
const coords2 = coords.map((point, i) => {
next = point;
Z = this._smoothing ? this._midPoint(last[X], last[Y], next[X], next[Y]) : next;
const sum = this._smoothing ? (next[V] + last[V]) / 2 : next[V];
last = next;
return [Z[X], Z[Y], sum, i + 1];
});
return coords2;
if (this._smoothing) {
let last = coords[0];
coords.shift();
return coords.map((point, i) => {
const Z = this._midPoint(last[X], last[Y], point[X], point[Y]);
const sum = (last[V] + point[V]) / 2;
last = point;
return [Z[X], Z[Y], sum, i + 1];
});
} else {
return coords.map((point, i) => [point[X], point[Y], point[V], i]);
}
}

0
src/handleClick.js Executable file → Normal file
View File

0
src/initialize.js Executable file → Normal file
View File

20
src/main.js Executable file → Normal file
View File

@@ -227,6 +227,14 @@ class MiniGraphCard extends LitElement {
}
renderIcon() {
if (this.config.icon_image !== undefined) {
return html`
<div class="icon">
<img src="${this.config.icon_image}" height="25"/>
</div>
`;
}
const { icon, icon_adaptive_color } = this.config.show;
return icon ? html`
<div class="icon" loc=${this.config.align_icon}
@@ -262,12 +270,16 @@ class MiniGraphCard extends LitElement {
`;
}
getObjectAttr(obj, path) {
return path.split('.').reduce((res, key) => res && res[key], obj);
}
getEntityState(id) {
const entityConfig = this.config.entities[id];
if (this.config.show.state === 'last') {
return this.points[id][this.points[id].length - 1][V];
} else if (entityConfig.attribute) {
return this.entity[id].attributes[entityConfig.attribute];
return this.getObjectAttr(this.entity[id].attributes, entityConfig.attribute);
} else {
return this.entity[id].state;
}
@@ -285,7 +297,7 @@ class MiniGraphCard extends LitElement {
style=${entityConfig.state_adaptive_color ? `color: ${this.computeColor(state, id)};` : ''}>
${entityConfig.show_indicator ? this.renderIndicator(state, id) : ''}
<span class="state__value ellipsis">
${this.computeState(isPrimary && tooltipValue || state)}
${this.computeState((isPrimary && tooltipValue !== undefined) ? tooltipValue : state)}
</span>
<span class="state__uom ellipsis">
${this.computeUom(isPrimary && entity || id)}
@@ -899,7 +911,7 @@ class MiniGraphCard extends LitElement {
newStateHistory[0].forEach((item) => {
if (this.config.entities[index].attribute) {
// eslint-disable-next-line no-param-reassign
item.state = item.attributes[this.config.entities[index].attribute];
item.state = this.getObjectAttr(item.attributes, this.config.entities[index].attribute);
// eslint-disable-next-line no-param-reassign
delete item.attributes;
}
@@ -950,7 +962,7 @@ class MiniGraphCard extends LitElement {
url += `?filter_entity_id=${entityId}`;
if (end) url += `&end_time=${end.toISOString()}`;
if (skipInitialState) url += '&skip_initial_state';
if (!withAttributes) url += '&minimal_response';
if (!withAttributes) url += '&minimal_response&no_attributes';
if (withAttributes) url += '&significant_changes_only=0';
return this._hass.callApi('GET', url);
}

1
src/style.js Executable file → Normal file
View File

@@ -315,6 +315,7 @@ const style = css`
.graph__labels.--secondary {
right: 0;
margin-right: 0px;
align-items: flex-end;
}
.graph__labels {
align-items: flex-start;

0
src/utils.js Executable file → Normal file
View File