UNPKG

iobroker.roborock

Version:
117 lines (101 loc) 3.68 kB
import type { FeatureDependencies } from "../../baseDeviceFeatures"; import { DeviceStateWriter } from "../../deviceStateWriter"; import { VACUUM_CONSTANTS } from "../vacuumConstants"; export class B01ConsumableService { private readonly stateWriter: DeviceStateWriter; constructor( private deps: FeatureDependencies, private duid: string ) { this.stateWriter = new DeviceStateWriter(deps, duid); } private readonly PROP_MAP: Record<string, string> = { main_brush: "main_brush_work_time", side_brush: "side_brush_work_time", hypa: "filter_work_time", main_sensor: "sensor_dirty_time", filter_element: "filter_element_work_time" }; public async updateConsumables(data?: unknown): Promise<void> { let resultObj: Record<string, any> | undefined; if (data) { resultObj = data as Record<string, any>; } else { const props = VACUUM_CONSTANTS.b01SettingsProps; const result = await this.deps.adapter.requestsHandler.sendRequest(this.duid, "prop.get", { property: props }); if (Array.isArray(result) && result.length === props.length) { resultObj = {}; for (let i = 0; i < props.length; i++) { const key = props[i]; const mappedKey = this.PROP_MAP[key] || key; resultObj[mappedKey] = result[i]; } } else if (typeof result === "object" && result !== null) { resultObj = result as Record<string, any>; } } if (resultObj) { await this.processConsumables(resultObj); } } protected async processConsumables(resultObj: Record<string, unknown>): Promise<void> { await this.stateWriter.ensureFolder("consumables"); await this.stateWriter.ensureFolder("resetConsumables"); for (const key in resultObj) { if (!key.endsWith("_work_time") && !key.endsWith("_work_times") && !key.endsWith("_dirty_time")) { continue; } let val = resultObj[key] as number; // Consumable name normalization const deviceName = key.replace(/(_work_times|_work_time|_dirty_time)$/, ""); const translationKey = VACUUM_CONSTANTS.consumableTranslationKeys[deviceName as keyof typeof VACUUM_CONSTANTS.consumableTranslationKeys]; const localizedName = translationKey ? this.deps.adapter.translationManager.get(translationKey, deviceName) : deviceName; let unit = ""; let suffix = ""; if (key.endsWith("_work_times")) { unit = "cycles"; suffix = " cycles"; } else if (key.endsWith("_work_time") || key.endsWith("_dirty_time")) { const totalSeconds = this.getConsumableLifeSpan(deviceName) * 3600; if (totalSeconds > 0) { // Convert seconds used to remaining hours val = Math.max(0, Math.round((totalSeconds - val) / 3600)); unit = "h"; suffix = " remaining time"; } else { unit = "s"; suffix = " work time"; } } // Create/Update the raw state exactly as it comes from the robot (but converted to h if applicable) await this.stateWriter.ensureAndSetValueState(`consumables.${key}`, { name: `${localizedName}${suffix}`, type: "number", role: "value", unit: unit, write: false }, val); // Reset Button const resetKey = `reset_${deviceName}`; await this.stateWriter.ensureState(`resetConsumables.${resetKey}`, { name: `Reset ${localizedName}`, type: "boolean", role: "button", write: true, def: false }, { resetParam: key }); } } private getConsumableLifeSpan(deviceName: string): number { switch (deviceName) { case "main_brush": return 300; case "side_brush": return 200; case "filter": case "filter_element": return 150; case "sensor": return 30; case "strainer": return 150; case "cleaning_brush": return 300; default: return 0; } } }