Skip to content

Commit 3dfd77e

Browse files
authored
fix: unavailable entities excluded by filter.above and lowercase display (#30)
1 parent fcb1c05 commit 3dfd77e

File tree

3 files changed

+90
-3
lines changed

3 files changed

+90
-3
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'ha-treemap-card': patch
3+
---
4+
5+
Fixed unavailable entities being incorrectly filtered out when using `filter.above`. Also fixed capitalization of "Unknown" and "Unavailable" states to match Home Assistant's UI.

src/treemap-card.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,11 @@ export class TreemapCard extends LitElement {
556556
const filterBelow = this._config.filter?.below;
557557

558558
return data.filter(item => {
559+
// Skip filter.above/below checks for unavailable entities
560+
// (they have placeholder value 0, which would incorrectly trigger filters)
561+
if (item.unavailable) {
562+
return true;
563+
}
559564
if (filterAbove !== undefined && item.value <= filterAbove) {
560565
return false;
561566
}
@@ -758,8 +763,8 @@ export class TreemapCard extends LitElement {
758763
// Format value: config precision > entity display_precision > default 1
759764
let formattedValue: string;
760765
if (rect.unavailable && rect.rawState) {
761-
// Show raw state for unavailable entities (e.g., "unavailable", "unknown")
762-
formattedValue = rect.rawState;
766+
// Show raw state for unavailable entities, capitalized like HA does (e.g., "Unavailable", "Unknown")
767+
formattedValue = rect.rawState.charAt(0).toUpperCase() + rect.rawState.slice(1);
763768
} else {
764769
const entityPrecision = rect.entity_id
765770
? this.hass?.entities?.[rect.entity_id]?.display_precision

tests/sensors.test.ts

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ describe('Sensor Entities', () => {
698698
const shadow = card.shadowRoot;
699699
const valueEl = shadow?.querySelector('.treemap-value');
700700

701-
expect(valueEl?.textContent).toBe('unavailable');
701+
expect(valueEl?.textContent).toBe('Unavailable');
702702
});
703703

704704
it('applies gray color to unavailable entities', async () => {
@@ -746,6 +746,83 @@ describe('Sensor Entities', () => {
746746
expect(deadSensor).toBeDefined();
747747
expect(deadSensor?.backgroundColor).toContain('rgb(255, 0, 0)');
748748
});
749+
750+
it('includes unavailable entities when using filter.above', async () => {
751+
// Bug report: "Unknown" entities not showing when used with filter.above
752+
// https://github.com/omachala/ha-treemap-card/issues/20
753+
const hass = mockHass([
754+
mockEntity('sensor.mqtt_1', '5', { friendly_name: 'MQTT 1' }),
755+
mockEntity('sensor.mqtt_2', '10', { friendly_name: 'MQTT 2' }),
756+
mockEntity('sensor.mqtt_3', 'unknown', { friendly_name: 'MQTT Unknown' }),
757+
]);
758+
759+
card.setConfig({
760+
type: 'custom:treemap-card',
761+
entities: ['sensor.mqtt_*'],
762+
filter: { unavailable: true, above: 3 },
763+
});
764+
card.hass = hass;
765+
await card.updateComplete;
766+
767+
const items = getRenderedItems(card);
768+
769+
// Should include: mqtt_1 (5 > 3), mqtt_2 (10 > 3), and mqtt_unknown (unavailable, should be included)
770+
expect(items).toHaveLength(3);
771+
expect(items.find(i => i.label === 'MQTT 1')).toBeDefined();
772+
expect(items.find(i => i.label === 'MQTT 2')).toBeDefined();
773+
expect(items.find(i => i.label === 'MQTT Unknown')).toBeDefined();
774+
});
775+
776+
it('includes unavailable entities when using filter.below', async () => {
777+
// This should work (reported as working in issue)
778+
const hass = mockHass([
779+
mockEntity('sensor.mqtt_1', '5', { friendly_name: 'MQTT 1' }),
780+
mockEntity('sensor.mqtt_2', '10', { friendly_name: 'MQTT 2' }),
781+
mockEntity('sensor.mqtt_3', 'unknown', { friendly_name: 'MQTT Unknown' }),
782+
]);
783+
784+
card.setConfig({
785+
type: 'custom:treemap-card',
786+
entities: ['sensor.mqtt_*'],
787+
filter: { unavailable: true, below: 8 },
788+
});
789+
card.hass = hass;
790+
await card.updateComplete;
791+
792+
const items = getRenderedItems(card);
793+
794+
// Should include: mqtt_1 (5 < 8), and mqtt_unknown (unavailable, should be included)
795+
// mqtt_2 (10) should be filtered out
796+
expect(items).toHaveLength(2);
797+
expect(items.find(i => i.label === 'MQTT 1')).toBeDefined();
798+
expect(items.find(i => i.label === 'MQTT Unknown')).toBeDefined();
799+
expect(items.find(i => i.label === 'MQTT 2')).toBeUndefined();
800+
});
801+
802+
it('displays capitalized state text for unavailable entities', async () => {
803+
// Bug report: raw state shows as "unknown" instead of "Unknown"
804+
// https://github.com/omachala/ha-treemap-card/issues/20
805+
const hass = mockHass([
806+
mockEntity('sensor.dead', 'unknown', {
807+
friendly_name: 'Dead Sensor',
808+
unit_of_measurement: '%',
809+
}),
810+
]);
811+
812+
card.setConfig({
813+
type: 'custom:treemap-card',
814+
entities: ['sensor.dead'],
815+
filter: { unavailable: true },
816+
});
817+
card.hass = hass;
818+
await card.updateComplete;
819+
820+
const shadow = card.shadowRoot;
821+
const valueEl = shadow?.querySelector('.treemap-value');
822+
823+
// Should capitalize like HA does: "Unknown" not "unknown"
824+
expect(valueEl?.textContent).toBe('Unknown');
825+
});
749826
});
750827

751828
describe('value.precision and value.abbreviate', () => {

0 commit comments

Comments
 (0)