ha-nunjucks 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -37
- package/dist/filters.js +21 -7
- package/dist/globals.js +12 -5
- package/dist/index.js +2 -0
- package/dist/utils/areas.js +12 -7
- package/dist/utils/devices.d.ts +1 -0
- package/dist/utils/devices.js +15 -0
- package/dist/utils/floors.d.ts +1 -0
- package/dist/utils/floors.js +34 -2
- package/dist/utils/json.d.ts +1 -0
- package/dist/utils/json.js +6 -0
- package/dist/utils/labels.d.ts +1 -0
- package/dist/utils/labels.js +3 -0
- package/dist/utils/state_translated.d.ts +1 -1
- package/dist/utils/state_translated.js +8 -1
- package/dist/utils/string_filters.d.ts +4 -0
- package/dist/utils/string_filters.js +27 -0
- package/dist/utils/time.d.ts +1 -0
- package/dist/utils/time.js +16 -12
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -168,15 +168,17 @@ Functions used to determine an entity's state or an attribute.
|
|
|
168
168
|
| device_attr | function, filter | device_or_entity_id, attr_name | Returns the value of attr_name for the given device or entity ID. |
|
|
169
169
|
| is_device_attr | function | device_or_entity_id, attr_name, attr_value | Returns whether the value of attr_name for the given device or entity ID matches attr_value. |
|
|
170
170
|
| device_id | function, filter | entity_id | Returns the device ID for a given entity ID or device name. |
|
|
171
|
+
| device_name | function, filter | device_or_entity_id | Returns the device name as defined by user or default for a give entity or device ID. |
|
|
171
172
|
|
|
172
173
|
### [Floors](https://www.home-assistant.io/docs/configuration/templating/#floors)
|
|
173
174
|
|
|
174
|
-
| Name
|
|
175
|
-
|
|
|
176
|
-
| floors
|
|
177
|
-
| floor_id
|
|
178
|
-
| floor_name
|
|
179
|
-
| floor_areas
|
|
175
|
+
| Name | Type | Arguments | Description |
|
|
176
|
+
| -------------- | ---------------- | ---------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
177
|
+
| floors | function | | Returns the full list of floor IDs that include an area. |
|
|
178
|
+
| floor_id | function, filter | lookup_value | Returns the floor ID for a given floor name or alias, device ID, entity ID, area ID, or area name or alias. |
|
|
179
|
+
| floor_name | function, filter | lookup_value | Returns the floor name for a given device ID, entity ID, area ID, area name, or floor ID. |
|
|
180
|
+
| floor_areas | function, filter | floor_name_or_id | Returns the list of area IDs tied to a given floor ID or name. |
|
|
181
|
+
| floor_entities | function, filter | floor_name_or_id | Returns the list of entity IDs tied to a given floor ID or name. |
|
|
180
182
|
|
|
181
183
|
### [Areas](https://www.home-assistant.io/docs/configuration/templating/#areas)
|
|
182
184
|
|
|
@@ -198,14 +200,15 @@ Functions used to determine an entity's state or an attribute.
|
|
|
198
200
|
|
|
199
201
|
**NOTE**: Labels are not available in the `hass` object and must be retrieved asynchronously from the Home Assistant backend the first time `ha-nunjucks` is imported. Since this package is otherwise synchronous, this can cause a race condition where no labels are found the first time `renderTemplate` is run. This generally resolves itself once the template re-renders.
|
|
200
202
|
|
|
201
|
-
| Name
|
|
202
|
-
|
|
|
203
|
-
| labels
|
|
204
|
-
| label_id
|
|
205
|
-
| label_name
|
|
206
|
-
|
|
|
207
|
-
|
|
|
208
|
-
|
|
|
203
|
+
| Name | Type | Arguments | Description |
|
|
204
|
+
| ----------------- | ---------------- | ----------------------- | ------------------------------------------------------------------------------------------ |
|
|
205
|
+
| labels | function, filter | lookup_value (optional) | Returns the full list of label IDs, or those for a given area ID, device ID, or entity ID. |
|
|
206
|
+
| label_id | function, filter | lookup_value | Returns the label ID for a given label name. |
|
|
207
|
+
| label_name | function, filter | lookup_value | Returns the label name for a given label ID. |
|
|
208
|
+
| label_description | function, filter | lookup_value | Returns the label description for a given label ID. |
|
|
209
|
+
| label_areas | function, filter | label_name_or_id | Returns the list of area IDs tied to a given label ID or name. |
|
|
210
|
+
| label_devices | function, filter | label_name_or_id | Returns the list of device IDs tied to a given label ID or name. |
|
|
211
|
+
| label_entities | function, filter | label_name_or_id | Returns the list of entity IDs tied to a given label ID or name. |
|
|
209
212
|
|
|
210
213
|
### [Immediate If](https://www.home-assistant.io/docs/configuration/templating/#immediate-if-iif)
|
|
211
214
|
|
|
@@ -223,21 +226,22 @@ A shorthand for an if else statement.
|
|
|
223
226
|
- JS Date is not as good at handling timezones as Python datetime. Be careful about timezone differences! You can try to account for this using the `utc` flags and/or by including a timezone offset in a datetime string to parse using `as_datetime` or `strptime`.
|
|
224
227
|
- Including time extensions in your templates does not cause them to refresh more regularly by themselves, although they will still update whenever the `hass` object does. If you are a developer, you have to implement this behavior yourself in your custom cards.
|
|
225
228
|
|
|
226
|
-
| Name | Type | Arguments | Description
|
|
227
|
-
| ---------------- | ---------------- | -------------------------------------------------------- |
|
|
228
|
-
| now | function | | Returns a datetime object that represents the current time in your time zone.
|
|
229
|
-
| utcnow | function | | Returns a datetime object of the current time in the UTC timezone.
|
|
230
|
-
| today_at | function, filter | value | Converts a string containing a military time format to a datetime object with today’s date in your time zone. Defaults to midnight (00:00).
|
|
231
|
-
| as_datetime | function, filter | value, fallback (optional), utc (default true) | Converts a string containing a timestamp, or valid UNIX timestamp, to a datetime object. If that fails, it returns the fallback value or, if omitted, raises an error. When the input is already a datetime object it will be returned as is. in case the input is a datetime.date object, midnight will be added as time.
|
|
232
|
-
| as_timestamp | function, filter | value, fallback (optional) | Converts a datetime object or string to UNIX timestamp. If that fails, returns the fallback value, or if omitted raises an error.
|
|
233
|
-
| as_local | function, filter | value | Converts a datetime object to local time.
|
|
234
|
-
| strptime | function | value, format, fallback (optional), utc (default false) | Parses a string based on a [format](https://d3js.org/d3-time-format#locale_format) and returns a datetime object. If that fails, it returns the default value or, if omitted, raises an error.
|
|
235
|
-
|
|
|
236
|
-
|
|
|
237
|
-
|
|
|
238
|
-
|
|
|
239
|
-
|
|
|
240
|
-
|
|
|
229
|
+
| Name | Type | Arguments | Description |
|
|
230
|
+
| ---------------- | ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
231
|
+
| now | function | | Returns a datetime object that represents the current time in your time zone. |
|
|
232
|
+
| utcnow | function | | Returns a datetime object of the current time in the UTC timezone. |
|
|
233
|
+
| today_at | function, filter | value | Converts a string containing a military time format to a datetime object with today’s date in your time zone. Defaults to midnight (00:00). |
|
|
234
|
+
| as_datetime | function, filter | value, fallback (optional), utc (default true) | Converts a string containing a timestamp, or valid UNIX timestamp, to a datetime object. If that fails, it returns the fallback value or, if omitted, raises an error. When the input is already a datetime object it will be returned as is. in case the input is a datetime.date object, midnight will be added as time. |
|
|
235
|
+
| as_timestamp | function, filter | value, fallback (optional) | Converts a datetime object or string to UNIX timestamp. If that fails, returns the fallback value, or if omitted raises an error. |
|
|
236
|
+
| as_local | function, filter | value | Converts a datetime object to local time. |
|
|
237
|
+
| strptime | function | value, format, fallback (optional), utc (default false) | Parses a string based on a [format](https://d3js.org/d3-time-format#locale_format) and returns a datetime object. If that fails, it returns the default value or, if omitted, raises an error. |
|
|
238
|
+
| relative_time | function, filter | value | Returns a human readable string indicating the differenceb between now and an input past datetime object. Only uses the largest unit (years, months, days, hours, minutes, seconds) rounded. |
|
|
239
|
+
| time_since | function, filter | value, precision (default 1) | Returns a human readable string indicating the difference between now and an input past datetime object. `precision` indicates how many units (years, months, days, hours, minutes, seconds) to use, with the last unit being rounded and 0 being the same as 6. If the input datetime is in the future it returns the input. If the input datetime is not a datetime object it returns nothing. |
|
|
240
|
+
| time_until | function, filter | value, precision (default 1) | Returns a human readable string indicating the difference between now and an input future datetime object. `precision` indicates how many units (years, months, days, hours, minutes, seconds) to use, with the last unit being rounded and 0 being the same as 6. If the input datetime is in the past it returns the input. If the input datetime is not a datetime object it returns nothing. |
|
|
241
|
+
| as_timedelta | function, filter | value | Converts a string to a timedelta object. Expects data in the format `DD HH:MM:SS.uuuuuu`, `DD HH:MM:SS,uuuuuu`, or as specified by ISO 8601 (e.g. `P4DT1H15M20S` which is equivalent to `4 1:15:20`) or PostgreSQL’s day-time interval format (e.g. `3 days 04:05:06`). |
|
|
242
|
+
| timestamp_local | filter | value, fallback (optional) | Converts a UNIX timestamp to the ISO format string representation as date/time in your local timezone. If that fails, returns the `fallback` value, or if omitted raises an error. |
|
|
243
|
+
| timestamp_utc | filter | value, fallback (optional) | Converts a UNIX timestamp to the ISO format string representation as date/time in UTC timezone. If that fails, returns the `fallback` value, or if omitted raises an error. |
|
|
244
|
+
| timestamp_custom | filter | value, format, local (default true), fallback (optional) | Converts a UNIX timestamp to its string representation based on a custom format. Uses the local timezone by default. If that fails, returns the `fallback` value, or if omitted raises an error. |
|
|
241
245
|
|
|
242
246
|
In addition to these functions, you have access to [a datetime library](https://github.com/Nerwyn/ts-py-datetime) which emulates the Python datetime module in TypeScript. You can instantiate `date`, `time`, `datetime`, and `timedelta` objects using the `dt` object. You can then access it's class methods using these objects. To use the static method and constants of these classes, you can reference them directly without prefixing them with `dt`. See the README in the datetime repository linked above for more information on how to use it.
|
|
243
247
|
|
|
@@ -260,6 +264,12 @@ In addition to these functions, you have access to [a datetime library](https://
|
|
|
260
264
|
| to_json | filter | obj, ensure_ascii, pretty_print, sort_keys | Turn an object into a JSON string. `ensure_ascii` converts unicode characters into escape sequences. `pretty_print` formats the output with new lines and an indent of two spaces. `sort_keys` sorts the keys of the JSON object. **Consider using the nunjucks `safe` filter with this, or the nunjucks `dump` filter instead.** |
|
|
261
265
|
| from_json | filter | value | Parse a string as JSON. |
|
|
262
266
|
|
|
267
|
+
### [Is Defined](https://www.home-assistant.io/docs/configuration/templating/#is-defined)
|
|
268
|
+
|
|
269
|
+
| Name | Type | Arguments | Description |
|
|
270
|
+
| ---------- | ------ | --------- | -------------------------------------------------------------- |
|
|
271
|
+
| is_defined | filter | value | Returns the value if it is defined, otherwise throws an error. |
|
|
272
|
+
|
|
263
273
|
### [Distance](https://www.home-assistant.io/docs/configuration/templating/#distance)
|
|
264
274
|
|
|
265
275
|
| Name | Type | Arguments | Description |
|
|
@@ -319,10 +329,11 @@ In addition to these functions, you have access to [a datetime library](https://
|
|
|
319
329
|
|
|
320
330
|
### [Type Conversions](https://www.home-assistant.io/docs/configuration/templating/#type-conversions)
|
|
321
331
|
|
|
322
|
-
| Name | Type
|
|
323
|
-
| ---- |
|
|
324
|
-
| set | function
|
|
325
|
-
| list | function
|
|
332
|
+
| Name | Type | Arguments | Description |
|
|
333
|
+
| ---- | ---------------- | --------- | ------------------------------------------------------ |
|
|
334
|
+
| set | function | args | Convert a list/array to a set. Removes duplicates. |
|
|
335
|
+
| list | function | args | Convert a set to an array. Does not remove duplicates. |
|
|
336
|
+
| str | function, filter | value | Return the string representation of the input. |
|
|
326
337
|
|
|
327
338
|
### [Iterating Multiple Objects](https://www.home-assistant.io/docs/configuration/templating/#iterating-multiple-objects)
|
|
328
339
|
|
|
@@ -330,6 +341,16 @@ In addition to these functions, you have access to [a datetime library](https://
|
|
|
330
341
|
| ---- | -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
331
342
|
| zip | function | args | Use to iterate over multiple collections in one operation. If given one array will perform the opposite action and unzip the list. |
|
|
332
343
|
|
|
344
|
+
### [String filters](https://www.home-assistant.io/docs/configuration/templating/#string-filters)
|
|
345
|
+
|
|
346
|
+
| Name | Type | Arguments | Description |
|
|
347
|
+
| ------------- | ------ | ----------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
348
|
+
| urlencode | filter | value | Convert an object to a percent-encoded ASCII text string. |
|
|
349
|
+
| slugify | filter | value, separator (default \_) | Convert a given string into a "slug". |
|
|
350
|
+
| ordinal | filter | value | Convert an integer into a number defining a position in a series (e.g. `1st`, `2nd`, `3rd`, `4th`, etc). |
|
|
351
|
+
| base64_encode | filter | value | Encodes a string or bytes to a base 64 string. |
|
|
352
|
+
| base64_decode | filter | value | Decodes a base 64 string to a UTF-8 string. |
|
|
353
|
+
|
|
333
354
|
### [Regular Expressions](https://www.home-assistant.io/docs/configuration/templating/#regular-expressions)
|
|
334
355
|
|
|
335
356
|
**NOTE**: The format of regular expressions in nunjucks is different than jinja2. You may want to read the [Nunjucks](https://mozilla.github.io/nunjucks/templating.html#regular-expressions) and [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions) documentation.
|
|
@@ -347,10 +368,9 @@ In addition to these functions, you have access to [a datetime library](https://
|
|
|
347
368
|
|
|
348
369
|
Functions that are not from the Home Assistant templating documentation.
|
|
349
370
|
|
|
350
|
-
| Name | Type
|
|
351
|
-
| ----------- |
|
|
352
|
-
| match_media | function
|
|
353
|
-
| str | function, filter | value | Return the string representation of the input. |
|
|
371
|
+
| Name | Type | Arguments | Description |
|
|
372
|
+
| ----------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
373
|
+
| match_media | function | value | Returns the boolean result of the provided [CSS media query](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries). |
|
|
354
374
|
|
|
355
375
|
[last-commit-shield]: https://img.shields.io/github/last-commit/Nerwyn/ha-nunjucks?style=for-the-badge
|
|
356
376
|
[commits]: https://github.com/Nerwyn/ha-nunjucks/commits/main
|
package/dist/filters.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { area_devices, area_entities, area_id, area_name } from './utils/areas';
|
|
2
2
|
import { contains } from './utils/contains';
|
|
3
|
-
import { device_attr, device_entities, device_id } from './utils/devices';
|
|
3
|
+
import { device_attr, device_entities, device_id, device_name, } from './utils/devices';
|
|
4
4
|
import { closest } from './utils/distance';
|
|
5
|
-
import { floor_areas, floor_id, floor_name } from './utils/floors';
|
|
5
|
+
import { floor_areas, floor_entities, floor_id, floor_name, } from './utils/floors';
|
|
6
6
|
import { expand } from './utils/groups';
|
|
7
7
|
import { iif } from './utils/iif';
|
|
8
|
-
import { from_json, to_json } from './utils/json';
|
|
9
|
-
import { label_areas, label_devices, label_entities, label_id, label_name, labels, } from './utils/labels';
|
|
8
|
+
import { from_json, is_defined, to_json } from './utils/json';
|
|
9
|
+
import { label_areas, label_description, label_devices, label_entities, label_id, label_name, labels, } from './utils/labels';
|
|
10
10
|
import { str } from './utils/miscellaneous';
|
|
11
11
|
import { acos, add, asin, atan, atan2, average, bitwise_and, bitwise_not, bitwise_or, bitwise_xor, bool, cos, is_number, log, max, median, min, multiply, ord, sin, sqrt, statistical_mode, tan, } from './utils/numeric';
|
|
12
12
|
import { regex_findall, regex_findall_index, regex_replace, } from './utils/regexp';
|
|
13
13
|
import { attr_name_translated, attr_value_translated, date_translated, datetime_translated, number_translated, state_translated, time_translated, } from './utils/state_translated';
|
|
14
14
|
import { has_value, state_attr, states } from './utils/states';
|
|
15
|
-
import {
|
|
15
|
+
import { base64_decode, base64_encode, ordinal, slugify, } from './utils/string_filters';
|
|
16
|
+
import { as_datetime, as_local, as_timedelta, as_timestamp, relative_time, time_since, time_until, timestamp_custom, timestamp_local, timestamp_utc, today_at, } from './utils/time';
|
|
16
17
|
export function addFilters(env) {
|
|
17
18
|
for (const func in FILTERS) {
|
|
18
19
|
env.addFilter(func, function (...args) {
|
|
@@ -41,10 +42,12 @@ const HASS_FILTERS = {
|
|
|
41
42
|
device_entities,
|
|
42
43
|
device_attr,
|
|
43
44
|
device_id,
|
|
45
|
+
device_name,
|
|
44
46
|
// Floors
|
|
45
47
|
floor_id,
|
|
46
48
|
floor_name,
|
|
47
49
|
floor_areas,
|
|
50
|
+
floor_entities,
|
|
48
51
|
// Areas
|
|
49
52
|
area_id,
|
|
50
53
|
area_name,
|
|
@@ -64,11 +67,14 @@ const FILTERS = {
|
|
|
64
67
|
// Labels
|
|
65
68
|
label_id,
|
|
66
69
|
label_name,
|
|
70
|
+
label_description,
|
|
67
71
|
// Time
|
|
68
72
|
today_at,
|
|
73
|
+
as_timedelta,
|
|
69
74
|
as_datetime,
|
|
70
75
|
as_timestamp,
|
|
71
76
|
as_local,
|
|
77
|
+
relative_time,
|
|
72
78
|
time_since,
|
|
73
79
|
time_until,
|
|
74
80
|
timestamp_local,
|
|
@@ -80,6 +86,8 @@ const FILTERS = {
|
|
|
80
86
|
// To/From JSON
|
|
81
87
|
to_json,
|
|
82
88
|
from_json,
|
|
89
|
+
// Is Defined
|
|
90
|
+
is_defined,
|
|
83
91
|
// Distance
|
|
84
92
|
closest,
|
|
85
93
|
// Contains
|
|
@@ -111,10 +119,16 @@ const FILTERS = {
|
|
|
111
119
|
multiply,
|
|
112
120
|
add,
|
|
113
121
|
number_translated,
|
|
122
|
+
// Type conversions
|
|
123
|
+
str,
|
|
124
|
+
// String filters
|
|
125
|
+
// urlencode filter is built into nunjucks
|
|
126
|
+
slugify,
|
|
127
|
+
ordinal,
|
|
128
|
+
base64_encode,
|
|
129
|
+
base64_decode,
|
|
114
130
|
// Regular Expressions
|
|
115
131
|
regex_replace,
|
|
116
132
|
regex_findall,
|
|
117
133
|
regex_findall_index,
|
|
118
|
-
// Miscellaneous
|
|
119
|
-
str,
|
|
120
134
|
};
|
package/dist/globals.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { area_devices, area_entities, area_id, area_name, areas, } from './utils/areas';
|
|
2
|
-
import { device_attr, device_entities, device_id, is_device_attr, } from './utils/devices';
|
|
2
|
+
import { device_attr, device_entities, device_id, device_name, is_device_attr, } from './utils/devices';
|
|
3
3
|
import { closest, distance } from './utils/distance';
|
|
4
4
|
import { is_hidden_entity } from './utils/entities';
|
|
5
|
-
import { floor_areas, floor_id, floor_name, floors } from './utils/floors';
|
|
5
|
+
import { floor_areas, floor_entities, floor_id, floor_name, floors, } from './utils/floors';
|
|
6
6
|
import { expand } from './utils/groups';
|
|
7
7
|
import { iif } from './utils/iif';
|
|
8
8
|
import { integration_entities } from './utils/integrations';
|
|
9
|
-
import { label_areas, label_devices, label_entities, label_id, label_name, labels, } from './utils/labels';
|
|
9
|
+
import { label_areas, label_description, label_devices, label_entities, label_id, label_name, labels, } from './utils/labels';
|
|
10
10
|
import { match_media, str } from './utils/miscellaneous';
|
|
11
11
|
import { acos, asin, atan, atan2, average, bool, cos, e, float, inf, int, is_number, log, max, median, min, pi, sin, sqrt, statistical_mode, tan, tau, } from './utils/numeric';
|
|
12
12
|
import { attr_name_translated, attr_value_translated, date_translated, datetime_translated, number_translated, state_translated, time_translated, } from './utils/state_translated';
|
|
13
13
|
import { has_value, is_state, is_state_attr, state_attr, states, } from './utils/states';
|
|
14
|
-
import {
|
|
14
|
+
import { slugify } from './utils/string_filters';
|
|
15
|
+
import { as_datetime, as_local, as_timedelta, as_timestamp, now, relative_time, strptime, time_since, time_until, today_at, utcnow, } from './utils/time';
|
|
15
16
|
import { list, set } from './utils/type_conversions';
|
|
16
17
|
import { zip } from './utils/zip';
|
|
17
18
|
import dt, { date, datetime, time, timedelta } from 'ts-py-datetime';
|
|
@@ -56,11 +57,13 @@ const HASS_GLOBALS = {
|
|
|
56
57
|
device_attr,
|
|
57
58
|
is_device_attr,
|
|
58
59
|
device_id,
|
|
60
|
+
device_name,
|
|
59
61
|
// Floors
|
|
60
62
|
floors,
|
|
61
63
|
floor_id,
|
|
62
64
|
floor_name,
|
|
63
65
|
floor_areas,
|
|
66
|
+
floor_entities,
|
|
64
67
|
// Areas
|
|
65
68
|
areas,
|
|
66
69
|
area_id,
|
|
@@ -84,6 +87,7 @@ const GLOBALS = {
|
|
|
84
87
|
// Labels
|
|
85
88
|
label_id,
|
|
86
89
|
label_name,
|
|
90
|
+
label_description,
|
|
87
91
|
// Time
|
|
88
92
|
now,
|
|
89
93
|
utcnow,
|
|
@@ -92,6 +96,7 @@ const GLOBALS = {
|
|
|
92
96
|
as_timestamp,
|
|
93
97
|
as_local,
|
|
94
98
|
strptime,
|
|
99
|
+
relative_time,
|
|
95
100
|
time_since,
|
|
96
101
|
time_until,
|
|
97
102
|
as_timedelta,
|
|
@@ -121,11 +126,13 @@ const GLOBALS = {
|
|
|
121
126
|
// Type Conversions
|
|
122
127
|
set,
|
|
123
128
|
list,
|
|
129
|
+
str,
|
|
124
130
|
// Iterating Multiple Objects
|
|
125
131
|
zip,
|
|
132
|
+
// String fitlers
|
|
133
|
+
slugify,
|
|
126
134
|
// Miscellaneous
|
|
127
135
|
match_media,
|
|
128
|
-
str,
|
|
129
136
|
};
|
|
130
137
|
const CONST_GLOBALS = {
|
|
131
138
|
e,
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,8 @@ if (!window.haNunjucks) {
|
|
|
25
25
|
window.haNunjucks.dateFormat = new Intl.DateTimeFormat(ha.hass.language, { dateStyle: 'full' });
|
|
26
26
|
window.haNunjucks.timeFormat = new Intl.DateTimeFormat(ha.hass.language, { timeStyle: 'long' });
|
|
27
27
|
window.haNunjucks.datetimeFormat = new Intl.DateTimeFormat(ha.hass.language, { dateStyle: 'full', timeStyle: 'long' });
|
|
28
|
+
window.haNunjucks.ordinalFormat = new Intl.PluralRules('en-US', // ha.hass.language, // Use english for proper numeric suffixes
|
|
29
|
+
{ type: 'ordinal' });
|
|
28
30
|
// Label registry and states object
|
|
29
31
|
window.haNunjucks.hass = ha.hass;
|
|
30
32
|
fetchLabelRegistry();
|
package/dist/utils/areas.js
CHANGED
|
@@ -20,7 +20,8 @@ export function area_id(hass, lookup_value) {
|
|
|
20
20
|
return hass.devices[lookup_value].area_id;
|
|
21
21
|
}
|
|
22
22
|
for (const areaId in hass.areas) {
|
|
23
|
-
if (hass.areas[areaId].name == lookup_value
|
|
23
|
+
if (hass.areas[areaId].name == lookup_value ||
|
|
24
|
+
hass.areas[areaId].aliases?.includes(lookup_value)) {
|
|
24
25
|
return areaId;
|
|
25
26
|
}
|
|
26
27
|
}
|
|
@@ -57,12 +58,15 @@ export function area_entities(hass, area_name_or_id) {
|
|
|
57
58
|
try {
|
|
58
59
|
const entityIds = [];
|
|
59
60
|
if (area_name_or_id) {
|
|
61
|
+
let areaId = area_name_or_id;
|
|
62
|
+
if (!hass.areas[area_name_or_id]) {
|
|
63
|
+
areaId = area_id(hass, area_name_or_id) ?? area_name_or_id;
|
|
64
|
+
}
|
|
60
65
|
const deviceIds = area_devices(hass, area_name_or_id);
|
|
61
|
-
for (const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
+
for (const entityId in hass.entities) {
|
|
67
|
+
if (deviceIds.includes(hass.entities[entityId].device_id) ||
|
|
68
|
+
hass.entities[entityId].area_id == areaId) {
|
|
69
|
+
entityIds.push(entityId);
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
entityIds.sort();
|
|
@@ -79,7 +83,8 @@ export function area_devices(hass, area_name_or_id) {
|
|
|
79
83
|
if (area_name_or_id) {
|
|
80
84
|
if (!(area_name_or_id in hass.areas)) {
|
|
81
85
|
for (const areaId in hass.areas) {
|
|
82
|
-
if (hass.areas[areaId].name == area_name_or_id
|
|
86
|
+
if (hass.areas[areaId].name == area_name_or_id ||
|
|
87
|
+
hass.areas[areaId].aliases?.includes(area_name_or_id)) {
|
|
83
88
|
area_name_or_id = areaId;
|
|
84
89
|
break;
|
|
85
90
|
}
|
package/dist/utils/devices.d.ts
CHANGED
|
@@ -4,3 +4,4 @@ export declare function device_entities(hass: HomeAssistant, device_id: string):
|
|
|
4
4
|
export declare function device_attr(hass: HomeAssistant, device_or_entity_id: string, attr_name: keyof DeviceRegistryEntry): any;
|
|
5
5
|
export declare function is_device_attr(hass: HomeAssistant, device_or_entity_id: string, attr_name: keyof DeviceRegistryEntry, attr_value: string): boolean;
|
|
6
6
|
export declare function device_id(hass: HomeAssistant, entity_id: string): string | undefined;
|
|
7
|
+
export declare function device_name(hass: HomeAssistant, lookup_value: string): string | null | undefined;
|
package/dist/utils/devices.js
CHANGED
|
@@ -55,3 +55,18 @@ export function device_id(hass, entity_id) {
|
|
|
55
55
|
return undefined;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
export function device_name(hass, lookup_value) {
|
|
59
|
+
try {
|
|
60
|
+
if (hass.entities[lookup_value]) {
|
|
61
|
+
lookup_value = hass.entities[lookup_value].device_id;
|
|
62
|
+
}
|
|
63
|
+
const device = hass.devices[lookup_value];
|
|
64
|
+
if (device) {
|
|
65
|
+
return device.name_by_user ?? device.name;
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
package/dist/utils/floors.d.ts
CHANGED
|
@@ -3,3 +3,4 @@ export declare function floors(hass: HomeAssistant): string[];
|
|
|
3
3
|
export declare function floor_id(hass: HomeAssistant, lookup_value: string): string | null | undefined;
|
|
4
4
|
export declare function floor_name(hass: HomeAssistant, lookup_value: string): string | undefined;
|
|
5
5
|
export declare function floor_areas(hass: HomeAssistant, floor_name_or_id: string): string[];
|
|
6
|
+
export declare function floor_entities(hass: HomeAssistant, floor_name_or_id: string): string[];
|
package/dist/utils/floors.js
CHANGED
|
@@ -4,25 +4,37 @@ export function floors(hass) {
|
|
|
4
4
|
export function floor_id(hass, lookup_value) {
|
|
5
5
|
try {
|
|
6
6
|
let areaId = lookup_value;
|
|
7
|
+
// Entity ID
|
|
7
8
|
if (hass.entities[lookup_value]) {
|
|
8
9
|
areaId = hass.entities[lookup_value].area_id ?? areaId;
|
|
9
10
|
lookup_value =
|
|
10
11
|
hass.entities[lookup_value].device_id ?? lookup_value;
|
|
11
12
|
}
|
|
12
13
|
if (lookup_value) {
|
|
14
|
+
// Device ID
|
|
13
15
|
if (hass.devices[lookup_value]) {
|
|
14
16
|
areaId = hass.devices[lookup_value].area_id ?? areaId;
|
|
15
17
|
}
|
|
18
|
+
// Area ID
|
|
16
19
|
if (hass.areas[areaId]) {
|
|
17
20
|
return hass.areas[areaId].floor_id;
|
|
18
21
|
}
|
|
19
22
|
else {
|
|
23
|
+
// Area name or alias
|
|
20
24
|
for (const areaId in hass.areas) {
|
|
21
|
-
if (hass.areas[areaId].name == lookup_value
|
|
25
|
+
if (hass.areas[areaId].name == lookup_value ||
|
|
26
|
+
hass.areas[areaId].aliases?.includes(lookup_value)) {
|
|
22
27
|
return hass.areas[areaId].floor_id;
|
|
23
28
|
}
|
|
24
29
|
}
|
|
25
30
|
}
|
|
31
|
+
// Floor name or alias
|
|
32
|
+
for (const floorId in hass.floors) {
|
|
33
|
+
if (hass.floors[floorId].name == lookup_value ||
|
|
34
|
+
hass.floors[floorId].aliases?.includes(lookup_value)) {
|
|
35
|
+
return floorId;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
26
38
|
}
|
|
27
39
|
return undefined;
|
|
28
40
|
}
|
|
@@ -50,7 +62,8 @@ export function floor_areas(hass, floor_name_or_id) {
|
|
|
50
62
|
}
|
|
51
63
|
else {
|
|
52
64
|
for (const id in hass.floors) {
|
|
53
|
-
if (hass.floors[id].name == floor_name_or_id
|
|
65
|
+
if (hass.floors[id].name == floor_name_or_id ||
|
|
66
|
+
hass.floors[id].aliases?.includes(floor_name_or_id)) {
|
|
54
67
|
floorId = id;
|
|
55
68
|
break;
|
|
56
69
|
}
|
|
@@ -71,3 +84,22 @@ export function floor_areas(hass, floor_name_or_id) {
|
|
|
71
84
|
return [];
|
|
72
85
|
}
|
|
73
86
|
}
|
|
87
|
+
export function floor_entities(hass, floor_name_or_id) {
|
|
88
|
+
try {
|
|
89
|
+
const res = new Set();
|
|
90
|
+
const areas = floor_areas(hass, floor_name_or_id);
|
|
91
|
+
for (const entityId in hass.entities) {
|
|
92
|
+
if (areas.includes(hass.entities[entityId].area_id)) {
|
|
93
|
+
res.add(entityId);
|
|
94
|
+
for (const subEntityId of hass.states[entityId]?.attributes
|
|
95
|
+
?.entity_id ?? []) {
|
|
96
|
+
res.add(subEntityId);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return Array.from(res);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
}
|
package/dist/utils/json.d.ts
CHANGED
package/dist/utils/json.js
CHANGED
|
@@ -21,3 +21,9 @@ export function to_json(obj, ensure_ascii = false, pretty_print = false, sort_ke
|
|
|
21
21
|
export function from_json(value) {
|
|
22
22
|
return JSON.parse(value);
|
|
23
23
|
}
|
|
24
|
+
export function is_defined(value) {
|
|
25
|
+
if (value == undefined) {
|
|
26
|
+
throw Error('UndefinedError: input is undefined');
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
package/dist/utils/labels.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare function fetchLabelRegistry(): Promise<void>;
|
|
|
3
3
|
export declare function labels(hass: HomeAssistant, lookup_value?: string): string[];
|
|
4
4
|
export declare function label_id(lookup_value: string): string | undefined;
|
|
5
5
|
export declare function label_name(lookup_value: string): string;
|
|
6
|
+
export declare function label_description(lookup_value: string): string | undefined;
|
|
6
7
|
export declare function label_areas(hass: HomeAssistant, label_name_or_id: string): string[];
|
|
7
8
|
export declare function label_devices(hass: HomeAssistant, label_name_or_id: string): string[];
|
|
8
9
|
export declare function label_entities(hass: HomeAssistant, label_name_or_id: string): string[];
|
package/dist/utils/labels.js
CHANGED
|
@@ -32,6 +32,9 @@ export function label_id(lookup_value) {
|
|
|
32
32
|
export function label_name(lookup_value) {
|
|
33
33
|
return window.haNunjucks.labelRegistry[lookup_value]?.name;
|
|
34
34
|
}
|
|
35
|
+
export function label_description(lookup_value) {
|
|
36
|
+
return window.haNunjucks.labelRegistry[lookup_value]?.description;
|
|
37
|
+
}
|
|
35
38
|
export function label_areas(hass, label_name_or_id) {
|
|
36
39
|
try {
|
|
37
40
|
const areaIds = [];
|
|
@@ -3,7 +3,7 @@ import { HomeAssistant } from '../models/interfaces/hass';
|
|
|
3
3
|
export declare function state_translated(hass: HomeAssistant, entity_id: string, state?: string): string;
|
|
4
4
|
export declare function attr_name_translated(hass: HomeAssistant, entity_id: string, attr_name: string): string;
|
|
5
5
|
export declare function attr_value_translated(hass: HomeAssistant, entity_id: string, attr_name: string, attr_value?: string): any;
|
|
6
|
-
export declare function number_translated(value: number): string | number;
|
|
6
|
+
export declare function number_translated(value: number, precision?: number): string | number;
|
|
7
7
|
export declare function date_translated(value: date | datetime): string | date | datetime;
|
|
8
8
|
export declare function time_translated(value: time | datetime): string | datetime | time;
|
|
9
9
|
export declare function datetime_translated(value: datetime): string | datetime;
|
|
@@ -26,10 +26,17 @@ export function attr_value_translated(hass, entity_id, attr_name, attr_value) {
|
|
|
26
26
|
undefined);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
export function number_translated(value) {
|
|
29
|
+
export function number_translated(value, precision) {
|
|
30
|
+
value = Number(value);
|
|
30
31
|
if (isNaN(value)) {
|
|
31
32
|
return value;
|
|
32
33
|
}
|
|
34
|
+
if (precision) {
|
|
35
|
+
return value.toLocaleString(window.haNunjucks.hass.language, {
|
|
36
|
+
minimumFractionDigits: precision,
|
|
37
|
+
maximumFractionDigits: precision,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
33
40
|
return window.haNunjucks.numberFormat.format(value);
|
|
34
41
|
}
|
|
35
42
|
export function date_translated(value) {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import slugifyLib from 'slugify';
|
|
2
|
+
export function slugify(str, separator = '_') {
|
|
3
|
+
return slugifyLib(str, {
|
|
4
|
+
replacement: separator,
|
|
5
|
+
lower: true,
|
|
6
|
+
strict: true,
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
export function ordinal(num) {
|
|
10
|
+
if (isNaN(num)) {
|
|
11
|
+
throw Error('Input must be a number');
|
|
12
|
+
}
|
|
13
|
+
const suffixes = {
|
|
14
|
+
one: 'st',
|
|
15
|
+
two: 'nd',
|
|
16
|
+
few: 'rd',
|
|
17
|
+
other: 'th',
|
|
18
|
+
};
|
|
19
|
+
const suffix = suffixes[window.haNunjucks.ordinalFormat.select(num)] || 'th';
|
|
20
|
+
return `${num}${suffix}`;
|
|
21
|
+
}
|
|
22
|
+
export function base64_encode(value) {
|
|
23
|
+
return btoa(value);
|
|
24
|
+
}
|
|
25
|
+
export function base64_decode(value) {
|
|
26
|
+
return atob(value);
|
|
27
|
+
}
|
package/dist/utils/time.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare function as_datetime(value: number | string | datetime | date, fa
|
|
|
6
6
|
export declare function as_timestamp(value: number | string | datetime | date, fallback?: string): string | number;
|
|
7
7
|
export declare function as_local(value: datetime): datetime;
|
|
8
8
|
export declare function strptime(value: string, format: string, fallback?: datetime | string | undefined | Record<string, datetime | string | boolean>, utc?: boolean): string | datetime | Record<string, string | boolean | datetime>;
|
|
9
|
+
export declare function relative_time(input: datetime): string | datetime;
|
|
9
10
|
export declare function time_since(input: datetime, precision?: number): string | datetime;
|
|
10
11
|
export declare function time_until(input: datetime, precision?: number): string | datetime;
|
|
11
12
|
export declare function as_timedelta(value: string): timedelta | null;
|
package/dist/utils/time.js
CHANGED
|
@@ -130,7 +130,7 @@ function timeDiff(input, precision = 1, until = false) {
|
|
|
130
130
|
if (diff <= 0) {
|
|
131
131
|
return input;
|
|
132
132
|
}
|
|
133
|
-
if (precision
|
|
133
|
+
if (precision < 1 || precision > 6) {
|
|
134
134
|
precision = 6;
|
|
135
135
|
}
|
|
136
136
|
const toSeconds = {
|
|
@@ -143,23 +143,29 @@ function timeDiff(input, precision = 1, until = false) {
|
|
|
143
143
|
};
|
|
144
144
|
const units = Object.keys(toSeconds);
|
|
145
145
|
let res = '';
|
|
146
|
-
let
|
|
147
|
-
for (let i = 0; i <
|
|
146
|
+
let p = 0;
|
|
147
|
+
for (let i = 0; i < units.length; i++) {
|
|
148
148
|
let value = diff / toSeconds[units[i]];
|
|
149
|
-
if (i ==
|
|
149
|
+
if (i == p - 1) {
|
|
150
150
|
value = Math.round(value);
|
|
151
151
|
}
|
|
152
152
|
else {
|
|
153
153
|
value = Math.floor(value);
|
|
154
154
|
}
|
|
155
|
-
if (
|
|
156
|
-
|
|
155
|
+
if (value > 0) {
|
|
156
|
+
p += 1;
|
|
157
157
|
res += ` ${value} ${units[i]}${value != 1 ? 's' : ''}`;
|
|
158
158
|
diff -= value * toSeconds[units[i]];
|
|
159
159
|
}
|
|
160
|
+
if (res.length && precision == p) {
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
160
163
|
}
|
|
161
164
|
return res.trim();
|
|
162
165
|
}
|
|
166
|
+
export function relative_time(input) {
|
|
167
|
+
return timeDiff(input);
|
|
168
|
+
}
|
|
163
169
|
export function time_since(input, precision = 1) {
|
|
164
170
|
return timeDiff(input, precision);
|
|
165
171
|
}
|
|
@@ -174,12 +180,10 @@ export function as_timedelta(value) {
|
|
|
174
180
|
/^\d*\.?\d*$/.test(value)) {
|
|
175
181
|
let daysStr, timeStr;
|
|
176
182
|
if (value.includes(' ')) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
[daysStr, timeStr] = value.split(' ');
|
|
182
|
-
}
|
|
183
|
+
[daysStr, timeStr] = value
|
|
184
|
+
.replace(/day(s?)/g, '')
|
|
185
|
+
.replace(/\s+/g, ' ')
|
|
186
|
+
.split(' ');
|
|
183
187
|
}
|
|
184
188
|
else {
|
|
185
189
|
daysStr = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ha-nunjucks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Wrapper for nunjucks for use with Home Assistant frontend custom components to render templates",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"*": "prettier -w"
|
|
18
18
|
},
|
|
19
19
|
"author": "Nerwyn",
|
|
20
|
-
"license": "
|
|
20
|
+
"license": "Apache-2.0",
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
23
|
"url": "git+https://github.com/Nerwyn/ha-nunjucks.git"
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"home-assistant-js-websocket": "latest",
|
|
31
31
|
"nunjucks": "latest",
|
|
32
|
+
"slugify": "latest",
|
|
32
33
|
"ts-py-datetime": "latest"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
@@ -39,14 +40,14 @@
|
|
|
39
40
|
"eslint": "latest",
|
|
40
41
|
"eslint-config-prettier": "latest",
|
|
41
42
|
"eslint-plugin-prettier": "latest",
|
|
42
|
-
"jsdom
|
|
43
|
+
"global-jsdom": "latest",
|
|
43
44
|
"lint-staged": "latest",
|
|
44
45
|
"mocha": "latest",
|
|
45
46
|
"prettier": "latest",
|
|
46
47
|
"prettier-plugin-organize-imports": "latest",
|
|
47
48
|
"ts-loader": "latest",
|
|
48
49
|
"ts-mocha": "latest",
|
|
49
|
-
"ts-node": "
|
|
50
|
+
"ts-node": "latest",
|
|
50
51
|
"tsx": "latest",
|
|
51
52
|
"typescript": "latest"
|
|
52
53
|
}
|