Skip to content

Commit 2c324ca

Browse files
authored
Added universal expressions (short form functions): $ex (#232)
* Added short form functions: $f * documented $f and reused $fn * renamed $f to to $ex
1 parent 50001f9 commit 2c324ca

File tree

2 files changed

+42
-18
lines changed

2 files changed

+42
-18
lines changed

readme.md

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,8 @@ entities:
353353
width: 1
354354
dash: dot
355355
color: deepskyblue
356-
x: $fn () => [Date.now(), Date.now()]
357-
y: $fn () => [0,1]
356+
x: $ex [Date.now(), Date.now()]
357+
y: [0, 1]
358358
layout:
359359
yaxis9:
360360
visible: false
@@ -749,13 +749,29 @@ The returned value will be used as value for the property where it is found. E.g
749749
name: $fn ({ hass }) => hass.states["sensor.garden_temperature"].state
750750
```
751751

752+
or a universal expression `$ex` (the parameters and arrow are added automatically):
753+
754+
```js
755+
name: $ex hass.states["sensor.garden_temperature"].state
756+
```
757+
758+
which can also take a block:
759+
760+
```js
761+
name: |
762+
$ex {
763+
return hass.states["sensor.garden_temperature"].state
764+
}
765+
```
766+
752767
### Available parameters:
753768

754769
Remember you can add a `console.log(the_object_you_want_to_inspect)` and see its content in the devTools console.
755770

756771
#### Everywhere:
757772

758773
- `getFromConfig: (path) => value;` Pass a path (e.g `entities.0.name`) and get back its value
774+
- `get: (path) => value;` same as `getFromConfig`
759775
- `hass: HomeAssistant object;` For example: `hass.states["sensor.garden_temperature"].state` to get its current state
760776
- `vars: Record<string, any>;` You can communicate between functions with this. E.g `vars.temperatures = ys`
761777
- `path: string;` The path of the current function
@@ -784,8 +800,7 @@ type: custom:plotly-graph
784800
entities:
785801
- entity: sensor.garden_temperature
786802
name: |
787-
$fn ({ ys,meta }) =>
788-
meta.friendly_name + " " + ys[ys.length - 1]
803+
$ex meta.friendly_name + " " + ys[ys.length - 1]
789804
```
790805

791806
#### Sharing data across functions
@@ -796,10 +811,8 @@ entities:
796811
- entity: sensor.garden_temperature
797812
798813
# the fn attribute has no meaning, it is just a placeholder to put a function there. It can be any name not used by plotly
799-
fn: |
800-
$fn ({ ys, vars }) =>
801-
vars.title = ys[ys.length - 1]
802-
title: $fn ({ vars }) => vars.title
814+
fn: $ex vars.title = ys[ys.length - 1];
815+
title: $ex vars.title
803816
```
804817

805818
#### Histograms
@@ -808,7 +821,7 @@ title: $fn ({ vars }) => vars.title
808821
type: custom:plotly-graph
809822
entities:
810823
- entity: sensor.openweathermap_temperature
811-
x: $fn ({ys,vars}) => ys
824+
x: $ex ys
812825
type: histogram
813826
title: Temperature Histogram last 10 days
814827
hours_to_show: 10d
@@ -895,8 +908,8 @@ When true, the `x` and `y` properties of the traces won't be automatically fille
895908
type: custom:plotly-graph
896909
entities:
897910
- entity: sensor.temperature_in_celsius
898-
x: $fn ({xs}) => xs
899-
y: $fn ({ys}) => ys
911+
x: $ex xs
912+
y: $ex ys
900913
raw_plotly_config: true # defaults to false
901914
```
902915

src/parse-config/parse-config.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class ConfigParser {
6868
hass,
6969
css_vars,
7070
getFromConfig: () => "",
71+
get: () => "",
7172
};
7273
for (const [key, value] of Object.entries(this.yaml_with_defaults)) {
7374
try {
@@ -101,6 +102,7 @@ class ConfigParser {
101102
this.fnParam.path = path;
102103
this.fnParam.getFromConfig = (pathQuery: string) =>
103104
this.getEvaledPath(pathQuery, path /* caller */);
105+
this.fnParam.get = this.fnParam.getFromConfig;
104106

105107
if (
106108
!this.fnParam.xs && // hasn't fetched yet
@@ -114,8 +116,15 @@ class ConfigParser {
114116
await this.fetchDataForEntity(entityPath);
115117
}
116118

117-
if (typeof value === "string" && value.startsWith("$fn")) {
118-
value = myEval(value.slice(3));
119+
if (typeof value === "string") {
120+
if (typeof value === "string" && value.startsWith("$ex")) {
121+
value =
122+
"$fn ({ getFromConfig, get, hass, vars, path, css_vars, xs, ys, statistics, states, meta }) => " +
123+
value.slice(3);
124+
}
125+
if (value.startsWith("$fn")) {
126+
value = myEval(value.slice(3));
127+
}
119128
}
120129
const error = getDeprecationError(path, value);
121130
if (error) this.errors?.push(error);
@@ -366,7 +375,8 @@ function isObjectOrArray(value) {
366375
function is$fn(value) {
367376
return (
368377
typeof value === "function" ||
369-
(typeof value === "string" && value.startsWith("$fn"))
378+
(typeof value === "string" && value.startsWith("$fn")) ||
379+
(typeof value === "string" && value.startsWith("$ex"))
370380
);
371381
}
372382

@@ -387,11 +397,12 @@ function removeOutOfRange(data: EntityData, range: [number, number]) {
387397
data.statistics.splice(last);
388398
}
389399
}
390-
400+
type GetFromConfig = (
401+
string
402+
) => ReturnType<InstanceType<typeof ConfigParser>["getEvaledPath"]>;
391403
type FnParam = {
392-
getFromConfig: (
393-
string
394-
) => ReturnType<InstanceType<typeof ConfigParser>["getEvaledPath"]>;
404+
getFromConfig: GetFromConfig;
405+
get: GetFromConfig;
395406
hass: HomeAssistant;
396407
vars: Record<string, any>;
397408
path: string;

0 commit comments

Comments
 (0)