Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for capability attributes in demo #21263

Merged
merged 1 commit into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 70 additions & 5 deletions src/fake_data/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ const now = () => new Date().toISOString();
const randomTime = () =>
new Date(new Date().getTime() - Math.random() * 80 * 60 * 1000).toISOString();

const CAPABILITY_ATTRIBUTES = [
"friendly_name",
"unit_of_measurement",
"icon",
"entity_picture",
"supported_features",
"hidden",
"assumed_state",
"device_class",
"state_class",
"restored",
];
export class Entity {
public domain: string;

Expand All @@ -29,16 +41,28 @@ export class Entity {

public hass?: any;

constructor(domain, objectId, state, baseAttributes) {
static CAPABILITY_ATTRIBUTES = new Set(CAPABILITY_ATTRIBUTES);

constructor(domain, objectId, state, attributes) {
this.domain = domain;
this.objectId = objectId;
this.entityId = `${domain}.${objectId}`;
this.lastChanged = randomTime();
this.lastUpdated = randomTime();
this.state = String(state);

// These are the attributes that we always write to the state machine
const baseAttributes = {};
const capabilityAttributes =
TYPES[domain]?.CAPABILITY_ATTRIBUTES || Entity.CAPABILITY_ATTRIBUTES;
for (const key of Object.keys(attributes)) {
if (capabilityAttributes.has(key)) {
baseAttributes[key] = attributes[key];
}
}

this.baseAttributes = baseAttributes;
this.attributes = baseAttributes;
this.attributes = attributes;
}

public async handleService(domain, service, data: Record<string, any>) {
Expand All @@ -54,7 +78,7 @@ export class Entity {
this.lastUpdated = now();
this.lastChanged =
state === this.state ? this.lastChanged : this.lastUpdated;
this.attributes = { ...this.baseAttributes, ...attributes };
this.attributes = { ...this.attributes, ...attributes };

// eslint-disable-next-line
console.log("update", this.entityId, this);
Expand All @@ -68,14 +92,24 @@ export class Entity {
return {
entity_id: this.entityId,
state: this.state,
attributes: this.attributes,
attributes: this.state === "off" ? this.baseAttributes : this.attributes,
last_changed: this.lastChanged,
last_updated: this.lastUpdated,
};
}
}

class LightEntity extends Entity {
static CAPABILITY_ATTRIBUTES = new Set([
...CAPABILITY_ATTRIBUTES,
"min_color_temp_kelvin",
"max_color_temp_kelvin",
"min_mireds",
"max_mireds",
"effect_list",
"supported_color_modes",
]);

public async handleService(domain, service, data) {
if (!["homeassistant", this.domain].includes(domain)) {
return;
Expand Down Expand Up @@ -188,6 +222,12 @@ class AlarmControlPanelEntity extends Entity {
}

class MediaPlayerEntity extends Entity {
static CAPABILITY_ATTRIBUTES = new Set([
...CAPABILITY_ATTRIBUTES,
"source_list",
"sound_mode_list",
]);

public async handleService(
domain,
service,
Expand Down Expand Up @@ -223,7 +263,11 @@ class CoverEntity extends Entity {
if (service === "open_cover") {
this.update("open");
} else if (service === "close_cover") {
this.update("closing");
this.update("closed");
} else if (service === "set_cover_position") {
this.update(data.position > 0 ? "open" : "closed", {
current_position: data.position,
});
} else {
super.handleService(domain, service, data);
}
Expand Down Expand Up @@ -288,6 +332,19 @@ class InputSelectEntity extends Entity {
}

class ClimateEntity extends Entity {
static CAPABILITY_ATTRIBUTES = new Set([
...CAPABILITY_ATTRIBUTES,
"hvac_modes",
"min_temp",
"max_temp",
"target_temp_step",
"fan_modes",
"preset_modes",
"swing_modes",
"min_humidity",
"max_humidity",
]);

public async handleService(domain, service, data) {
if (domain !== this.domain) {
return;
Expand Down Expand Up @@ -357,6 +414,14 @@ class ClimateEntity extends Entity {
}

class WaterHeaterEntity extends Entity {
static CAPABILITY_ATTRIBUTES = new Set([
...CAPABILITY_ATTRIBUTES,
"current_temperature",
"min_temp",
"max_temp",
"operation_list",
]);

public async handleService(domain, service, data) {
if (domain !== this.domain) {
return;
Expand Down
2 changes: 2 additions & 0 deletions src/fake_data/provide_hass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ export const provideHass = (
// @ts-ignore
async callService(domain, service, data) {
if (data && "entity_id" in data) {
// eslint-disable-next-line
console.log("Entity service call", domain, service, data);
Comment on lines +281 to +282
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a debug flag for logging.

Logging service calls is useful for debugging, but it might not be necessary for production environments. Consider adding a debug flag to control this logging.

- console.log("Entity service call", domain, service, data);
+ if (hass().debugConnection) {
+   console.log("Entity service call", domain, service, data);
+ }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// eslint-disable-next-line
console.log("Entity service call", domain, service, data);
// eslint-disable-next-line
if (hass().debugConnection) {
console.log("Entity service call", domain, service, data);
}

await Promise.all(
ensureArray(data.entity_id).map((ent) =>
entities[ent].handleService(domain, service, data)
Expand Down
Loading