Skip to content

Commit

Permalink
Merge pull request #587 from maxwroc/DynamicIcon
Browse files Browse the repository at this point in the history
Dynamic custom icons
  • Loading branch information
maxwroc authored Oct 24, 2023
2 parents 9963573 + 32a90a3 commit 57f33fe
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 2 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -606,12 +606,15 @@ entities:

### Other use cases

![image](https://github.com/maxwroc/battery-state-card/assets/8268674/d66bcd53-e37a-4518-a087-bd7e708b3425)
![image](https://github.com/maxwroc/battery-state-card/assets/8268674/40957377-d523-45d2-99ae-39325b5ddacc)
![image](https://github.com/maxwroc/battery-state-card/assets/8268674/477149f8-9d88-4858-b1f4-f7c615186845)

```yaml
type: custom:battery-state-card
secondary_info: '{last_changed}'
icon: mdi:signal
# below an example with dynamic icon
# icon: "mdi:signal-cellular-{state|abs()|greaterthan(69,outline)|greaterthan(59,1)|greaterthan(49,2)|greaterthan(2,3)}"
filter:
include:
- name: attributes.device_class
Expand Down
5 changes: 4 additions & 1 deletion src/entity-fields/get-icon.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { HomeAssistant } from "custom-card-helpers";
import { log } from "../utils";
import { RichStringProcessor } from "../rich-string-processor";

/**
* Gets MDI icon class
Expand All @@ -16,6 +17,7 @@ export const getIcon = (config: IBatteryEntityConfig, level: number, isCharging:

if (config.icon) {
const attribPrefix = "attribute.";
// check if we should return the icon/string from the attribute value
if (hass && config.icon.startsWith(attribPrefix)) {
const attribName = config.icon.substr(attribPrefix.length);
const val = hass.states[config.entity].attributes[attribName] as string | undefined;
Expand All @@ -27,7 +29,8 @@ export const getIcon = (config: IBatteryEntityConfig, level: number, isCharging:
return val;
}

return config.icon;
const processor = new RichStringProcessor(hass, config.entity);
return processor.process(config.icon);
}

if (isNaN(level) || level > 100 || level < 0) {
Expand Down
16 changes: 16 additions & 0 deletions test/other/entity-fields/get-icon.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getIcon } from "../../../src/entity-fields/get-icon";
import { HomeAssistantMock } from "../../helpers";

describe("Get icon", () => {
test("charging and charging icon set in config", () => {
Expand Down Expand Up @@ -45,4 +46,19 @@ describe("Get icon", () => {
let icon = getIcon({ entity: "", icon: "mdi:custom" }, 20, false, undefined);
expect(icon).toBe("mdi:custom");
});

test.each([
["signal-cellular-{state}", "20", "signal-cellular-20"],
["signal-cellular-{state|abs()|greaterthan(69,outline)|greaterthan(59,1)|greaterthan(49,2)|greaterthan(2,3)}", "40", "signal-cellular-3"],
["signal-cellular-{state|abs()|greaterthan(69,outline)|greaterthan(59,1)|greaterthan(49,2)|greaterthan(2,3)}", "55", "signal-cellular-2"],
["signal-cellular-{state|abs()|greaterthan(69,outline)|greaterthan(59,1)|greaterthan(49,2)|greaterthan(2,3)}", "65", "signal-cellular-1"],
["signal-cellular-{state|abs()|greaterthan(69,outline)|greaterthan(59,1)|greaterthan(49,2)|greaterthan(2,3)}", "75", "signal-cellular-outline"],
])("returns dynamic icon", (configuredIcon: string, state: string, expectedResult: string) => {

const hassMock = new HomeAssistantMock();
hassMock.addEntity("Battery state", state);

let icon = getIcon({ entity: "battery_state", icon: configuredIcon }, Number(state), false, hassMock.hass);
expect(icon).toBe(expectedResult);
})
});

0 comments on commit 57f33fe

Please sign in to comment.