@rygine/omnilogic-local-sdk 0.0.1 → 0.0.3

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["setTimeout","protocolLog","setTimeout","setTimeout"],"sources":["../src/client/spec.ts","../src/constants/labels.ts","../src/constants/sentinels.ts","../src/utils/errors.ts","../src/utils/helpers.ts","../src/utils/inventory.ts","../src/equipment/device.ts","../src/utils/decode.ts","../src/equipment/chlorinator.ts","../src/equipment/csad.ts","../src/equipment/schedules.ts","../src/utils/xml.ts","../src/utils/command.ts","../src/equipment/pump.ts","../src/equipment/filter.ts","../src/equipment/heaterAppliance.ts","../src/equipment/heater.ts","../src/constants/lightShows.ts","../src/utils/logger.ts","../src/equipment/light.ts","../src/equipment/relay.ts","../src/equipment/bodyOfWater.ts","../src/equipment/favorites.ts","../src/equipment/panel.ts","../src/equipment/themes.ts","../src/equipment/backyard.ts","../src/transport/message.ts","../src/transport/queue.ts","../src/transport/protocol.ts","../src/client/omnilogic.ts"],"sourcesContent":["import type { InventoryPath } from \"@/utils/inventory\";\nimport type { DataType } from \"@/utils/xml\";\n\n// a request parameter's type, which is never a bool\nexport type CommandWireType = Exclude<DataType, \"bool\">;\n\ntype CommandNumericParam = {\n name: string;\n type: Exclude<CommandWireType, \"string\">;\n};\n\ntype CommandStringParam = {\n name: string;\n type: \"string\";\n // the longest value the firmware keeps intact\n maxLength: number;\n values?: string[];\n};\n\nexport type CommandRequestParam = CommandNumericParam | CommandStringParam;\n\ntype CommandResponseParam = {\n name: string;\n dataType: DataType;\n unit?: string;\n};\n\nexport type CommandResponseSpec = {\n name: string;\n opcode: number;\n parameters: CommandResponseParam[];\n};\n\ntype CommandSpec<Name extends string = string> = {\n opcode: number;\n // wire order\n request: CommandRequestParam[];\n // the reply's opcode\n response?: CommandResponseSpec;\n // the cache stays clean after one\n read?: true;\n // the controller goes quiet for 12–22 s after acknowledging this and drops what arrives meanwhile\n settle?: true;\n // inventory paths that must not be absent for this command to apply\n requires?: InventoryPath[];\n // the equipment whose id this command takes\n target?: InventoryPath;\n caveat?: {\n // what the command does that a caller would not expect\n effect: string;\n // the command to use instead\n alternative?: Name;\n };\n};\n\nconst defineSpec = <\n const S extends Record<string, CommandSpec<keyof S & string>>,\n>(\n spec: S,\n) => spec;\n\nconst SPEC = defineSpec({\n SetUIPoolSpaSpilloverCmd: {\n opcode: 6,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"moves the return valve. On some installs it is plumbed the other way around, so turning spillover on has the opposite effect and stops it\",\n },\n },\n GetUIPoolSpaSpilloverCmd: {\n read: true,\n opcode: 7,\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"UIPoolSpaSpilloverRsp\",\n opcode: 1007,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"position\", dataType: \"int\" },\n ],\n },\n },\n SetUIPoolFilterCmd: {\n opcode: 8,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n SetUIFilterSpeedCmd: {\n opcode: 9,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIFilterSpeedCmd: {\n read: true,\n opcode: 10,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIFilterSpeedRsp\",\n opcode: 1010,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n { name: \"speed\", dataType: \"int\", unit: \"RPM\" },\n ],\n },\n },\n SetUIHeaterCmd: {\n opcode: 11,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIHeaterCmd: {\n read: true,\n opcode: 12,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIHeaterRsp\",\n opcode: 1012,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"temp\", dataType: \"int\", unit: \"F\" },\n ],\n },\n },\n SetUIHeaterPriorityCmd: {\n opcode: 13,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIHeaterPriorityCmd: {\n read: true,\n opcode: 14,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUISuperCHLORCmd: {\n opcode: 15,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"stops the filter pump when it turns superchlorination off, even a pump turned on by hand, so send the filter's speed again afterwards\",\n },\n },\n GetUISuperCHLORCmd: {\n read: true,\n opcode: 16,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UISuperCHLORRsp\",\n opcode: 1016,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"isOn\", dataType: \"byte\" },\n ],\n },\n },\n SetUISuperCHLORTimeoutCmd: {\n opcode: 17,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n SetUIORPCHLORTimeoutCmd: {\n opcode: 18,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"is acknowledged and then ignored: the controller does nothing with it and sends no reply\",\n },\n },\n SetUISuperCHLOROutputCmd: {\n opcode: 19,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"is acknowledged and then ignored: the controller does nothing with it and sends no reply\",\n },\n },\n GetUISuperCHLOROutputCmd: {\n read: true,\n opcode: 20,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"is acknowledged and then ignored: the controller does nothing with it and sends no reply\",\n },\n },\n SetUIRelayCmd: {\n opcode: 21,\n caveat: {\n effect:\n \"does nothing with isOn 1 unless a start and end time are given, and then runs the relay as a schedule without enforcing the end time\",\n alternative: \"SetUIEquipmentCmd\",\n },\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"isOn\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n GetUIRelayCmd: {\n read: true,\n opcode: 22,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIRelayRsp\",\n opcode: 1022,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"relayId\", dataType: \"int\" },\n { name: \"isOn\", dataType: \"int\" },\n ],\n },\n },\n SetUIValveCmd: {\n opcode: 23,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n GetUIValveCmd: {\n read: true,\n opcode: 24,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIValveRsp\",\n opcode: 1024,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"vaid\", dataType: \"int\" },\n { name: \"valveState\", dataType: \"int\" },\n ],\n },\n },\n GetUIPoolTempCmd: {\n read: true,\n opcode: 25,\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"UIGetPoolTempRsp\",\n opcode: 1025,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"temp\", dataType: \"int\", unit: \"F\" },\n ],\n },\n },\n GetUIAirTempCmd: {\n read: true,\n opcode: 26,\n request: [],\n response: {\n name: \"UIGetAirTempRsp\",\n opcode: 1026,\n parameters: [{ name: \"temp\", dataType: \"int\", unit: \"F\" }],\n },\n },\n GetUIFlowSensor: {\n read: true,\n opcode: 27,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetUIFlowSensorRsp\",\n opcode: 1027,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"reading\", dataType: \"int\" },\n ],\n },\n },\n GetUISensor: {\n read: true,\n opcode: 28,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"is acknowledged and then ignored: the controller does nothing with it and sends no reply\",\n },\n },\n GetUISolarTempCmd: {\n read: true,\n opcode: 29,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UiSetManualLastSpeed: {\n opcode: 34,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n GetAutoTime: {\n read: true,\n opcode: 35,\n request: [],\n response: {\n name: \"GetAutoTimeRsp\",\n opcode: 1035,\n parameters: [\n { name: \"year\", dataType: \"int\" },\n { name: \"month\", dataType: \"int\" },\n { name: \"day\", dataType: \"int\" },\n { name: \"format\", dataType: \"bool\" },\n { name: \"hour\", dataType: \"int\" },\n { name: \"minute\", dataType: \"int\" },\n { name: \"amPm\", dataType: \"string\" },\n { name: \"autoUpdateTime\", dataType: \"bool\" },\n ],\n },\n },\n SetUISolarSetPointCmd: {\n opcode: 40,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetSetUISolarSetPointCmd: {\n read: true,\n opcode: 41,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UISolarSetPointCmdRsp\",\n opcode: 1041,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"temp\", dataType: \"int\", unit: \"F\" },\n ],\n },\n },\n SetUIHeaterModeCmd: {\n opcode: 42,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIHeaterModeCmd: {\n read: true,\n opcode: 43,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIGetHeaterModeCmdRsp\",\n opcode: 1043,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"mode\", dataType: \"int\" },\n ],\n },\n },\n SetHeaterAutoDifferential: {\n opcode: 44,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterAutoDifferential: {\n read: true,\n opcode: 45,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIGetHeaterAutoDifferentialRsp\",\n opcode: 1045,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"data\", dataType: \"int\" },\n ],\n },\n },\n GetHeaterDiagnostic: {\n read: true,\n opcode: 46,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetHeaterPowerUsage: {\n read: true,\n opcode: 47,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetHeaterSensor: {\n read: true,\n opcode: 48,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetHeaterSilentMode: {\n opcode: 49,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterSilentMode: {\n read: true,\n opcode: 50,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterSilentModeRsp\",\n opcode: 1050,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetUISmartValveCmd: {\n opcode: 60,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n GetUISmartValveCmd: {\n read: true,\n opcode: 61,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIGetSmartValveRsp\",\n opcode: 1061,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"isOn\", dataType: \"byte\" },\n { name: \"target\", dataType: \"byte\" },\n { name: \"data3\", dataType: \"byte\" },\n { name: \"data4\", dataType: \"byte\" },\n ],\n },\n },\n SetUISmartValveTargetCmd: {\n opcode: 62,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n SetUISmartValveForTheme: {\n opcode: 63,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n ],\n },\n GetFlowControlPortStatus: {\n read: true,\n opcode: 64,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetFlowControlPortConfig: {\n read: true,\n opcode: 65,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetFlowControlDiagnostic: {\n read: true,\n opcode: 66,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetFlowControlPortErrors: {\n read: true,\n opcode: 67,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n FlowControlHomePortsCmd: {\n opcode: 68,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUIFlowControlForTheme: {\n opcode: 69,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"field1c\", type: \"byte\" },\n { name: \"field1d\", type: \"byte\" },\n { name: \"field1e\", type: \"byte\" },\n { name: \"field1f\", type: \"byte\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n { name: \"field27\", type: \"byte\" },\n ],\n },\n SetTime2: {\n opcode: 100,\n request: [\n { name: \"is24Hour\", type: \"byte\" },\n { name: \"hour\", type: \"byte\" },\n { name: \"minute\", type: \"byte\" },\n { name: \"second\", type: \"byte\" },\n // ignored on a 24-hour clock\n {\n name: \"amPm\",\n type: \"string\",\n maxLength: 9,\n values: [\"AM\", \"PM\"],\n },\n ],\n },\n SetDateTime: {\n opcode: 101,\n caveat: {\n effect:\n \"is acknowledged but the clock does not move; SetTime2 and SetDate together set everything this takes\",\n alternative: \"SetTime2\",\n },\n request: [\n // stored as two bytes, century and year within the century\n { name: \"year\", type: \"int\" },\n { name: \"month\", type: \"byte\" },\n { name: \"day\", type: \"byte\" },\n { name: \"is24Hour\", type: \"byte\" },\n { name: \"hour\", type: \"byte\" },\n { name: \"minute\", type: \"byte\" },\n // ignored on a 24-hour clock\n {\n name: \"amPm\",\n type: \"string\",\n maxLength: 9,\n values: [\"AM\", \"PM\"],\n },\n ],\n },\n GetDateTime: {\n read: true,\n opcode: 102,\n request: [],\n response: {\n name: \"GetDateTimeRsp\",\n opcode: 1102,\n parameters: [\n { name: \"year\", dataType: \"int\" },\n { name: \"month\", dataType: \"int\" },\n { name: \"day\", dataType: \"int\" },\n { name: \"format\", dataType: \"bool\" },\n { name: \"hour\", dataType: \"int\" },\n { name: \"minute\", dataType: \"int\" },\n { name: \"amPm\", dataType: \"string\" },\n ],\n },\n },\n SetDate: {\n opcode: 103,\n request: [\n // stored as two bytes, century and year within the century\n { name: \"year\", type: \"int\" },\n { name: \"month\", type: \"byte\" },\n { name: \"day\", type: \"byte\" },\n ],\n caveat: {\n effect:\n \"ends every schedule window in progress and rebooks each daily schedule from the new date, so a day moved back to runs no schedule until each is edited or re-enabled\",\n },\n },\n GetDate: {\n read: true,\n opcode: 104,\n request: [],\n response: {\n name: \"GetDateRsp\",\n opcode: 1104,\n parameters: [\n { name: \"year\", dataType: \"int\" },\n { name: \"month\", dataType: \"int\" },\n { name: \"day\", dataType: \"int\" },\n ],\n },\n },\n SetTime: {\n opcode: 105,\n request: [\n { name: \"is24Hour\", type: \"byte\" },\n { name: \"hour\", type: \"byte\" },\n { name: \"minute\", type: \"byte\" },\n // ignored on a 24-hour clock\n {\n name: \"amPm\",\n type: \"string\",\n maxLength: 9,\n values: [\"AM\", \"PM\"],\n },\n ],\n },\n GetTime: {\n read: true,\n opcode: 106,\n request: [],\n response: {\n name: \"GetTimeRsp\",\n opcode: 1106,\n parameters: [\n { name: \"format\", dataType: \"bool\" },\n { name: \"hour\", dataType: \"int\" },\n { name: \"minute\", dataType: \"int\" },\n { name: \"amPm\", dataType: \"string\" },\n ],\n },\n },\n SetBackLight: {\n opcode: 107,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetBackLight: {\n read: true,\n opcode: 108,\n request: [],\n response: {\n name: \"GetBackLightRsp\",\n opcode: 1108,\n parameters: [{ name: \"state\", dataType: \"bool\" }],\n },\n },\n SetBackLightBrightness: {\n opcode: 109,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetBackLightBrightness: {\n read: true,\n opcode: 110,\n request: [],\n response: {\n name: \"GetBackLightBrightnessRsp\",\n opcode: 1110,\n parameters: [{ name: \"brightness\", dataType: \"int\" }],\n },\n },\n SetBackLightTimeout: {\n opcode: 111,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetBackLightTimeout: {\n read: true,\n opcode: 112,\n request: [],\n response: {\n name: \"GetBackLightTimeoutRsp\",\n opcode: 1112,\n parameters: [{ name: \"timeout\", dataType: \"int\", unit: \"second\" }],\n },\n },\n SetBeeper: {\n opcode: 113,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetBeeper: {\n read: true,\n opcode: 114,\n request: [],\n response: {\n name: \"GetBeeperRsp\",\n opcode: 1114,\n parameters: [{ name: \"enabled\", dataType: \"bool\" }],\n },\n },\n SetTimeFormat: {\n opcode: 115,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetTimeFormat: {\n read: true,\n opcode: 116,\n request: [],\n response: {\n name: \"GetTimeFormatRsp\",\n opcode: 1116,\n parameters: [{ name: \"format\", dataType: \"int\" }],\n },\n },\n SetUnits: {\n opcode: 117,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetUnits: {\n read: true,\n opcode: 118,\n request: [],\n response: {\n name: \"GetUnitsRsp\",\n opcode: 1118,\n parameters: [{ name: \"unitFormat\", dataType: \"bool\" }],\n },\n },\n SetVSPSpeedFormat: {\n opcode: 119,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetVSPSpeedFormat: {\n read: true,\n opcode: 120,\n request: [],\n response: {\n name: \"GetVSPSpeedFormatRsp\",\n opcode: 1120,\n parameters: [{ name: \"format\", dataType: \"bool\" }],\n },\n },\n SetCHLOREnable: {\n opcode: 121,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetCHLOREnable: {\n read: true,\n opcode: 122,\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetCHLOREnableRsp\",\n opcode: 1122,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetCHLORDisplay: {\n opcode: 123,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetCHLORDisplay: {\n read: true,\n opcode: 124,\n request: [],\n response: {\n name: \"GetCHLORDisplayRsp\",\n opcode: 1124,\n parameters: [{ name: \"enabled\", dataType: \"bool\" }],\n },\n },\n SetSpaSpilloverEnable: {\n opcode: 127,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetSpaSpilloverEnable: {\n read: true,\n opcode: 128,\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetSpaSpilloverEnableRsp\",\n opcode: 1128,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetFilterOperation: {\n opcode: 129,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFilterOperation: {\n read: true,\n opcode: 130,\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFilterOperationRsp\",\n opcode: 1130,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"operation\", dataType: \"int\" },\n ],\n },\n },\n SetFilterOffValveChg: {\n opcode: 131,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFilterOffValveChg: {\n read: true,\n opcode: 132,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFilterOffValveChgRsp\",\n opcode: 1132,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetFilterLowSpeed: {\n opcode: 133,\n requires: [\"filter\", \"filter.vsp\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFilterLowSpeed: {\n read: true,\n opcode: 134,\n requires: [\"filter\", \"filter.vsp\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetFilterLowSpeedRsp\",\n opcode: 1134,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n // the minimum speed whatever the speed format\n { name: \"speed\", dataType: \"int\" },\n ],\n },\n },\n SetFilterHighSpeed: {\n opcode: 135,\n requires: [\"filter\", \"filter.vsp\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFilterHighSpeed: {\n read: true,\n opcode: 136,\n requires: [\"filter\", \"filter.vsp\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetFilterHighSpeedRsp\",\n opcode: 1136,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n // the maximum speed whatever the speed format\n { name: \"speed\", dataType: \"int\" },\n ],\n },\n },\n SetFreezeProtect: {\n opcode: 137,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFreezeProtect: {\n read: true,\n opcode: 138,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFreezeProtectRsp\",\n opcode: 1138,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetFreezeProtectSpeed: {\n opcode: 139,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFreezeProtectSpeed: {\n read: true,\n opcode: 140,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFreezeProtectSpeedRsp\",\n opcode: 1140,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"speed\", dataType: \"int\", unit: \"RPM\" },\n ],\n },\n },\n SetFreezeProtectTemp: {\n opcode: 141,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFreezeProtectTemp: {\n read: true,\n opcode: 142,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFreezeProtectTempRsp\",\n opcode: 1142,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"temp\", dataType: \"int\", unit: \"F\" },\n ],\n },\n },\n SetFlowMonitor: {\n opcode: 143,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFlowMonitor: {\n read: true,\n opcode: 144,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFlowMonitorRsp\",\n opcode: 1144,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetExternalInterLock: {\n opcode: 145,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"field1c\", type: \"byte\" },\n { name: \"field1d\", type: \"byte\" },\n { name: \"field1e\", type: \"byte\" },\n { name: \"field1f\", type: \"byte\" },\n { name: \"field20\", type: \"int\" },\n { name: \"field24\", type: \"int\" },\n ],\n },\n GetExternalInterLock: {\n read: true,\n opcode: 146,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n // zero-based index into the equipment's interlock list, one past the count silently ignored\n { name: \"data\", type: \"int\" },\n ],\n },\n SetHeaterEnable: {\n opcode: 147,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterEnable: {\n read: true,\n opcode: 148,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterEnableRsp\",\n opcode: 1148,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetHeaterCoolDown: {\n opcode: 149,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterCoolDown: {\n read: true,\n opcode: 150,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterCoolDownRsp\",\n opcode: 1150,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetHeaterExtend: {\n opcode: 151,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterExtend: {\n read: true,\n opcode: 152,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterExtendRsp\",\n opcode: 1152,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetHeaterAllowedLowSpeed: {\n opcode: 153,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterAllowedLowSpeed: {\n read: true,\n opcode: 154,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterAllowedLowSpeedRsp\",\n opcode: 1154,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n // the appliance id, not the thermostat's\n { name: \"heaterId\", dataType: \"int\" },\n // the allow-low-speed flag\n { name: \"speed\", dataType: \"int\", unit: \"RPM\" },\n ],\n },\n },\n SetCHLORParams: {\n opcode: 155,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n // a byte code the config does not carry\n { name: \"cfgState\", type: \"byte\" },\n { name: \"opMode\", type: \"byte\" },\n // a byte code the config does not carry\n { name: \"bowType\", type: \"byte\" },\n // a byte code the config does not carry\n { name: \"cellType\", type: \"byte\" },\n { name: \"timedPercent\", type: \"byte\" },\n { name: \"scTimeout\", type: \"byte\" },\n { name: \"orpTimeout\", type: \"byte\" },\n ],\n },\n GetCHLORParams: {\n read: true,\n opcode: 156,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCHLORParamsRsp\",\n opcode: 1156,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"cfgState\", dataType: \"byte\" },\n { name: \"opMode\", dataType: \"byte\" },\n { name: \"bowType\", dataType: \"byte\" },\n { name: \"cellType\", dataType: \"byte\" },\n { name: \"timedPercent\", dataType: \"byte\" },\n { name: \"scTimeout\", dataType: \"byte\", unit: \"hour\" },\n { name: \"orpTimeout\", dataType: \"byte\", unit: \"hour\" },\n ],\n },\n },\n GetCHLORStatus: {\n opcode: 157,\n read: true,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n target: \"chlorinator.cell\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCHLORStatusRsp\",\n opcode: 1157,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"opState\", dataType: \"byte\" },\n { name: \"scState\", dataType: \"byte\" },\n { name: \"alertStatus\", dataType: \"byte\" },\n { name: \"instantSaltHigh\", dataType: \"byte\" },\n { name: \"instantSaltLow\", dataType: \"byte\" },\n { name: \"averageSaltHigh\", dataType: \"byte\" },\n { name: \"averageSaltLow\", dataType: \"byte\" },\n { name: \"activelyDispensing\", dataType: \"byte\" },\n ],\n },\n },\n GetCHLORAlert: {\n opcode: 158,\n read: true,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n target: \"chlorinator.cell\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCHLORAlertRsp\",\n opcode: 1158,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"alertHighByte\", dataType: \"byte\" },\n { name: \"alertLowByte\", dataType: \"byte\" },\n ],\n },\n },\n GetCHLORError: {\n opcode: 159,\n read: true,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n target: \"chlorinator.cell\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCHLORErrorRsp\",\n opcode: 1159,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"errorHighByte\", dataType: \"byte\" },\n { name: \"errorLowByte\", dataType: \"byte\" },\n ],\n },\n },\n CHLORSaltCalcRestart: {\n opcode: 160,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n CHLORRelayPolarityReverse: {\n opcode: 161,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n CHLORCellRuntimeRestart: {\n opcode: 162,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetCHLORMeasurement: {\n opcode: 163,\n read: true,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n target: \"chlorinator.cell\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n // byte pairs are big-endian u16 (high * 256 + low): salt in ppm, the rest ADC counts\n response: {\n name: \"GetCHLORMeasurementRsp\",\n opcode: 1163,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"voltageHighByte\", dataType: \"byte\" },\n { name: \"voltageLowByte\", dataType: \"byte\" },\n { name: \"currentHighByte\", dataType: \"byte\" },\n { name: \"currentLowByte\", dataType: \"byte\" },\n { name: \"cellTempHighByte\", dataType: \"byte\" },\n { name: \"cellTempLowByte\", dataType: \"byte\" },\n { name: \"boardTempHighByte\", dataType: \"byte\" },\n { name: \"boardTempLowByte\", dataType: \"byte\" },\n { name: \"instantSaltLevelHighByte\", dataType: \"byte\" },\n { name: \"instantSaltLevelLowByte\", dataType: \"byte\" },\n { name: \"averageSaltLevelHighByte\", dataType: \"byte\" },\n { name: \"averageSaltLevelLowByte\", dataType: \"byte\" },\n ],\n },\n },\n SetUIEquipmentCmd: {\n opcode: 164,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n // a filter speed for a filter, 0/1 for everything else\n { name: \"isOn\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n GetScVersionCmd: {\n opcode: 167,\n read: true,\n request: [\n // a bus address, never 0\n { name: \"data\", type: \"int\" },\n ],\n response: {\n name: \"GetScVersionRsp\",\n opcode: 1167,\n parameters: [\n { name: \"stageMajor\", dataType: \"byte\" },\n { name: \"minorRev\", dataType: \"byte\" },\n { name: \"incremRev\", dataType: \"byte\" },\n { name: \"specRev1\", dataType: \"byte\" },\n { name: \"specRev2\", dataType: \"byte\" },\n { name: \"specRev3\", dataType: \"byte\" },\n ],\n },\n },\n SetScLedCmd: {\n opcode: 168,\n request: [\n { name: \"data\", type: \"int\" },\n { name: \"field1c\", type: \"int\" },\n ],\n },\n SetCHLORTimePercent: {\n opcode: 172,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetCHLORRelayPolarity: {\n opcode: 174,\n read: true,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n target: \"chlorinator.cell\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCHLORRelayPolarityRsp\",\n opcode: 1174,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"relaySetting\", dataType: \"byte\" },\n ],\n },\n },\n GetUICLLightStatus: {\n read: true,\n opcode: 199,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUICLLightStatusRsp\",\n opcode: 1199,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"colorLogicId\", dataType: \"int\" },\n { name: \"lightState\", dataType: \"byte\" },\n { name: \"whyLightIsOn\", dataType: \"byte\" },\n { name: \"currentShow\", dataType: \"byte\" },\n { name: \"speed\", dataType: \"byte\" },\n { name: \"brightness\", dataType: \"byte\" },\n { name: \"specialEffect\", dataType: \"byte\" },\n ],\n },\n },\n GetUICLIMStatus: {\n read: true,\n opcode: 200,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetCLSerialIdentifyStart: {\n opcode: 201,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLSerialIdentifyStop: {\n opcode: 202,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetUICLIMAuthenticate: {\n read: true,\n opcode: 203,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLIMUnlock: {\n opcode: 204,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetNetworkedLightStatus: {\n read: true,\n opcode: 205,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumAssignSeqStandard: {\n opcode: 206,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumAssignSeqCustom: {\n opcode: 207,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumAssignSeqStationary: {\n opcode: 208,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumUnassignAux: {\n opcode: 209,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumIdentifyStart: {\n opcode: 210,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumIdentifyStop: {\n opcode: 211,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxLightOnOff: {\n opcode: 212,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxUpdateSettingStationary: {\n opcode: 213,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxUpdateSettingStandard: {\n opcode: 214,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxUpdateSettingCustom: {\n opcode: 215,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxUpdateBrightness: {\n opcode: 216,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxRelease: {\n opcode: 217,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAllFindLightsStart: {\n opcode: 218,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAllFindLightsStop: {\n opcode: 219,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetUICLAllFindLightsReport: {\n read: true,\n opcode: 220,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAllResetToDefaults: {\n opcode: 221,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAllOnWhite: {\n opcode: 222,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetLightMode: {\n opcode: 223,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n IDV2Light: {\n opcode: 224,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetV2Mode: {\n opcode: 225,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetLightModeByRelay: {\n opcode: 226,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"field1c\", type: \"int\" },\n ],\n },\n SetV2ModeByRelay: {\n opcode: 227,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n CreateUIScheduleAltCmd: {\n opcode: 229,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"event\", type: \"int\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"enabled\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n CreateUIScheduleCmd: {\n opcode: 230,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n // the opcode the scheduler replays: 164 SetUIEquipmentCmd, 311 SetUISpilloverCmd, 317 RunGroupCmd\n { name: \"event\", type: \"int\" },\n { name: \"startHour\", type: \"byte\" },\n { name: \"startMinute\", type: \"byte\" },\n { name: \"endHour\", type: \"byte\" },\n { name: \"endMinute\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"enabled\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n DeleteUIScheduleCmd: {\n opcode: 231,\n request: [{ name: \"scheduleId\", type: \"int\" }],\n },\n SetUIScheduleEnableCmd: {\n opcode: 232,\n request: [\n { name: \"scheduleId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n // replaces the whole schedule\n EditUIScheduleCmd: {\n opcode: 233,\n request: [\n { name: \"scheduleId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n // the replayed opcode, as on CreateUIScheduleCmd\n { name: \"event\", type: \"int\" },\n { name: \"startHour\", type: \"byte\" },\n { name: \"startMinute\", type: \"byte\" },\n { name: \"endHour\", type: \"byte\" },\n { name: \"endMinute\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"enabled\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n EditUIScheduleAltCmd: {\n opcode: 234,\n request: [\n { name: \"scheduleId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"event\", type: \"int\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"enabled\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n UIGetCSADForcedOnTimeout: {\n read: true,\n opcode: 246,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADForcedOnTimeout: {\n opcode: 247,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n UIGetCSADAutoTimeout: {\n read: true,\n opcode: 248,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADAutoTimeout: {\n opcode: 249,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n UIGetCSADStatus: {\n read: true,\n opcode: 250,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIGetCSADStatusRsp\",\n opcode: 1250,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"csadid\", dataType: \"int\" },\n { name: \"ph\", dataType: \"float\" },\n { name: \"orp\", dataType: \"int\" },\n ],\n },\n },\n UIGetCSADRevision: {\n read: true,\n opcode: 251,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UIGetCSADTargetValue: {\n read: true,\n opcode: 252,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADTargetValue: {\n opcode: 253,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"targetValue\", type: \"float\" },\n ],\n },\n UIGetCSADPHAlarmLevel: {\n read: true,\n opcode: 256,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADPHAlarmLevel: {\n opcode: 257,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"float\" },\n { name: \"field1c\", type: \"float\" },\n ],\n },\n UIGetCSADEnabled: {\n read: true,\n opcode: 258,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADEnabled: {\n opcode: 259,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n UIGetCSADExtendEnabled: {\n read: true,\n opcode: 262,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADExtendEnabled: {\n opcode: 263,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n UIGetCSADType: {\n read: true,\n opcode: 264,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADType: {\n opcode: 265,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n UIGetCSADMode: {\n read: true,\n opcode: 266,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADMode: {\n opcode: 267,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n SetUISystemStateCmd: {\n opcode: 268,\n request: [\n // 0 off, 1 on, 2 service, 3 config, 4 timed service\n { name: \"data\", type: \"int\" },\n // the timed minutes\n { name: \"field1c\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"int\" },\n ],\n },\n GetUISuperCHLORTimeRemaining: {\n read: true,\n opcode: 270,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUISuperCHLORTimeRemainingRsp\",\n opcode: 1270,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"superChlorTimeRemaining\", dataType: \"int\" },\n ],\n },\n },\n UIGetCSADCalibrationValue: {\n read: true,\n opcode: 274,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADCalibrationValue: {\n opcode: 275,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"calibrationValue\", type: \"float\" },\n ],\n },\n // the service or config state, answered with no opcode + 1000 reply\n GetUISystemStateCmd: {\n read: true,\n opcode: 278,\n request: [],\n },\n SetUICHLOROperatingMode: {\n opcode: 279,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUICHLOROperatingMode: {\n read: true,\n opcode: 280,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUICHLOROperatingModeRsp\",\n opcode: 1280,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"operatingMode\", dataType: \"int\" },\n ],\n },\n },\n SetUICSADORPTargetLevel: {\n opcode: 281,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUICSADORPTargetLevel: {\n read: true,\n opcode: 282,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICSADORPAlarmLevel: {\n opcode: 283,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"field1c\", type: \"int\" },\n ],\n },\n GetUICSADORPAlarmLevel: {\n read: true,\n opcode: 284,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUIMultiHeaterPriorityCmd: {\n opcode: 289,\n requires: [\"heater\"],\n // the body's heat sources by appliance id, first priority first\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"rank1\", type: \"int\" },\n { name: \"rank2\", type: \"int\" },\n { name: \"rank3\", type: \"int\" },\n { name: \"rank4\", type: \"int\" },\n { name: \"rank5\", type: \"int\" },\n ],\n },\n SetChlorinatorScheduleCmd: {\n opcode: 290,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n caveat: {\n effect:\n \"sets a chlorinator percent override the firmware never clears on its own: the effective percent sticks, surviving even a restart, and masks later percent writes until RestoreChlorinatorPercentCmd clears it\",\n alternative: \"SetCHLORTimePercent\",\n },\n },\n RestoreChlorinatorPercentCmd: {\n opcode: 291,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"exists only to clear the percent override SetChlorinatorScheduleCmd leaves behind, and has no other use\",\n alternative: \"SetCHLORTimePercent\",\n },\n },\n ClearUIAlarmCmd: {\n opcode: 303,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIFilterStatus: {\n read: true,\n opcode: 306,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUIFilterStatusRsp\",\n opcode: 1306,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n { name: \"filterSpeed\", dataType: \"int\" },\n { name: \"filterState\", dataType: \"int\" },\n { name: \"whyFilterIsOn\", dataType: \"int\" },\n { name: \"valvePosition\", dataType: \"int\" },\n ],\n },\n },\n GetUIHeaterStatus: {\n read: true,\n opcode: 307,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUIHeaterStatusRsp\",\n opcode: 1307,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"isHeaterIsOn\", dataType: \"byte\" },\n { name: \"whyHeaterIsOn\", dataType: \"byte\" },\n { name: \"currentTemp\", dataType: \"byte\" },\n { name: \"setTemp\", dataType: \"byte\" },\n ],\n },\n },\n SetStandAloneLightShow: {\n opcode: 308,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n ResetStandAloneLight: {\n opcode: 309,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetStandAloneLightShow: {\n read: true,\n opcode: 310,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetStandAloneLightShowRsp\",\n opcode: 1310,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"lightId\", dataType: \"int\" },\n { name: \"show\", dataType: \"int\" },\n { name: \"speed\", dataType: \"int\" },\n { name: \"brightness\", dataType: \"int\" },\n { name: \"specialEffect\", dataType: \"int\" },\n ],\n },\n },\n SetUISpilloverCmd: {\n opcode: 311,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n caveat: {\n effect:\n \"moves the return valve. On some installs it is plumbed the other way around, so turning spillover on has the opposite effect and stops it\",\n },\n },\n GetUIPumpStatus: {\n read: true,\n opcode: 312,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetHeaterScheduleAltCmd: {\n opcode: 314,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n SetHeaterScheduleCmd: {\n opcode: 315,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n RestoreHeaterSetPointCmd: {\n opcode: 316,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n RunGroupCmd: {\n settle: true,\n opcode: 317,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n SaveNewGroupCmd: {\n settle: true,\n opcode: 318,\n request: [\n { name: \"name\", type: \"string\", maxLength: 12 },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n { name: \"poolId\", type: \"int\" },\n ],\n },\n SaveExistingGroupCmd: {\n opcode: 319,\n request: [{ name: \"equipmentId\", type: \"int\" }],\n },\n DeleteGroupCmd: {\n settle: true,\n opcode: 320,\n request: [{ name: \"equipmentId\", type: \"int\" }],\n },\n SetGroupCmd: {\n opcode: 321,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"name\", type: \"string\", maxLength: 12 },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n { name: \"poolId\", type: \"int\" },\n ],\n },\n TurnOnOffForGroup: {\n opcode: 322,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n // optional, 0 when absent\n { name: \"field1c\", type: \"int\" },\n ],\n },\n CreateUIFavoriteAltCmd: {\n opcode: 324,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n ],\n },\n CreateUIFavoriteCmd: {\n opcode: 325,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n DeleteUIFavoriteCmd: {\n opcode: 326,\n request: [{ name: \"data\", type: \"int\" }],\n },\n ModifyUIFavoriteCmd: {\n opcode: 327,\n request: [{ name: \"data\", type: \"int\" }],\n caveat: {\n effect: \"is acknowledged but does nothing\",\n alternative: \"DeleteUIFavoriteCmd\",\n },\n },\n UpdateButtonOnTerm: {\n opcode: 328,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"field1c\", type: \"int\" },\n { name: \"field20\", type: \"int\" },\n ],\n },\n GetRemainingCountdownTime: {\n read: true,\n opcode: 330,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetRemainingCountdownTimeRsp\",\n opcode: 1330,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"hour\", dataType: \"byte\" },\n { name: \"minute\", dataType: \"byte\" },\n { name: \"second\", dataType: \"byte\" },\n ],\n },\n },\n GetRemainingSCTime: {\n read: true,\n opcode: 331,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UiEditConfigObjectName: {\n opcode: 332,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"name\", type: \"string\", maxLength: 13 },\n ],\n },\n UiGetConfigObjectName: {\n read: true,\n opcode: 333,\n request: [{ name: \"equipmentId\", type: \"int\" }],\n response: {\n name: \"UiGetConfigObjectNameRsp\",\n opcode: 1333,\n parameters: [\n { name: \"systemId\", dataType: \"int\" },\n { name: \"name\", dataType: \"string\" },\n ],\n },\n },\n SetSolarScheduleCmd: {\n opcode: 334,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n RestoreSolarSetPointCmd: {\n opcode: 335,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n RestoreIdleState: {\n opcode: 340,\n request: [],\n },\n SetDemandResponseCmd: {\n opcode: 341,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n SetPrimingDuration: {\n opcode: 350,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetPrimingDuration: {\n read: true,\n opcode: 351,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetPrimingDurationRsp\",\n opcode: 1351,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"duration\", dataType: \"int\" },\n ],\n },\n },\n SetCooldownDuration: {\n opcode: 352,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetCooldownDuration: {\n read: true,\n opcode: 353,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCooldownDurationRsp\",\n opcode: 1353,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"duration\", dataType: \"int\" },\n ],\n },\n },\n SetSharedFilterTimeout: {\n opcode: 354,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetSharedFilterTimeout: {\n read: true,\n opcode: 355,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetSharedFilterTimeoutRsp\",\n opcode: 1355,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"timeout\", dataType: \"int\" },\n ],\n },\n },\n SetHeaterAllowLowSpeed: {\n opcode: 356,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterAllowLowSpeed: {\n read: true,\n opcode: 357,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterAllowLowSpeedRsp\",\n opcode: 1357,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n // the appliance id, not the thermostat's\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetHeaterLowSpeed: {\n opcode: 358,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterLowSpeed: {\n read: true,\n opcode: 359,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterLowSpeedRsp\",\n opcode: 1359,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n // the appliance id, not the thermostat's\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"speed\", dataType: \"int\", unit: \"percent\" },\n ],\n },\n },\n SetUITestModeEnter: {\n opcode: 361,\n request: [],\n },\n SetUIDisplayModeState: {\n opcode: 378,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetUIDisplayModeState: {\n read: true,\n opcode: 379,\n request: [],\n response: {\n name: \"GetUIDisplayModeStateRsp\",\n // not opcode + 1000\n opcode: 1368,\n parameters: [{ name: \"state\", dataType: \"string\" }],\n },\n },\n SetUIPumpSpeed: {\n opcode: 380,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIPumpSpeed: {\n read: true,\n opcode: 381,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUIFreezeProtectOverride: {\n opcode: 382,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIFreezeProtectOverride: {\n read: true,\n opcode: 383,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIFreezeProtectOverrideRsp\",\n // not opcode + 1000\n opcode: 1370,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetUIFreezeProtectOverrideInterval: {\n opcode: 384,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIFreezeProtectOverrideInterval: {\n read: true,\n opcode: 385,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIFreezeProtectOverrideIntervalRsp\",\n // not opcode + 1000\n opcode: 1371,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n { name: \"interval\", dataType: \"int\" },\n ],\n },\n },\n // power in BCD watts, revisions in ASCII\n GetUIFilterDiagnosticInfo: {\n read: true,\n opcode: 386,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUIFilterDiagnosticInfoRsp\",\n opcode: 1386,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"powerLsb\", dataType: \"byte\" },\n { name: \"powerMsb\", dataType: \"byte\" },\n { name: \"errorStatus\", dataType: \"byte\" },\n { name: \"displayFwRevisionB1\", dataType: \"byte\" },\n { name: \"displayFwRevisionB2\", dataType: \"byte\" },\n { name: \"displayFwRevisionB3\", dataType: \"byte\" },\n { name: \"displayFwRevisionB4\", dataType: \"byte\" },\n { name: \"displayFwRevisionB5\", dataType: \"byte\" },\n { name: \"displayFwRevisionB6\", dataType: \"byte\" },\n { name: \"driveFwRevisionB1\", dataType: \"byte\" },\n { name: \"driveFwRevisionB2\", dataType: \"byte\" },\n { name: \"driveFwRevisionB3\", dataType: \"byte\" },\n { name: \"driveFwRevisionB4\", dataType: \"byte\" },\n { name: \"driveFwRevisionB5\", dataType: \"byte\" },\n { name: \"driveFwRevisionB6\", dataType: \"byte\" },\n ],\n },\n },\n SetUITemporaryHeaterEnable: {\n opcode: 400,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n SetUITemporaryHeaterPriorityCmd: {\n opcode: 401,\n requires: [\"heater\"],\n // the body's heat sources by appliance id, first priority first\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"rank1\", type: \"int\" },\n { name: \"rank2\", type: \"int\" },\n { name: \"rank3\", type: \"int\" },\n { name: \"rank4\", type: \"int\" },\n { name: \"rank5\", type: \"int\" },\n ],\n },\n SetUITemporaryHeaterMaintainPriorityCmd: {\n opcode: 402,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"field1c\", type: \"byte\" },\n ],\n },\n SetCoordinates: {\n opcode: 416,\n request: [\n { name: \"latitude\", type: \"float\" },\n { name: \"longitude\", type: \"float\" },\n ],\n },\n GetCoordinates: {\n read: true,\n opcode: 417,\n request: [],\n response: {\n name: \"GetCoordinatesRsp\",\n opcode: 1417,\n parameters: [\n { name: \"latitude\", dataType: \"float\" },\n { name: \"longitude\", dataType: \"float\" },\n ],\n },\n },\n Unknown1414: {\n opcode: 1414,\n request: [],\n caveat: {\n effect:\n \"is acknowledged and then ignored: the controller does nothing with it and sends no reply\",\n },\n },\n});\n\nexport type CommandName = keyof typeof SPEC;\n\nexport type CommandOpcode = (typeof SPEC)[CommandName][\"opcode\"];\n\n// the three fetches, sent with no parameters and answered without an opcode + 1000 reply\nexport const SWITCH_OPCODE = {\n RequestConfiguration: 1,\n GetTelemetry: 300,\n GetSysInfo: 411,\n} as const;\n\nexport const COMMANDS: Record<\n CommandName,\n Omit<CommandSpec<CommandName>, \"opcode\"> & { opcode: CommandOpcode }\n> = SPEC;\n\ntype ParamValue<P> = P extends { values: (infer V)[] }\n ? V\n : P extends { type: \"string\" }\n ? string\n : number;\n\nexport type CommandParams<K extends CommandName> =\n (typeof SPEC)[K][\"request\"] extends (infer P extends CommandRequestParam)[]\n ? { [Q in P as Q[\"name\"]]: ParamValue<Q> }\n : Record<string, never>;\n\ntype ResultValue<D> = D extends \"bool\"\n ? boolean\n : D extends \"string\"\n ? string\n : number;\n\nexport type CommandResult<K extends CommandName> = (typeof SPEC)[K] extends {\n response: {\n parameters: (infer P extends CommandResponseParam)[];\n };\n}\n ? { [Q in P as Q[\"name\"]]: ResultValue<Q[\"dataType\"]> }\n : void;\n","export const FILTER_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"On\",\n 2: \"Priming\",\n 3: \"Waiting To Turn Off\",\n 4: \"Waiting To Turn Off (Manual)\",\n 5: \"Heater Extend\",\n 6: \"Cooldown\",\n 7: \"Suspend\",\n 8: \"CSAD Extend\",\n 9: \"Superchlorinate\",\n 10: \"Force Priming\",\n 11: \"Waiting For Pump To Turn Off\",\n 12: \"Waiting To Change Valves\",\n};\n\n// why a pump other than the filter pump is running\nexport const PUMP_WHY_ON: Record<number, string> = {\n 0: \"No Message\",\n 1: \"Freeze Protect\",\n 2: \"Interlock\",\n 3: \"Group On\",\n 4: \"Group Off\",\n 5: \"Manual Off\",\n 6: \"Countdown Done\",\n 7: \"End Schedule\",\n 8: \"Manual On\",\n 9: \"Countdown Timer\",\n 10: \"Schedule On\",\n};\n\nexport const PUMP_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"On\",\n 2: \"On (Freeze Protect)\",\n 3: \"Off (Valves Changing)\",\n 4: \"Priming\",\n // the firmware names no state 5\n 6: \"Waiting For Interlock\",\n 7: \"Paused\",\n};\n\nexport const SPEED_PRESET: Record<number, string> = {\n 0: \"Low\",\n 1: \"Medium\",\n 2: \"High\",\n};\n\nexport const FILTER_VALVE_POSITION: Record<number, string> = {\n 1: \"Pool Only\",\n 2: \"Spa Only\",\n 3: \"Spillover\",\n 4: \"Low Priority Heat\",\n 5: \"High Priority Heat\",\n};\n\nexport const FILTER_WHY_ON: Record<number, string> = {\n 0: \"Off\",\n 1: \"No Water Flow\",\n 2: \"Cooldown\",\n 3: \"CSAD Extend\",\n 4: \"Heater Extend\",\n 5: \"Pause\",\n 6: \"Off (Valve Changing)\",\n 7: \"Force High Speed\",\n 8: \"External Interlock\",\n 9: \"Superchlorinate\",\n 10: \"Countdown Timer\",\n 11: \"Manual On\",\n 12: \"Manual Spillover\",\n 13: \"Timed Spillover\",\n 14: \"Timed Event\",\n 15: \"Freeze Protect\",\n 16: \"Set Pool/Spa/Spillover\",\n 17: \"Spillover Countdown Timer\",\n 18: \"Group Command\",\n 19: \"Spillover Interlock\",\n 20: \"Max Value\",\n};\n\nexport const LIGHT_SPEED: Record<number, string> = {\n 0: \"1/16x\",\n 1: \"1/8x\",\n 2: \"1/4x\",\n 3: \"1/2x\",\n 4: \"1x\",\n 5: \"2x\",\n 6: \"4x\",\n 7: \"8x\",\n 8: \"16x\",\n};\n\nexport const LIGHT_BRIGHTNESS: Record<number, number> = {\n 0: 20,\n 1: 40,\n 2: 60,\n 3: 80,\n 4: 100,\n};\n\nexport const SYSTEM_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"On\",\n 2: \"Service Mode\",\n 3: \"Config Mode\",\n 4: \"Timed Service Mode\",\n};\n\n// the backyard is On\nexport const isRunning = (state: number) => state === 1;\n\nexport const HEATER_MODE: Record<number, string> = {\n 0: \"Heat\",\n 1: \"Cool\",\n 2: \"Auto\",\n 3: \"Off\",\n};\n\n// what the chemistry module is doing with the pH reducer\nexport const CSAD_MODE: Record<number, string> = {\n 0: \"Off\",\n 1: \"Auto\",\n 2: \"Forced On\",\n 3: \"Monitoring\",\n 4: \"Dispense Off\",\n};\n\n// the rank an appliance takes among a body's heat sources\nexport const HEATER_PRIORITY: Record<number, string> = {\n 0: \"Priority 1\",\n 1: \"Priority 2\",\n 2: \"Priority 3\",\n 3: \"Priority 4\",\n 4: \"Priority 5\",\n // not a rank, but the panel setting that puts solar ahead of everything\n 254: \"Solar First\",\n};\n\nexport const HEATER_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"On\",\n 2: \"Pause\",\n 3: \"Cool Down\",\n};\n\nexport const CHLORINATOR_OP_MODE: Record<number, string> = {\n 0: \"Not Config\",\n 1: \"Timed\",\n 2: \"ORP Auto\",\n};\n\nexport const CHLORINATOR_OPERATING_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"Paused\",\n 2: \"Generating\",\n};\n\nexport const CHLORINATOR_STATUS: Record<number, string> = {\n 1: \"Error Present\",\n 2: \"Alert Present\",\n 4: \"Generating\",\n 8: \"System Paused\",\n 16: \"Local Paused\",\n 32: \"Authenticated\",\n 64: \"K1 Active\",\n 128: \"K2 Active\",\n};\n\n// a word packed as fields from bit 0 up\nexport type PackedField = {\n // bits\n width: number;\n values: Record<number, string>;\n};\n\nexport const CHLORINATOR_ALERTS: PackedField[] = [\n {\n width: 2,\n values: {\n 1: \"Low Salt\",\n 2: \"Very Low Salt\",\n },\n },\n {\n width: 1,\n values: {\n 1: \"High Cell Current\",\n },\n },\n {\n width: 1,\n values: {\n 1: \"Low Cell Voltage\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Low Water Temp\",\n 2: \"Water Temp Scaleback\",\n 3: \"High Water Temp\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"High Board Temp\",\n 2: \"Board Temp Clearing\",\n },\n },\n {\n width: 1,\n values: {\n 1: \"ORP Overfeed Timeout\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Superchlorinating\",\n 2: \"Superchlorinate Timeout\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Clean Cell\",\n },\n },\n];\n\nexport const CHLORINATOR_ERRORS: PackedField[] = [\n {\n width: 2,\n values: {\n 1: \"Cell Current Sensor Shorted\",\n 2: \"Cell Current Sensor Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Cell Voltage Sensor Shorted\",\n 2: \"Cell Voltage Sensor Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Cell Temp Sensor Shorted\",\n 2: \"Cell Temp Sensor Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Board Temp Sensor Shorted\",\n 2: \"Board Temp Sensor Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Relay K1 Shorted\",\n 2: \"Relay K1 Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Relay K2 Shorted\",\n 2: \"Relay K2 Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Non-Hayward Cell\",\n 2: \"Cell Authentication Error\",\n },\n },\n];\n\nexport const RELAY_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"On\",\n 2: \"On (Freeze Protect)\",\n 3: \"Waiting For Interlock\",\n 4: \"Paused\",\n 5: \"Waiting For Filter\",\n};\n\nexport const RELAY_WHY_ON: Record<number, string> = {\n 0: \"No Message\",\n 1: \"Manual Off\",\n 2: \"Countdown Done\",\n 3: \"End Schedule\",\n 4: \"Group Off\",\n 5: \"Manual On\",\n 6: \"Countdown Timer\",\n 7: \"Schedule On\",\n 8: \"Group On\",\n 9: \"Freeze Protect\",\n 10: \"Interlock\",\n};\n\nexport const bitmaskNames = (raw: number, map: Record<number, string>) => {\n const names: string[] = [];\n for (const [bit, name] of Object.entries(map)) {\n if ((raw & Number(bit)) !== 0) {\n names.push(name);\n }\n }\n if (names.length > 0) {\n return names.join(\", \");\n }\n return raw === 0 ? \"None\" : \"Unknown\";\n};\n\nexport const packedNames = (raw: number, fields: PackedField[]) => {\n const names: string[] = [];\n let shift = 0;\n for (const field of fields) {\n const value = (raw >> shift) & ((1 << field.width) - 1);\n if (value !== 0) {\n names.push(field.values[value] ?? \"Unknown\");\n }\n shift += field.width;\n }\n return names.length > 0 ? names.join(\", \") : \"None\";\n};\n","// the water temperature while the filter pump is off or the sensor reports nothing\nexport const WATER_TEMP_UNAVAILABLE = -1;\n\n// the air temperature while the backyard sensor is unplugged or faulted\nexport const AIR_TEMP_UNAVAILABLE = -1;\n\n// the heater temperature with no valid reading\nexport const HEATER_TEMP_UNAVAILABLE = 65535;\n\n// the ORP with no reading from the probe\nexport const ORP_UNAVAILABLE = -1;\n\n// the pH with no reading from the probe\nexport const PH_UNAVAILABLE = 0;\n","import { SYSTEM_STATE } from \"@/constants/labels\";\nimport type { Inventory } from \"@/utils/inventory\";\n\nconst stateName = (state: number) => SYSTEM_STATE[state] ?? String(state);\n\nexport class OmniLogicError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"OmniLogicError\";\n }\n}\n\nexport class OmniTimeoutError extends OmniLogicError {\n constructor(message: string) {\n super(message);\n this.name = \"OmniTimeoutError\";\n }\n}\n\nexport class OmniValidationError extends OmniLogicError {\n constructor(message: string) {\n super(message);\n this.name = \"OmniValidationError\";\n }\n}\n\nexport class CommandFailedError extends OmniLogicError {\n command: string;\n attempts: number;\n\n constructor(details: {\n message: string;\n command: string;\n attempts: number;\n cause?: unknown;\n }) {\n super(details.message, { cause: details.cause });\n this.name = \"CommandFailedError\";\n this.command = details.command;\n this.attempts = details.attempts;\n }\n}\n\nexport class ReadingUnavailableError extends OmniLogicError {\n backyardState: number;\n\n constructor(details: { name: string; backyardState: number }) {\n super(\n `\"${details.name}\" telemetry is not reliable while the controller is not in normal operating state (state: ${stateName(details.backyardState)})`,\n );\n this.name = \"ReadingUnavailableError\";\n this.backyardState = details.backyardState;\n }\n}\n\nexport class SystemStateError extends OmniLogicError {\n command: string;\n backyardState: number;\n\n constructor(details: { command: string; backyardState: number }) {\n super(\n `${details.command} refused: the controller must be in a normal operating state (state: ${stateName(details.backyardState)}).\\n\\nPass { force: true } to ignore this error.`,\n );\n this.name = \"SystemStateError\";\n this.command = details.command;\n this.backyardState = details.backyardState;\n }\n}\n\nexport class FirmwareTooOldError extends OmniLogicError {\n version: string;\n minimum: string;\n\n constructor(details: { version: string; minimum: string }) {\n super(\n `This controller reports firmware ${details.version}, below the ${details.minimum} this library was built against, so nothing it sends can be trusted.\\n\\nPass { force: true } to refresh() or command() to ignore this error; fetchTelemetry() works either way.`,\n );\n this.name = \"FirmwareTooOldError\";\n this.version = details.version;\n this.minimum = details.minimum;\n }\n}\n\nexport class EquipmentNotInstalledError extends OmniLogicError {\n command: string;\n requirement: string;\n poolId: number;\n hint: string | undefined;\n inventory: Inventory;\n\n constructor(details: {\n command: string;\n requirement: string;\n poolId: number;\n hint?: string;\n inventory: Inventory;\n }) {\n const why =\n details.hint ??\n (details.requirement === \"body\"\n ? `no body of water with id ${details.poolId}`\n : `${details.requirement} is absent on body ${details.poolId}`);\n super(\n `${details.command} refused: ${why}.\\n\\nPass { force: true } to ignore this error.`,\n );\n this.name = \"EquipmentNotInstalledError\";\n this.command = details.command;\n this.requirement = details.requirement;\n this.poolId = details.poolId;\n this.hint = details.hint;\n this.inventory = details.inventory;\n }\n}\n","export const numberOf = (v: unknown) =>\n typeof v === \"number\" && Number.isFinite(v) ? v : undefined;\n\nexport const stringOf = (v: unknown) =>\n typeof v === \"string\" && v !== \"\" ? v : undefined;\n\nexport const defined = <T extends object>(obj: T) => {\n const out: Partial<T> = {};\n for (const key in obj) {\n if (obj[key] !== undefined) {\n out[key] = obj[key];\n }\n }\n return out;\n};\n\nexport const matches = <E extends object>(\n actual: { [K in keyof E]?: unknown } | undefined,\n expected: E,\n) => {\n if (actual === undefined) {\n return false;\n }\n for (const key in expected) {\n if (actual[key] !== expected[key]) {\n return false;\n }\n }\n return true;\n};\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== \"object\") {\n return false;\n }\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n};\n\nexport const findBySystemId = (\n parent: unknown,\n systemId: number,\n): Record<string, unknown> | undefined => {\n if (!isRecord(parent)) {\n return undefined;\n }\n for (const value of Object.values(parent)) {\n for (const item of Array.isArray(value) ? value : [value]) {\n if (!isRecord(item)) {\n continue;\n }\n if (Number(item.systemId) === systemId) {\n return item;\n }\n const found = findBySystemId(item, systemId);\n if (found !== undefined) {\n return found;\n }\n }\n }\n return undefined;\n};\n","import type { BodyOfWater, MSPConfig } from \"@/types/config\";\nimport { OmniLogicError } from \"@/utils/errors\";\nimport { isRecord, numberOf, stringOf } from \"@/utils/helpers\";\n\nexport type Presence = \"installed\" | \"absent\" | \"unknown\";\n\ntype Slot<T = object> =\n | ({ presence: \"installed\"; systemId: number } & T)\n | { presence: \"absent\" }\n | { presence: \"unknown\" };\n\ntype CellSlot = Slot<{\n cellType: string | undefined;\n feeder: Presence;\n}>;\n\ntype HeaterUnitSlot = Slot<{ heaterType: string | undefined }>;\n\ntype BodyInventory = {\n systemId: number;\n // a pool and spa sharing one filter pump\n spillover: Presence;\n csad: Slot;\n filter: Slot<{ vsp: Presence }>;\n heater: Slot<{\n heaterType: string | undefined;\n gas: Presence;\n unit: HeaterUnitSlot;\n }>;\n chlorinator: Slot<{\n cell: CellSlot;\n }>;\n light: Slot<{ networked: Presence }>;\n blower: Slot;\n};\n\nexport type Inventory = {\n bodies: BodyInventory[];\n};\n\nexport const INVENTORY_PATHS = [\n \"filter\",\n \"filter.vsp\",\n \"heater\",\n \"heater.gas\",\n \"heater.unit\",\n \"chlorinator\",\n \"chlorinator.cell\",\n \"chlorinator.feeder\",\n \"csad\",\n \"light\",\n \"light.networked\",\n \"blower\",\n \"spillover\",\n] as const;\n\nexport type InventoryPath = (typeof INVENTORY_PATHS)[number];\n\nconst unreachablePath = (path: never) => {\n throw new OmniLogicError(`Unhandled inventory path ${String(path)}`);\n};\n\nconst VARIABLE_SPEED_FILTER_TYPES: Set<string> = new Set([\n \"FMT_VARIABLE_SPEED_PUMP\",\n]);\n\nconst SINGLE_SPEED_FILTER_TYPES: Set<string> = new Set([\n \"FMT_SINGLE_SPEED\",\n \"FMT_DUAL_SPEED\",\n]);\n\nconst GAS_HEATER_TYPES: Set<string> = new Set([\"HTR_GAS\", \"HTR_SMART_GAS\"]);\n\nconst OTHER_HEATER_TYPES: Set<string> = new Set([\n \"HTR_HEAT_PUMP\",\n \"HTR_SOLAR\",\n \"HTR_ELECTRIC\",\n \"HTR_GEOTHERMAL\",\n \"HTR_CHILLER\",\n \"HTR_SMART_HEAT_PUMP\",\n \"HTR_SMART_VSHP\",\n]);\n\nexport const hasSystemId = <T>(node: T): node is T & { systemId: number } =>\n isRecord(node) && numberOf(node.systemId) !== undefined;\n\nconst presenceByType = (\n type: string | undefined,\n installedTypes: Set<string>,\n absentTypes: Set<string>,\n): Presence => {\n if (type === undefined) {\n return \"unknown\";\n }\n if (installedTypes.has(type)) {\n return \"installed\";\n }\n if (absentTypes.has(type)) {\n return \"absent\";\n }\n return \"unknown\";\n};\n\nconst filterOf = (bow: BodyOfWater): BodyInventory[\"filter\"] => {\n const filter = bow.filter;\n if (!hasSystemId(filter)) {\n return { presence: \"absent\" };\n }\n return {\n presence: \"installed\",\n systemId: filter.systemId,\n vsp: presenceByType(\n stringOf(filter.filterType),\n VARIABLE_SPEED_FILTER_TYPES,\n SINGLE_SPEED_FILTER_TYPES,\n ),\n };\n};\n\nconst heaterOf = (bow: BodyOfWater): BodyInventory[\"heater\"] => {\n const heater = bow.heater;\n if (!hasSystemId(heater)) {\n return { presence: \"absent\" };\n }\n const appliances = heater.operations.flatMap((o) => o.heaterEquipment ?? []);\n const types = appliances.map((e) => stringOf(e.heaterType));\n const first = appliances[0];\n const heaterType = types[0];\n const unit: HeaterUnitSlot = hasSystemId(first)\n ? { presence: \"installed\", systemId: first.systemId, heaterType }\n : { presence: \"absent\" };\n const burnsGas = types.map((t) =>\n presenceByType(t, GAS_HEATER_TYPES, OTHER_HEATER_TYPES),\n );\n const gas: Presence = burnsGas.includes(\"installed\")\n ? \"installed\"\n : burnsGas.length > 0 && burnsGas.every((p) => p === \"absent\")\n ? \"absent\"\n : \"unknown\";\n return {\n presence: \"installed\",\n systemId: heater.systemId,\n heaterType,\n gas,\n unit,\n };\n};\n\nconst FEEDER_CELL_TYPES = new Set([\"CELL_TYPE_LIQUID\", \"CELL_TYPE_TABLET\"]);\n\nconst SALT_CELL_TYPES = new Set([\n \"CELL_TYPE_T3\",\n \"CELL_TYPE_T5\",\n \"CELL_TYPE_T9\",\n \"CELL_TYPE_T15\",\n \"CELL_TYPE_T15_LS\",\n \"CELL_TYPE_TCELLS315\",\n \"CELL_TYPE_TCELLS325\",\n \"CELL_TYPE_TCELLS340\",\n]);\n\nconst flag = (value: boolean): Presence => (value ? \"installed\" : \"absent\");\n\nconst chlorinatorOf = (bow: BodyOfWater): BodyInventory[\"chlorinator\"] => {\n const chlorinator = bow.chlorinator;\n if (!hasSystemId(chlorinator)) {\n return { presence: \"absent\" };\n }\n const cell = chlorinator.operations\n .map((o) => o.chlorinatorEquipment)\n .find(hasSystemId);\n const cellType = stringOf(chlorinator.cellType);\n return {\n presence: \"installed\",\n systemId: chlorinator.systemId,\n cell:\n cell === undefined\n ? { presence: \"absent\" }\n : {\n presence: \"installed\",\n systemId: cell.systemId,\n cellType,\n feeder: presenceByType(\n cellType,\n FEEDER_CELL_TYPES,\n SALT_CELL_TYPES,\n ),\n },\n };\n};\n\nconst slotOf = (node: unknown): Slot =>\n hasSystemId(node)\n ? { presence: \"installed\", systemId: node.systemId }\n : { presence: \"absent\" };\n\nconst lightOf = (bow: BodyOfWater): BodyInventory[\"light\"] => {\n const light = bow.colorLogicLights[0];\n if (!hasSystemId(light)) {\n return { presence: \"absent\" };\n }\n return {\n presence: \"installed\",\n systemId: light.systemId,\n networked: flag(light.networked),\n };\n};\n\nconst blowerOf = (bow: BodyOfWater): Slot =>\n slotOf(bow.relays.find((r) => stringOf(r.function) === \"RLY_BLOWER\"));\n\nconst spilloverOf = (bow: BodyOfWater, bodies: BodyOfWater[]): Presence => {\n const sharedType = stringOf(bow.sharedType);\n if (sharedType === \"BOW_SHARED_EQUIPMENT\") {\n const partner = bodies.find(\n (b) => b.systemId === bow.sharedEquipmentSystemId,\n );\n return partner !== undefined && partner.type !== bow.type\n ? \"installed\"\n : \"unknown\";\n }\n return sharedType === undefined || sharedType === \"BOW_NO_EQUIPMENT_SHARED\"\n ? \"absent\"\n : \"unknown\";\n};\n\nconst bodyOf = (bow: BodyOfWater, bodies: BodyOfWater[]): BodyInventory => {\n return {\n systemId: bow.systemId,\n spillover: spilloverOf(bow, bodies),\n csad: slotOf(bow.csad),\n filter: filterOf(bow),\n heater: heaterOf(bow),\n chlorinator: chlorinatorOf(bow),\n light: lightOf(bow),\n blower: blowerOf(bow),\n };\n};\n\nexport const discover = (config: MSPConfig): Inventory => ({\n bodies: config.backyard.bodiesOfWater\n .filter(hasSystemId)\n .map((bow) => bodyOf(bow, config.backyard.bodiesOfWater)),\n});\n\nexport const presenceAt = (body: BodyInventory, path: InventoryPath) => {\n switch (path) {\n case \"filter\":\n return body.filter.presence;\n case \"filter.vsp\":\n return body.filter.presence === \"installed\"\n ? body.filter.vsp\n : body.filter.presence;\n case \"heater\":\n return body.heater.presence;\n case \"heater.gas\":\n return body.heater.presence === \"installed\"\n ? body.heater.gas\n : body.heater.presence;\n case \"heater.unit\":\n return body.heater.presence === \"installed\"\n ? body.heater.unit.presence\n : body.heater.presence;\n case \"chlorinator\":\n return body.chlorinator.presence;\n case \"chlorinator.cell\":\n return body.chlorinator.presence === \"installed\"\n ? body.chlorinator.cell.presence\n : body.chlorinator.presence;\n case \"chlorinator.feeder\":\n return body.chlorinator.presence === \"installed\"\n ? body.chlorinator.cell.presence === \"installed\"\n ? body.chlorinator.cell.feeder\n : body.chlorinator.cell.presence\n : body.chlorinator.presence;\n case \"csad\":\n return body.csad.presence;\n case \"light\":\n return body.light.presence;\n case \"light.networked\":\n return body.light.presence === \"installed\"\n ? body.light.networked\n : body.light.presence;\n case \"blower\":\n return body.blower.presence;\n case \"spillover\":\n return body.spillover;\n default:\n return unreachablePath(path);\n }\n};\n\nexport const systemIdAt = (body: BodyInventory, path: InventoryPath) => {\n const slot = (() => {\n switch (path) {\n case \"filter\":\n case \"filter.vsp\":\n return body.filter;\n case \"heater\":\n case \"heater.gas\":\n return body.heater;\n case \"heater.unit\":\n return body.heater.presence === \"installed\"\n ? body.heater.unit\n : undefined;\n case \"chlorinator\":\n return body.chlorinator;\n case \"chlorinator.cell\":\n case \"chlorinator.feeder\":\n return body.chlorinator.presence === \"installed\"\n ? body.chlorinator.cell\n : undefined;\n case \"light\":\n case \"light.networked\":\n return body.light;\n case \"blower\":\n return body.blower;\n case \"csad\":\n return body.csad;\n case \"spillover\":\n return undefined;\n default:\n return unreachablePath(path);\n }\n })();\n return slot?.presence === \"installed\" ? slot.systemId : undefined;\n};\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { isRunning } from \"@/constants/labels\";\nimport { OmniLogicError, ReadingUnavailableError } from \"@/utils/errors\";\nimport { systemIdAt, type InventoryPath } from \"@/utils/inventory\";\n\nexport class Device {\n #poolId: number;\n #equipmentId: number;\n #name: string;\n #omni: OmniLogic;\n\n constructor(\n omni: OmniLogic,\n poolId: number,\n equipmentId: number,\n name: string,\n ) {\n this.#omni = omni;\n this.#poolId = poolId;\n this.#equipmentId = equipmentId;\n this.#name = name;\n }\n\n get omni() {\n return this.#omni;\n }\n\n // the body of water this one belongs to\n get poolId() {\n return this.#poolId;\n }\n\n get equipmentId() {\n return this.#equipmentId;\n }\n\n get name() {\n return this.#name;\n }\n\n get running() {\n return isRunning(this.omni.telemetry.backyard.state);\n }\n\n // this device's body in the cached config\n get bodyConfig() {\n return this.omni.config.backyard.bodiesOfWater.find(\n (b) => b.systemId === this.poolId,\n );\n }\n\n // this device's body in the inventory\n get inventoryBody() {\n const found = this.omni.inventory.bodies.find(\n (b) => b.systemId === this.poolId,\n );\n if (found === undefined) {\n throw new OmniLogicError(`No inventory for \"${this.name}\"`);\n }\n return found;\n }\n\n // a part's system id, or this device's id\n idAt(path: InventoryPath) {\n return systemIdAt(this.inventoryBody, path) ?? this.equipmentId;\n }\n\n requireRunning() {\n if (!this.running) {\n throw new ReadingUnavailableError({\n name: this.name,\n backyardState: this.omni.telemetry.backyard.state,\n });\n }\n }\n\n // whether the controller is on and reports this device\n reportedIn(list: { systemId: number }[]) {\n return this.running && list.some((r) => r.systemId === this.equipmentId);\n }\n\n // a config node of this device, which must be there\n configured<T>(node: T | undefined): T {\n if (node === undefined) {\n throw new OmniLogicError(`No configuration for \"${this.name}\"`);\n }\n return node;\n }\n\n telemetry<T extends { systemId: number }>(list: T[]) {\n const found = list.find((r) => r.systemId === this.equipmentId);\n if (found === undefined) {\n throw new OmniLogicError(`No telemetry for \"${this.name}\"`);\n }\n return found;\n }\n}\n","// the cell thermistor curve, tenths of °F\nconst THERMISTOR: number[] = [\n 8000, 3740, 3136, 2817, 2603, 2444, 2318, 2214, 2125, 2048, 1980, 1919, 1864,\n 1813, 1767, 1723, 1683, 1645, 1610, 1576, 1544, 1514, 1485, 1458, 1431, 1406,\n 1381, 1358, 1335, 1313, 1291, 1270, 1250, 1230, 1211, 1193, 1174, 1156, 1139,\n 1122, 1105, 1088, 1072, 1056, 1041, 1025, 1010, 995, 980, 966, 951, 937, 923,\n 909, 895, 881, 868, 854, 841, 828, 815, 802, 789, 776, 763, 750, 737, 725,\n 712, 699, 687, 674, 661, 649, 636, 624, 611, 598, 586, 573,\n];\n\n// a 16-bit value sent as two bytes\nexport const word = (high: number, low: number) => high * 256 + low;\n\n// cell voltage: ADC count → volts\nexport const cellVolts = (raw: number) => ((raw * 5) / 255) * 8.15;\n\n// cell current: ADC count → amps, a raw 0 reported as 0\nexport const cellAmps = (raw: number) =>\n raw === 0 ? 0 : (raw * 5) / 255 / 0.489;\n\n// thermistor count → °F, NaN past the table's end (raw ≥ 640)\nexport const thermistorF = (raw: number) => {\n const i = raw >> 3;\n const lo = THERMISTOR[i];\n if (lo === undefined) {\n return Number.NaN;\n }\n const hi = THERMISTOR[i + 1] ?? lo;\n return (lo + ((raw & 7) / 8) * (hi - lo)) / 10;\n};\n\n// two BCD nibbles → the decimal they spell (0x58 → 58)\nconst bcd = (byte: number) => (byte >> 4) * 10 + (byte & 0x0f);\n\n// the pump drive's power: two BCD bytes spelling watts\nexport const bcdWatts = (msb: number, lsb: number) => bcd(msb) * 100 + bcd(lsb);\n\n// six ASCII bytes → their digits, spaces and nulls dropped (\"1015 \" → \"1015\")\nconst revisionDigits = (bytes: number[]) =>\n String.fromCharCode(...bytes).replaceAll(/[^0-9]/g, \"\");\n\n// the display board's revision as the panel shows it: \"1015\" → \"10.1.5\"\nexport const displayRevision = (bytes: number[]) => {\n const d = revisionDigits(bytes);\n return d.length >= 4\n ? `${d.slice(0, 2)}.${d.slice(2, 3)}.${d.slice(3, 4)}`\n : d;\n};\n\n// the drive's revision as the panel shows it: \"0073\" → \"0.73\"\nexport const driveRevision = (bytes: number[]) => {\n const d = revisionDigits(bytes);\n return d.length >= 4 ? `${Number(d.slice(0, 2))}.${d.slice(2, 4)}` : d;\n};\n","import type { ReadOptions } from \"@/client/omnilogic\";\nimport {\n bitmaskNames,\n CHLORINATOR_ALERTS,\n CHLORINATOR_ERRORS,\n CHLORINATOR_OP_MODE,\n CHLORINATOR_OPERATING_STATE,\n CHLORINATOR_STATUS,\n packedNames,\n} from \"@/constants/labels\";\nimport { Device } from \"@/equipment/device\";\nimport { cellAmps, cellVolts, thermistorF, word } from \"@/utils/decode\";\nimport { OmniValidationError } from \"@/utils/errors\";\nimport { presenceAt } from \"@/utils/inventory\";\n\nexport type CellStatus = {\n // a label, or the code with { raw: true }\n opState: number | string;\n scState: number;\n alertStatus: number;\n // ppm\n instantSalt: number;\n averageSalt: number;\n // only a liquid or tablet feeder dispenses\n activelyDispensing?: boolean;\n};\n\nexport type CellMeasurement = {\n // volts, or the ADC count with { raw: true }\n voltage: number;\n // amps, or the ADC count with { raw: true }\n current: number;\n // °F, or the thermistor count with { raw: true }\n cellTemp: number;\n boardTemp: number;\n // ppm\n instantSalt: number;\n averageSalt: number;\n};\n\nexport class Chlorinator extends Device {\n get state() {\n return this.telemetry(this.omni.telemetry.chlorinators);\n }\n\n get #reported() {\n return this.reportedIn(this.omni.telemetry.chlorinators);\n }\n\n get #runningState() {\n this.requireRunning();\n return this.state;\n }\n\n get #config() {\n return this.configured(this.bodyConfig?.chlorinator);\n }\n\n get enabled() {\n return this.#runningState.enable !== 0;\n }\n\n setEnabled(on: boolean) {\n return this.omni.command(\"SetCHLOREnable\", {\n poolId: this.poolId,\n data: Number(on),\n });\n }\n\n get timedPercent() {\n return this.#config.timedPercent;\n }\n\n setTimedPercent(percent: number) {\n if (!Number.isInteger(percent) || percent < 0 || percent > 100) {\n throw new OmniValidationError(\n `Timed percent ${percent} is not a whole number from 0 to 100`,\n );\n }\n return this.omni.command(\"SetCHLORTimePercent\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: percent,\n });\n }\n\n get operatingState() {\n return this.#reported\n ? (CHLORINATOR_OPERATING_STATE[this.state.operatingState] ?? \"Unknown\")\n : \"Off\";\n }\n\n // whether a probe or the clock decides the output\n get operatingMode() {\n return this.#reported\n ? (CHLORINATOR_OP_MODE[this.state.operatingMode] ?? \"Unknown\")\n : \"Not Config\";\n }\n\n // every condition the cell reports at once, such as \"Generating, K1 Active\"\n get conditions() {\n return this.#reported\n ? bitmaskNames(this.state.status, CHLORINATOR_STATUS)\n : \"None\";\n }\n\n // what the cell is warning about, such as \"Low Salt, Clean Cell\"\n get alert() {\n return packedNames(this.#runningState.chlrAlert, CHLORINATOR_ALERTS);\n }\n\n // the faults the cell reports, such as \"Relay K1 Open\"\n get error() {\n return packedNames(this.#runningState.chlrError, CHLORINATOR_ERRORS);\n }\n\n // ppm\n get averageSalt() {\n return this.#runningState.avgSaltLevel;\n }\n\n // ppm\n get instantSalt() {\n return this.#runningState.instantSaltLevel;\n }\n\n get isSuperchlorinating() {\n return this.#reported && this.state.scMode !== 0;\n }\n\n superchlorinate(on = true) {\n return this.omni.command(\"SetUISuperCHLORCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n get superchlorinateHours() {\n return this.#config.superChlorTimeout;\n }\n\n setSuperchlorinateHours(hours: number) {\n return this.omni.command(\"SetUISuperCHLORTimeoutCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: hours,\n });\n }\n\n async superchlorinateMinutesRemaining() {\n const r = await this.omni.command(\"GetUISuperCHLORTimeRemaining\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n });\n return r.superChlorTimeRemaining;\n }\n\n async relayPolarity() {\n const r = await this.omni.command(\"GetCHLORRelayPolarity\", {\n poolId: this.poolId,\n equipmentId: this.idAt(\"chlorinator.cell\"),\n });\n return r.relaySetting;\n }\n\n async cellStatus(options: ReadOptions = {}): Promise<CellStatus> {\n const r = await this.omni.command(\"GetCHLORStatus\", {\n poolId: this.poolId,\n equipmentId: this.idAt(\"chlorinator.cell\"),\n });\n const opState = r.opState;\n const reading: CellStatus = {\n opState: options.raw\n ? opState\n : (CHLORINATOR_OPERATING_STATE[opState] ?? \"Unknown\"),\n scState: r.scState,\n alertStatus: r.alertStatus,\n instantSalt: word(r.instantSaltHigh, r.instantSaltLow),\n averageSalt: word(r.averageSaltHigh, r.averageSaltLow),\n };\n if (presenceAt(this.inventoryBody, \"chlorinator.feeder\") !== \"absent\") {\n reading.activelyDispensing = r.activelyDispensing === 1;\n }\n return reading;\n }\n\n async cellMeasurement(options: ReadOptions = {}): Promise<CellMeasurement> {\n const r = await this.omni.command(\"GetCHLORMeasurement\", {\n poolId: this.poolId,\n equipmentId: this.idAt(\"chlorinator.cell\"),\n });\n const voltage = word(r.voltageHighByte, r.voltageLowByte);\n const current = word(r.currentHighByte, r.currentLowByte);\n const cellTemp = word(r.cellTempHighByte, r.cellTempLowByte);\n const boardTemp = word(r.boardTempHighByte, r.boardTempLowByte);\n const salt = {\n instantSalt: word(r.instantSaltLevelHighByte, r.instantSaltLevelLowByte),\n averageSalt: word(r.averageSaltLevelHighByte, r.averageSaltLevelLowByte),\n };\n if (options.raw) {\n return { voltage, current, cellTemp, boardTemp, ...salt };\n }\n return {\n voltage: cellVolts(voltage),\n current: cellAmps(current),\n cellTemp: thermistorF(cellTemp),\n boardTemp: thermistorF(boardTemp),\n ...salt,\n };\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { CSAD_MODE } from \"@/constants/labels\";\nimport { ORP_UNAVAILABLE, PH_UNAVAILABLE } from \"@/constants/sentinels\";\nimport { Device } from \"@/equipment/device\";\nimport type { CSAD as CSADConfig } from \"@/types/config\";\nimport { OmniValidationError } from \"@/utils/errors\";\n\ntype Scale = { min: number; max: number; step: number };\n\n// the scales the panel offers\nconst PH_SCALE: Scale = { min: 7, max: 8, step: 0.1 };\nconst ORP_SCALE: Scale = { min: 400, max: 900, step: 5 };\n\nconst onScale = (value: number, { min, max, step }: Scale, what: string) => {\n const steps = Math.round((value - min) / step);\n if (value < min || value > max || min + steps * step !== value) {\n throw new OmniValidationError(\n `${what} ${value} is not between ${min} and ${max} in steps of ${step}`,\n );\n }\n return value;\n};\n\n// chemistry sense and dispense\nexport class CSAD extends Device {\n constructor(omni: OmniLogic, poolId: number, config: CSADConfig) {\n super(omni, poolId, config.systemId, config.name);\n }\n\n get #config() {\n return this.configured(this.bodyConfig?.csad);\n }\n\n // what reduces the pH: ACID or CO2\n get type() {\n return this.#config.type;\n }\n\n get enabled() {\n return this.#config.enabled;\n }\n\n get phTarget() {\n return Number(this.#config.targetValue);\n }\n\n // the offset between the tested and the displayed reading\n get phCalibration() {\n return Number(this.#config.calibrationValue);\n }\n\n get phLowAlarm() {\n return Number(this.#config.phLowAlarmLevel);\n }\n\n get phHighAlarm() {\n return Number(this.#config.phHighAlarmLevel);\n }\n\n get orpTarget() {\n return this.#config.orpTargetLevel;\n }\n\n get orpLowAlarm() {\n return this.#config.orpLowAlarmLevel;\n }\n\n get orpHighAlarm() {\n return this.#config.orpHighAlarmLevel;\n }\n\n get state() {\n return this.telemetry(this.omni.telemetry.csads);\n }\n\n get #reported() {\n return this.reportedIn(this.omni.telemetry.csads);\n }\n\n // without the calibration offset applied\n get ph() {\n if (!this.#reported) {\n return undefined;\n }\n const ph = Number(this.state.ph);\n return ph === PH_UNAVAILABLE ? undefined : ph;\n }\n\n get orp() {\n if (!this.#reported) {\n return undefined;\n }\n const orp = this.state.orp;\n return orp === ORP_UNAVAILABLE ? undefined : orp;\n }\n\n get mode() {\n return this.#reported ? (CSAD_MODE[this.state.mode] ?? \"Unknown\") : \"Off\";\n }\n\n get isDispensing() {\n return this.#reported && this.state.status === 1;\n }\n\n setPhTarget(ph: number) {\n return this.omni.command(\"UISetCSADTargetValue\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n targetValue: onScale(ph, PH_SCALE, \"pH\"),\n });\n }\n\n setOrpTarget(millivolts: number) {\n return this.omni.command(\"SetUICSADORPTargetLevel\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: onScale(millivolts, ORP_SCALE, \"ORP\"),\n });\n }\n}\n","import type { OmniLogic, WriteOptions } from \"@/client/omnilogic\";\nimport { OmniValidationError } from \"@/utils/errors\";\nimport { defined, matches } from \"@/utils/helpers\";\n\nexport const SCHEDULE_MONDAY = 1;\nexport const SCHEDULE_TUESDAY = 2;\nexport const SCHEDULE_WEDNESDAY = 4;\nexport const SCHEDULE_THURSDAY = 8;\nexport const SCHEDULE_FRIDAY = 16;\nexport const SCHEDULE_SATURDAY = 32;\nexport const SCHEDULE_SUNDAY = 64;\nexport const SCHEDULE_EVERY_DAY = 127;\n\nexport const SCHEDULE_SUNRISE_HOUR = 25;\nexport const SCHEDULE_SUNSET_HOUR = 26;\nexport const SCHEDULE_SUNRISE_SUNSET_MINUTE = 25;\n\nexport const SCHEDULE_TYPE = {\n equipment: 164,\n spillover: 311,\n theme: 317,\n} as const;\n\nexport type ScheduleType = keyof typeof SCHEDULE_TYPE;\n\nexport const scheduleTypeOf = (event: number) =>\n ([\"equipment\", \"spillover\", \"theme\"] as const).find(\n (type) => SCHEDULE_TYPE[type] === event,\n );\n\nexport type ScheduleCreate = {\n equipmentId: number;\n // the value to set: a speed, a show, a percent, a set point, 1/0 for a relay\n data: number;\n // default \"equipment\"\n type?: ScheduleType;\n startHour: number;\n startMinute?: number;\n endHour: number;\n endMinute?: number;\n // a bit per day, the constants above added together\n days: number;\n // default true\n enabled?: boolean;\n // default true\n recurring?: boolean;\n};\n\nexport type ScheduleUpdate = Partial<Omit<ScheduleCreate, \"equipmentId\">>;\n\nexport class Schedules {\n #omni: OmniLogic;\n\n constructor(omni: OmniLogic) {\n this.#omni = omni;\n }\n\n list() {\n return this.#omni.config.schedules;\n }\n\n for(equipmentId: number) {\n return this.list().filter((s) => s.equipmentId === equipmentId);\n }\n\n get(scheduleId: number) {\n return this.list().find((s) => s.scheduleSystemId === scheduleId);\n }\n\n async create(spec: ScheduleCreate, options: WriteOptions = {}) {\n const {\n type = \"equipment\",\n startMinute = 0,\n endMinute = 0,\n days: daysActive,\n enabled = true,\n recurring = true,\n ...rest\n } = spec;\n const record = {\n ...rest,\n event: SCHEDULE_TYPE[type],\n startMinute,\n endMinute,\n daysActive,\n enabled: Number(enabled),\n recurring: Number(recurring),\n };\n const before = new Set(this.list().map((s) => s.scheduleSystemId));\n const created = () =>\n this.list().find(\n (s) => !before.has(s.scheduleSystemId) && matches(s, record),\n );\n await this.#omni.command(\"CreateUIScheduleCmd\", record, {\n verify: () => created() !== undefined,\n attempts: options.attempts,\n failure: \"Unable to create the schedule\",\n });\n return created()!;\n }\n\n async update(\n scheduleId: number,\n changes: ScheduleUpdate,\n options: WriteOptions = {},\n ) {\n const current = this.get(scheduleId);\n if (current === undefined) {\n throw new OmniValidationError(\n `No schedule ${scheduleId} in the cached config`,\n );\n }\n const { bowSystemId, equipmentId, scheduleSystemId, ...stored } = current;\n const { type, days, enabled, recurring, ...rest } = changes;\n const next = {\n ...stored,\n ...defined({\n ...rest,\n event: type === undefined ? undefined : SCHEDULE_TYPE[type],\n daysActive: days,\n enabled: enabled === undefined ? undefined : Number(enabled),\n recurring: recurring === undefined ? undefined : Number(recurring),\n }),\n };\n await this.#omni.command(\n \"EditUIScheduleCmd\",\n { scheduleId, ...next },\n {\n verify: () => matches(this.get(scheduleId), next),\n attempts: options.attempts,\n failure: `Unable to update schedule ${scheduleId}`,\n },\n );\n }\n\n async setEnabled(\n scheduleId: number,\n enabled: boolean,\n options: WriteOptions = {},\n ) {\n const flag = Number(enabled);\n await this.#omni.command(\n \"SetUIScheduleEnableCmd\",\n { scheduleId, data: flag },\n {\n verify: () => this.get(scheduleId)?.enabled === flag,\n attempts: options.attempts,\n failure: `Unable to ${enabled ? \"enable\" : \"disable\"} schedule ${scheduleId}`,\n },\n );\n }\n\n async remove(scheduleId: number, options: WriteOptions = {}) {\n if (this.get(scheduleId) === undefined) {\n throw new OmniValidationError(\n `No schedule ${scheduleId} in the cached config`,\n );\n }\n await this.#omni.command(\n \"DeleteUIScheduleCmd\",\n { scheduleId },\n {\n verify: () => this.get(scheduleId) === undefined,\n attempts: options.attempts,\n failure: `Unable to delete schedule ${scheduleId}`,\n },\n );\n }\n}\n","import Builder from \"fast-xml-builder\";\nimport { XMLParser } from \"fast-xml-parser\";\n\nimport type {\n Action,\n Backyard,\n BodyOfWater,\n Chlorinator,\n ChlorinatorEquipment,\n ColorLogicLight,\n CSAD,\n CSADEquipment,\n Device,\n Favorite,\n Filter,\n Heater,\n HeaterEquipment,\n MSPConfig,\n Operation,\n Pump,\n Relay,\n Schedule,\n Sensor,\n Theme,\n ThemeCommand,\n} from \"@/types/config\";\nimport type * as telemetry from \"@/types/telemetry\";\nimport { OmniLogicError, OmniValidationError } from \"@/utils/errors\";\nimport { isRecord } from \"@/utils/helpers\";\n\n// illegal XML 1.0 characters\nconst ILLEGAL =\n /[\\0-\\x08\\x0B\\f\\x0E-\\x1F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nconst legal = (value: string) => {\n const hit = ILLEGAL.exec(value);\n if (hit !== null) {\n throw new OmniValidationError(\n `Invalid character in string: ${value} at index ${hit.index}`,\n );\n }\n return value;\n};\n\nconst checked = (value: unknown) =>\n typeof value === \"string\" ? legal(value) : value;\n\nconst builder = new Builder({\n ignoreAttributes: false,\n attributeNamePrefix: \"@\",\n textNodeName: \"_\",\n suppressEmptyNode: true,\n tagValueProcessor: (_name, value) => checked(value),\n attributeValueProcessor: (_name, value) => checked(value),\n});\n\ntype XMLBody = {\n Request: {\n \"@xmlns\": string;\n Name: string;\n Parameters?: {\n Parameter: {\n \"@name\": string;\n \"@dataType\": DataType;\n _: string;\n }[];\n };\n };\n};\n\nexport type DataType = \"int\" | \"bool\" | \"byte\" | \"float\" | \"string\";\n\nexport type Parameter = {\n name: string;\n dataType: DataType;\n value: string;\n};\n\nexport const buildMessageXml = (name: string, parameters?: Parameter[]) => {\n const body: XMLBody = {\n Request: { \"@xmlns\": \"http://nextgen.hayward.com/api\", Name: name },\n };\n if (parameters && parameters.length > 0) {\n body.Request.Parameters = {\n Parameter: parameters.map(({ name: n, dataType, value }) => ({\n \"@name\": n,\n \"@dataType\": dataType,\n _: value,\n })),\n };\n }\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>${builder.build(body)}`;\n};\n\nconst coerceText = (value: string) => {\n if (value === \"yes\") {\n return true;\n }\n if (value === \"no\") {\n return false;\n }\n const num = parseInt(value, 10);\n return !Number.isNaN(num) && num.toString() === value ? num : value;\n};\n\nconst CONFIG_LISTS = new Set([\n \"action\",\n \"bodyOfWater\",\n \"colorLogicLight\",\n \"component\",\n \"device\",\n \"favorite\",\n \"group\",\n \"operation\",\n \"parameter\",\n \"pump\",\n \"relay\",\n \"request\",\n \"sche\",\n \"sensor\",\n]);\n\nconst TELEMETRY_LISTS = new Set([\n \"bodyOfWater\",\n \"chlorinator\",\n \"colorLogicLight\",\n \"csad\",\n \"filter\",\n \"group\",\n \"heater\",\n \"pump\",\n \"relay\",\n \"smartValveActuator\",\n \"valveActuator\",\n \"virtualHeater\",\n]);\n\nconst toCamelCase = (str: string) =>\n str\n .trim()\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\")\n .replace(/([a-z\\d])([A-Z])/g, \"$1 $2\")\n .split(/[\\s_-]+/)\n .map((word, index) => {\n const lower = word.toLowerCase();\n return index === 0\n ? lower\n : lower.charAt(0).toUpperCase() + lower.slice(1);\n })\n .join(\"\");\n\nconst parser = new XMLParser({\n ignoreAttributes: false,\n ignoreDeclaration: true,\n jPath: true,\n attributeNamePrefix: \"\",\n textNodeName: \"_\",\n parseTagValue: false,\n parseAttributeValue: false,\n transformTagName: toCamelCase,\n transformAttributeName: toCamelCase,\n tagValueProcessor: (tag, value, jPath) =>\n jPath === \"response.parameters.parameter\" ||\n tag === \"name\" ||\n tag === \"deviceName\"\n ? value\n : coerceText(value),\n attributeValueProcessor: (_attr, value) => coerceText(value),\n isArray: (tag, path, _leaf, isAttribute) =>\n !isAttribute &&\n (String(path).startsWith(\"status.\")\n ? TELEMETRY_LISTS.has(tag)\n : CONFIG_LISTS.has(tag)),\n});\n\nexport const parseXML = (xml: string) => parser.parse(xml);\n\ntype ResponseParameter = {\n _: string | number | boolean;\n name: string;\n dataType: DataType;\n};\n\nexport type ResponseMessage = {\n response: {\n xmlns: string;\n name: string;\n parameters: {\n parameter: ResponseParameter[];\n };\n };\n};\n\nexport const coerceParameterValue = (\n dataType: DataType,\n value: string | number | boolean,\n) => {\n const text = String(value);\n switch (dataType) {\n case \"int\":\n case \"byte\": {\n const num = parseInt(text, 10);\n return isNaN(num) ? 0 : num;\n }\n case \"float\": {\n const num = parseFloat(text);\n return isNaN(num) ? 0 : num;\n }\n case \"bool\":\n return text === \"1\";\n default:\n return value;\n }\n};\n\nexport const parametersByName = (parameters: ResponseParameter[]) => {\n return Object.fromEntries(\n parameters.map(({ _, dataType, name }) => {\n return [toCamelCase(name), coerceParameterValue(dataType, _)];\n }),\n );\n};\n\ntype List<T> = T[] | undefined;\n\ntype RawEquipment<T extends { operations: Operation[] }> = Omit<\n T,\n \"operations\"\n> & { operation: List<RawOperation> };\n\ntype RawOperation = {\n action: List<Action>;\n chlorinatorEquipment?: RawEquipment<ChlorinatorEquipment>;\n csadEquipment?: RawEquipment<CSADEquipment>;\n heaterEquipment?: RawEquipment<HeaterEquipment>;\n};\n\ntype RawBodyOfWater = Omit<\n BodyOfWater,\n | \"chlorinator\"\n | \"colorLogicLights\"\n | \"csad\"\n | \"filter\"\n | \"heater\"\n | \"pumps\"\n | \"relays\"\n | \"sensors\"\n> & {\n chlorinator?: RawEquipment<Chlorinator>;\n csad?: RawEquipment<CSAD>;\n colorLogicLight: List<RawEquipment<ColorLogicLight>>;\n filter?: RawEquipment<Filter>;\n heater?: RawEquipment<Heater>;\n pump: List<RawEquipment<Pump>>;\n relay: List<RawEquipment<Relay>>;\n sensor: List<RawEquipment<Sensor>>;\n};\n\ntype RawParameter = Omit<ThemeCommand[\"parameters\"][number], \"value\"> & {\n _: number | string;\n};\n\ntype RawThemeCommand = Omit<ThemeCommand, \"parameters\"> & {\n parameters?: { parameter: List<RawParameter> } | string;\n};\n\ntype RawTheme = Omit<Theme, \"commands\"> & { request: List<RawThemeCommand> };\n\ntype RawDevice = Omit<Device, \"devices\"> & {\n devices: { device: List<RawDevice> } | string;\n};\n\ntype RawConfig = {\n mspConfig: Omit<\n MSPConfig,\n \"backyard\" | \"devices\" | \"favorites\" | \"themes\" | \"schedules\"\n > & {\n backyard: Omit<\n Backyard,\n \"bodiesOfWater\" | \"colorLogicLights\" | \"relays\" | \"sensors\"\n > & {\n bodyOfWater: List<RawBodyOfWater>;\n colorLogicLight: List<RawEquipment<ColorLogicLight>>;\n relay: List<RawEquipment<Relay>>;\n sensor: List<RawEquipment<Sensor>>;\n };\n dmt: { device: List<RawDevice> } | string;\n favorites: { favorite: List<Favorite> } | string;\n groups: { group: List<RawTheme> } | string;\n schedules: { sche: List<Schedule> } | string;\n };\n};\n\nconst operations = (raw: List<RawOperation>): Operation[] =>\n (raw ?? []).map(\n ({ action, chlorinatorEquipment, csadEquipment, heaterEquipment }) => ({\n actions: action ?? [],\n ...(chlorinatorEquipment && {\n chlorinatorEquipment: withOperations(chlorinatorEquipment),\n }),\n ...(csadEquipment && {\n csadEquipment: withOperations(csadEquipment),\n }),\n ...(heaterEquipment && {\n heaterEquipment: withOperations(heaterEquipment),\n }),\n }),\n );\n\nconst withOperations = <T extends { operations: Operation[] }>({\n operation,\n ...rest\n}: RawEquipment<T>) => ({ ...rest, operations: operations(operation) });\n\nconst devices = (raw: List<RawDevice>): Device[] =>\n (raw ?? []).map(({ devices: children, ...rest }) => ({\n ...rest,\n devices: devices(isRecord(children) ? children.device : undefined),\n }));\n\nconst bodyOfWater = ({\n chlorinator,\n colorLogicLight,\n csad,\n filter,\n heater,\n pump,\n relay,\n sensor,\n ...rest\n}: RawBodyOfWater) => ({\n ...rest,\n ...(chlorinator && { chlorinator: withOperations(chlorinator) }),\n colorLogicLights: (colorLogicLight ?? []).map(withOperations),\n ...(csad && { csad: withOperations(csad) }),\n ...(filter && { filter: withOperations(filter) }),\n ...(heater && { heater: withOperations(heater) }),\n pumps: (pump ?? []).map(withOperations),\n relays: (relay ?? []).map(withOperations),\n sensors: (sensor ?? []).map(withOperations),\n});\n\nconst section = <T>(\n wrapper: { [k: string]: List<T> } | string | undefined,\n tag: string,\n) => (isRecord(wrapper) ? (wrapper[tag] ?? []) : []);\n\nconst theme = ({ request, ...rest }: RawTheme) => ({\n ...rest,\n commands: (request ?? []).map(({ parameters, ...command }) => ({\n ...command,\n parameters: section(parameters, \"parameter\").map(({ _, ...parameter }) => ({\n ...parameter,\n value: _,\n })),\n })),\n});\n\nexport const parseConfig = (xml: string) => {\n const raw: RawConfig = parseXML(xml);\n if (!isRecord(raw.mspConfig)) {\n throw new OmniLogicError(\"Malformed reply: no <MSPConfig> element\");\n }\n const {\n backyard: {\n bodyOfWater: bodies,\n colorLogicLight,\n relay,\n sensor,\n ...backyard\n },\n dmt,\n favorites,\n groups,\n schedules,\n ...rest\n } = raw.mspConfig;\n return {\n ...rest,\n backyard: {\n ...backyard,\n bodiesOfWater: (bodies ?? []).map(bodyOfWater),\n colorLogicLights: (colorLogicLight ?? []).map(withOperations),\n relays: (relay ?? []).map(withOperations),\n sensors: (sensor ?? []).map(withOperations),\n },\n devices: devices(section(dmt, \"device\")),\n favorites: section(favorites, \"favorite\"),\n themes: section(groups, \"group\").map(theme),\n schedules: section(schedules, \"sche\"),\n };\n};\n\ntype RawTelemetry = {\n version: string;\n backyard: telemetry.Backyard;\n bodyOfWater: List<telemetry.BodyOfWater>;\n chlorinator: List<telemetry.Chlorinator>;\n colorLogicLight: List<telemetry.ColorLogicLight>;\n csad: List<telemetry.CSAD>;\n filter: List<telemetry.Filter>;\n group: List<telemetry.Theme>;\n heater: List<telemetry.Heater>;\n pump: List<telemetry.Pump>;\n relay: List<telemetry.Relay>;\n smartValveActuator: List<telemetry.SmartValveActuator>;\n valveActuator: List<telemetry.ValveActuator>;\n virtualHeater: List<telemetry.VirtualHeater>;\n};\n\nexport const parseTelemetry = (xml: string) => {\n const raw: { status: RawTelemetry } = parseXML(xml);\n const t = raw.status;\n if (!isRecord(t)) {\n throw new OmniLogicError(\"Malformed reply: no <STATUS> element\");\n }\n return {\n version: t.version,\n backyard: t.backyard,\n bodiesOfWater: t.bodyOfWater ?? [],\n chlorinators: t.chlorinator ?? [],\n colorLogicLights: t.colorLogicLight ?? [],\n csads: t.csad ?? [],\n filters: t.filter ?? [],\n themes: t.group ?? [],\n heaters: t.heater ?? [],\n pumps: t.pump ?? [],\n relays: t.relay ?? [],\n smartValveActuators: t.smartValveActuator ?? [],\n valveActuators: t.valveActuator ?? [],\n virtualHeaters: t.virtualHeater ?? [],\n };\n};\n\ntype RawComponent = { parameter?: ResponseParameter[] };\ntype RawSysInfo = {\n sysInfo?: { parameter?: ResponseParameter[]; component?: RawComponent[] };\n};\n\nexport const parseSysInfo = (xml: string) => {\n const raw: RawSysInfo = parseXML(xml);\n const root = raw.sysInfo;\n if (!isRecord(root)) {\n throw new OmniLogicError(\"Malformed reply: no <SysInfo> element\");\n }\n const top = parametersByName(root.parameter ?? []);\n const components = (root.component ?? []).map((c) => {\n const p = parametersByName(c.parameter ?? []);\n return {\n devName: String(p.devName ?? \"\"),\n type: String(p.type ?? \"\"),\n hua: String(p.hua ?? \"\"),\n version: String(p.version ?? \"\"),\n nodeId: Number(p.nodeId),\n systemId: Number(p.systemId),\n upgradeCapable: p.upgradeCapable === 1,\n };\n });\n return { numComponents: Number(top.numComponents), components };\n};\n","import {\n COMMANDS,\n type CommandName,\n type CommandRequestParam,\n type CommandResponseSpec,\n} from \"@/client/spec\";\nimport { SCHEDULE_EVERY_DAY } from \"@/equipment/schedules\";\nimport { OmniValidationError } from \"@/utils/errors\";\nimport {\n buildMessageXml,\n coerceParameterValue,\n parseXML,\n type ResponseMessage,\n} from \"@/utils/xml\";\n\nconst validateParam = (\n command: CommandName,\n param: CommandRequestParam,\n index: number,\n value: number | string | undefined,\n) => {\n if (param.type === \"string\") {\n if (typeof value !== \"string\") {\n throw new OmniValidationError(\n `${command}: missing or non-string parameter \"${param.name}\" (position ${index})`,\n );\n }\n if (param.values && !param.values.includes(value)) {\n throw new OmniValidationError(\n `${command}: parameter \"${param.name}\" must be one of ` +\n `${param.values.map((v) => JSON.stringify(v)).join(\", \")}, got ` +\n JSON.stringify(value),\n );\n }\n const bytes = Buffer.byteLength(value, \"utf8\");\n if (bytes > param.maxLength) {\n throw new OmniValidationError(\n `${command}: parameter \"${param.name}\" is ${bytes} bytes, ` +\n `longer than the ${param.maxLength} the controller keeps`,\n );\n }\n return value;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new OmniValidationError(\n `${command}: missing or non-numeric parameter \"${param.name}\" (position ${index})`,\n );\n }\n if (param.type !== \"float\") {\n if (!Number.isInteger(value)) {\n throw new OmniValidationError(\n `${command}: parameter \"${param.name}\" must be an integer, got ${value}`,\n );\n }\n // a byte is unsigned, an int a signed 32-bit\n const [min, max] =\n param.type === \"byte\" ? [0, 255] : [-2147483648, 2147483647];\n if (value < min || value > max) {\n throw new OmniValidationError(\n `${command}: parameter \"${param.name}\" must be between ${min} and ${max}, got ${value}`,\n );\n }\n }\n return value;\n};\n\nexport const buildCommandXml = (\n name: CommandName,\n params: Record<string, number | string>,\n) => {\n const request = COMMANDS[name].request;\n const known = new Set(request.map((p) => p.name));\n const xml = buildMessageXml(\n name,\n request.map((p, index) => ({\n name: p.name,\n dataType: p.type,\n value: String(validateParam(name, p, index, params[p.name])),\n })),\n );\n return {\n xml,\n unknown: Object.keys(params).filter((k) => !known.has(k)),\n };\n};\n\n// matched in order, not by name\nexport const parseCommandResponse = (\n responseSpec: CommandResponseSpec,\n xml: string,\n) => {\n const parsed: ResponseMessage = parseXML(xml);\n const parameters = parsed.response?.parameters?.parameter ?? [];\n if (parameters.length !== responseSpec.parameters.length) {\n return {\n ok: false,\n actual: parameters.length,\n expected: responseSpec.parameters.length,\n };\n }\n\n const out: Record<string, number | boolean | string> = {};\n responseSpec.parameters.forEach((p, index) => {\n out[p.name] = coerceParameterValue(p.dataType, parameters[index]?._ ?? \"\");\n });\n return { ok: true, params: out };\n};\n\nexport type TimerOptions = {\n isCountdownTimer?: boolean;\n startTimeHours?: number;\n startTimeMinutes?: number;\n endTimeHours?: number;\n endTimeMinutes?: number;\n daysActive?: number;\n recurring?: boolean;\n};\n\nexport const timerParams = (t: TimerOptions = {}) => ({\n // spelled the firmware's way\n isCountDownTimer: Number(t.isCountdownTimer ?? false),\n startTimeHours: t.startTimeHours ?? 0,\n startTimeMinutes: t.startTimeMinutes ?? 0,\n endTimeHours: t.endTimeHours ?? 0,\n endTimeMinutes: t.endTimeMinutes ?? 0,\n daysActive: t.daysActive ?? 0,\n recurring: Number(t.recurring ?? false),\n});\n\nexport const countdownParams = (minutes: number) =>\n timerParams({\n isCountdownTimer: true,\n endTimeHours: Math.floor(minutes / 60),\n endTimeMinutes: minutes % 60,\n daysActive: SCHEDULE_EVERY_DAY,\n });\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { PUMP_STATE, PUMP_WHY_ON } from \"@/constants/labels\";\nimport { Device } from \"@/equipment/device\";\nimport { timerParams } from \"@/utils/command\";\n\ntype PumpConfig = {\n systemId: number;\n name: string;\n type: string;\n function?: string;\n};\n\nexport class Pump extends Device {\n #type: string;\n #function: string | undefined;\n\n constructor(omni: OmniLogic, poolId: number, config: PumpConfig) {\n super(omni, poolId, config.systemId, config.name);\n this.#type = config.type;\n this.#function = config.function;\n }\n\n // the speeds it can run, e.g. PMP_VARIABLE_SPEED_PUMP\n get type() {\n return this.#type;\n }\n\n // what it drives, absent on the filter pump\n get function() {\n return this.#function;\n }\n\n get #rows() {\n const t = this.omni.telemetry;\n return [...t.pumps, ...t.filters];\n }\n\n get state() {\n return this.telemetry(this.#rows);\n }\n\n get reported() {\n return this.reportedIn(this.#rows);\n }\n\n get states() {\n return PUMP_STATE;\n }\n\n get reasons() {\n return PUMP_WHY_ON;\n }\n\n get countdownReason() {\n return 9;\n }\n\n get #reading() {\n const row = this.state;\n return \"pumpState\" in row\n ? { speed: row.pumpSpeed, position: row.pumpState, whyOn: row.whyOn }\n : {\n speed: row.filterSpeed,\n position: row.filterState,\n whyOn: row.whyFilterIsOn,\n };\n }\n\n get speed() {\n return this.reported ? this.#reading.speed : 0;\n }\n\n get isOn() {\n return this.reported && this.#reading.position !== 0;\n }\n\n get lastSpeed() {\n return (\n this.#rows.find((r) => r.systemId === this.equipmentId)?.lastSpeed ?? 0\n );\n }\n\n get status() {\n const position = this.reported ? this.#reading.position : 0;\n return this.states[position] ?? \"Unknown\";\n }\n\n get whyOn() {\n const code = this.reported ? this.#reading.whyOn : 0;\n return this.reasons[code] ?? \"Unknown\";\n }\n\n get onCountdown() {\n return this.reported && this.#reading.whyOn === this.countdownReason;\n }\n\n // set the pump speed, 0 for off\n setSpeed(value: number) {\n return this.omni.command(\"SetUIEquipmentCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n isOn: value,\n ...timerParams(),\n });\n }\n}\n","import type { OmniLogic, ReadOptions } from \"@/client/omnilogic\";\nimport {\n FILTER_STATE,\n FILTER_VALVE_POSITION,\n FILTER_WHY_ON,\n} from \"@/constants/labels\";\nimport { Pump } from \"@/equipment/pump\";\nimport type { Filter as FilterConfig } from \"@/types/config\";\nimport { bcdWatts, displayRevision, driveRevision, word } from \"@/utils/decode\";\n\nconst ascii = (bytes: number[]) =>\n String.fromCharCode(...bytes).replace(/[\\0 ]+$/, \"\");\n\nexport type FilterDiagnostics = {\n // watts, or the BCD word with { raw: true }\n power: number;\n errorStatus: number;\n // as the panel shows it, or the six bytes as text with { raw: true }\n displayRevision: string;\n driveRevision: string;\n};\n\n// the pump that drives the filter\nexport class Filter extends Pump {\n constructor(omni: OmniLogic, poolId: number, config: FilterConfig) {\n super(omni, poolId, {\n systemId: config.systemId,\n name: config.name,\n type: config.filterType,\n });\n }\n\n get #config() {\n return this.configured(this.bodyConfig?.filter);\n }\n\n get states() {\n return FILTER_STATE;\n }\n\n get reasons() {\n return FILTER_WHY_ON;\n }\n\n get countdownReason() {\n return 10;\n }\n\n get state() {\n return this.telemetry(this.omni.telemetry.filters);\n }\n\n // which way the valves are set, e.g. \"Pool Only\", \"Spillover\"\n get valvePosition() {\n const position = this.reported ? this.state.valvePosition : -1;\n return FILTER_VALVE_POSITION[position] ?? \"Unknown\";\n }\n\n // the speed the pump reports back, lagging the speed it was told\n get reportedSpeed() {\n return this.reported ? this.state.reportedFilterSpeed : 0;\n }\n\n get isPriming() {\n const state = this.reported ? this.state.filterState : 0;\n return state === 2 || state === 10; // Priming or Force Priming\n }\n\n // watts\n get power() {\n return this.reported ? this.state.power : 0;\n }\n\n async diagnostics(options: ReadOptions = {}): Promise<FilterDiagnostics> {\n const r = await this.omni.command(\"GetUIFilterDiagnosticInfo\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n });\n const display = [\n r.displayFwRevisionB1,\n r.displayFwRevisionB2,\n r.displayFwRevisionB3,\n r.displayFwRevisionB4,\n r.displayFwRevisionB5,\n r.displayFwRevisionB6,\n ];\n const drive = [\n r.driveFwRevisionB1,\n r.driveFwRevisionB2,\n r.driveFwRevisionB3,\n r.driveFwRevisionB4,\n r.driveFwRevisionB5,\n r.driveFwRevisionB6,\n ];\n const errorStatus = r.errorStatus;\n if (options.raw) {\n return {\n power: word(r.powerMsb, r.powerLsb),\n errorStatus,\n displayRevision: ascii(display),\n driveRevision: ascii(drive),\n };\n }\n return {\n power: bcdWatts(r.powerMsb, r.powerLsb),\n errorStatus,\n displayRevision: displayRevision(display),\n driveRevision: driveRevision(drive),\n };\n }\n\n get minSpeed() {\n return this.#config.minPumpSpeed;\n }\n\n setMinSpeed(value: number) {\n return this.omni.command(\"SetFilterLowSpeed\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: value,\n });\n }\n\n get maxSpeed() {\n return this.#config.maxPumpSpeed;\n }\n\n setMaxSpeed(value: number) {\n return this.omni.command(\"SetFilterHighSpeed\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: value,\n });\n }\n\n // the speed the Low preset runs\n get lowSpeed() {\n return this.#config.vspLowPumpSpeed;\n }\n\n // the speed the Medium preset runs\n get mediumSpeed() {\n return this.#config.vspMediumPumpSpeed;\n }\n\n // the speed the High preset runs\n get highSpeed() {\n return this.#config.vspHighPumpSpeed;\n }\n\n get primingDuration() {\n return this.#config.primingDuration;\n }\n\n setPrimingDuration(seconds: number) {\n return this.omni.command(\"SetPrimingDuration\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: seconds,\n });\n }\n\n get cooldownDuration() {\n return this.#config.cooldownDuration;\n }\n\n setCooldownDuration(seconds: number) {\n return this.omni.command(\"SetCooldownDuration\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: seconds,\n });\n }\n\n get sharedFilterTimeout() {\n return this.#config.sharedFilterTimeout;\n }\n\n setSharedFilterTimeout(seconds: number) {\n return this.omni.command(\"SetSharedFilterTimeout\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: seconds,\n });\n }\n\n get freezeProtectOverrideInterval() {\n return this.#config.freezeProtectOverrideInterval;\n }\n\n setFreezeProtectOverrideInterval(seconds: number) {\n return this.omni.command(\"SetUIFreezeProtectOverrideInterval\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: seconds,\n });\n }\n\n get freezeProtect() {\n return this.#config.freezeProtectEnable;\n }\n\n setFreezeProtect(on: boolean) {\n return this.omni.command(\"SetFreezeProtect\", {\n poolId: this.poolId,\n data: Number(on),\n });\n }\n\n get freezeProtectTemp() {\n return this.#config.freezeProtectTemp;\n }\n\n setFreezeProtectTemp(degrees: number) {\n return this.omni.command(\"SetFreezeProtectTemp\", {\n poolId: this.poolId,\n data: degrees,\n });\n }\n\n get freezeProtectSpeed() {\n return this.#config.freezeProtectSpeed;\n }\n\n setFreezeProtectSpeed(value: number) {\n return this.omni.command(\"SetFreezeProtectSpeed\", {\n poolId: this.poolId,\n data: value,\n });\n }\n\n get offDuringValveChange() {\n return this.#config.valveChangeOffEnable;\n }\n\n setOffDuringValveChange(on: boolean) {\n return this.omni.command(\"SetFilterOffValveChg\", {\n poolId: this.poolId,\n data: Number(on),\n });\n }\n\n get flowMonitor() {\n return this.#config.noWaterFlowTimeoutEnable;\n }\n\n setFlowMonitor(on: boolean) {\n return this.omni.command(\"SetFlowMonitor\", {\n poolId: this.poolId,\n data: Number(on),\n });\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { HEATER_PRIORITY, HEATER_STATE } from \"@/constants/labels\";\nimport { HEATER_TEMP_UNAVAILABLE } from \"@/constants/sentinels\";\nimport { Device } from \"@/equipment/device\";\nimport type { HeaterEquipment } from \"@/types/config\";\nimport { OmniValidationError } from \"@/utils/errors\";\n\n// the priority that puts a solar loop ahead of every other source\nconst SOLAR_FIRST = 254;\n\n// one heat source under a body's thermostat\nexport class HeaterAppliance extends Device {\n constructor(omni: OmniLogic, poolId: number, config: HeaterEquipment) {\n super(omni, poolId, config.systemId, config.name);\n }\n\n get #config() {\n return this.configured(\n this.bodyConfig?.heater?.operations\n .flatMap((o) => o.heaterEquipment ?? [])\n .find((e) => e.systemId === this.equipmentId),\n );\n }\n\n // HTR_GAS, HTR_SOLAR, HTR_HEAT_PUMP…\n get type() {\n return this.#config.heaterType;\n }\n\n // the other body's record for the same unit, -1 when it is not shared\n get sharedWith() {\n return this.#config.sharedEquipmentSystemId;\n }\n\n get state() {\n return this.telemetry(this.omni.telemetry.heaters);\n }\n\n get #reported() {\n return this.reportedIn(this.omni.telemetry.heaters);\n }\n\n get #runningState() {\n this.requireRunning();\n return this.state;\n }\n\n get status() {\n return this.#reported\n ? (HEATER_STATE[this.state.heaterState] ?? \"Unknown\")\n : \"Off\";\n }\n\n get isOn() {\n return this.#reported && this.state.heaterState === 1;\n }\n\n get temp() {\n if (!this.#reported) {\n return undefined;\n }\n const temp = this.state.temp;\n return temp === HEATER_TEMP_UNAVAILABLE ? undefined : temp;\n }\n\n get supportsCooling() {\n return this.#config.supportsCooling;\n }\n\n // the slowest the filter pump may run while this one heats\n get lowSpeed() {\n return this.#config.minSpeedForOperation;\n }\n\n setLowSpeed(value: number) {\n return this.omni.command(\"SetHeaterLowSpeed\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: value,\n });\n }\n\n // whether the filter pump may run slow while this one heats\n get allowLowSpeed() {\n return this.#config.allowLowSpeedOperation;\n }\n\n setAllowLowSpeed(on: boolean) {\n return this.omni.command(\"SetHeaterAllowedLowSpeed\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n get enabled() {\n return this.#runningState.enable !== 0;\n }\n\n setEnabled(on: boolean) {\n return this.omni.command(\"SetHeaterEnable\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n // its rank against the body's other heat sources\n get priority() {\n return HEATER_PRIORITY[this.#runningState.priority] ?? \"Unknown\";\n }\n\n setPriority(rank: number) {\n if (HEATER_PRIORITY[rank] === undefined) {\n throw new OmniValidationError(\n `Heater priority ${rank} is not one of ${Object.keys(HEATER_PRIORITY).join(\", \")}`,\n );\n }\n if (rank === SOLAR_FIRST && this.type !== \"HTR_SOLAR\") {\n throw new OmniValidationError(\n `Only a solar loop takes priority ${SOLAR_FIRST}; \"${this.name}\" is ${this.type}`,\n );\n }\n return this.omni.command(\"SetUIHeaterPriorityCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: rank,\n });\n }\n\n // hours this source keeps priority, 0 shares it, 24 keeps it while it can run\n get maintainFor() {\n return this.#runningState.maintainFor;\n }\n}\n","import { HEATER_MODE } from \"@/constants/labels\";\nimport { Device } from \"@/equipment/device\";\nimport { HeaterAppliance } from \"@/equipment/heaterAppliance\";\nimport { OmniLogicError, OmniValidationError } from \"@/utils/errors\";\n\n// Heat, Cool and Auto\nconst VALID_MODES = [0, 1, 2];\n\n// the body's thermostat\nexport class Heater extends Device {\n get state() {\n return this.telemetry(this.omni.telemetry.virtualHeaters);\n }\n\n get #runningState() {\n this.requireRunning();\n return this.state;\n }\n\n get #config() {\n return this.configured(this.bodyConfig?.heater);\n }\n\n // every heat source this body can call on, in the controller's order\n get appliances() {\n return this.#config.operations\n .flatMap((o) => o.heaterEquipment ?? [])\n .map((e) => new HeaterAppliance(this.omni, this.poolId, e));\n }\n\n // what the first heat source is doing\n get applianceState() {\n return this.appliances[0]?.status ?? \"Off\";\n }\n\n get setPoint() {\n return this.#runningState.currentSetPoint;\n }\n\n // every controller reports one, fitted with solar or not\n get solarSetPoint() {\n return this.#runningState.solarSetPoint;\n }\n\n // the lowest set point the panel accepts\n get minSetPoint() {\n return this.#config.minSettableWaterTemp;\n }\n\n // the highest set point the panel accepts\n get maxSetPoint() {\n return this.#config.maxSettableWaterTemp;\n }\n\n setSetPoint(degrees: number) {\n const { minSetPoint: min, maxSetPoint: max } = this;\n if (degrees < min || degrees > max) {\n throw new OmniValidationError(\n `Set point ${degrees} is not between ${min} and ${max}`,\n );\n }\n return this.omni.command(\"SetUIHeaterCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: degrees,\n });\n }\n\n get enabled() {\n return this.#runningState.enable !== 0;\n }\n\n setEnabled(on: boolean) {\n return this.omni.command(\"SetHeaterEnable\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n get mode() {\n return HEATER_MODE[this.#runningState.mode] ?? \"Unknown\";\n }\n\n setMode(mode: number) {\n if (!VALID_MODES.includes(mode)) {\n throw new OmniValidationError(\n `Heater mode ${mode} is not one of ${VALID_MODES.map((code) => `${code} (${HEATER_MODE[code]})`).join(\", \")}`,\n );\n }\n return this.omni.command(\"SetUIHeaterModeCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: mode,\n });\n }\n\n get silentMode() {\n return this.#runningState.silentMode !== 0;\n }\n\n setSilentMode(on: boolean) {\n return this.omni.command(\"SetHeaterSilentMode\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n get cooldown() {\n return this.#config.cooldownEnabled;\n }\n\n setCooldown(on: boolean) {\n return this.omni.command(\"SetHeaterCoolDown\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n get extend() {\n return this.#config.extendEnabled;\n }\n\n setExtend(on: boolean) {\n return this.omni.command(\"SetHeaterExtend\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n async autoDifferential() {\n const r = await this.omni.command(\"GetHeaterAutoDifferential\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n });\n return r.data;\n }\n\n setAutoDifferential(degrees: number) {\n return this.omni.command(\"SetHeaterAutoDifferential\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: degrees,\n });\n }\n\n #first() {\n const first = this.appliances[0];\n if (first === undefined) {\n throw new OmniLogicError(`No heat source configured for \"${this.name}\"`);\n }\n return first;\n }\n\n get allowLowSpeed() {\n return this.#first().allowLowSpeed;\n }\n\n setAllowLowSpeed(on: boolean) {\n return this.#first().setAllowLowSpeed(on);\n }\n\n get lowSpeed() {\n return this.#first().lowSpeed;\n }\n\n setLowSpeed(value: number) {\n return this.#first().setLowSpeed(value);\n }\n}\n","// the Universal ColorLogic (UCL) show table: base 0–16, V2 tail 17–27\nexport const ColorLogicShow = {\n VOODOO_LOUNGE: 0,\n DEEP_BLUE_SEA: 1,\n ROYAL_BLUE: 2,\n AFTERNOON_SKY: 3,\n AQUA_GREEN: 4,\n EMERALD: 5,\n CLOUD_WHITE: 6,\n WARM_RED: 7,\n FLAMINGO: 8,\n VIVID_VIOLET: 9,\n SANGRIA: 10,\n TWILIGHT: 11,\n TRANQUILITY: 12,\n GEMSTONE: 13,\n USA: 14,\n MARDI_GRAS: 15,\n COOL_CABARET: 16,\n YELLOW: 17,\n ORANGE: 18,\n GOLD: 19,\n MINT: 20,\n TEAL: 21,\n BURNT_ORANGE: 22,\n PURE_WHITE: 23,\n CRISP_WHITE: 24,\n WARM_WHITE: 25,\n BRIGHT_YELLOW: 26,\n WATERFIRE: 27,\n} as const;\n\nexport const ColorLogicPowerState = {\n OFF: 0,\n POWERING_OFF: 1,\n RESETTING: 2,\n CHANGING_SHOW: 3,\n FIFTEEN_SECONDS_WHITE: 4,\n ACTIVE: 6,\n COOLDOWN: 7,\n} as const;\n\nexport const powerStateName = (code: number | undefined) =>\n Object.entries(ColorLogicPowerState).find(([, v]) => v === code)?.[0] ??\n `#${String(code)}`;\n\n// lit or warming up, with on its way off counting as off\nexport const isLightLit = (state: number) =>\n state === ColorLogicPowerState.CHANGING_SHOW ||\n state === ColorLogicPowerState.FIFTEEN_SECONDS_WHITE ||\n state === ColorLogicPowerState.ACTIVE;\n\ntype ShowEntry = [number, string];\n\n// ColorLogic 2.5 and ColorLogic 4.0\nconst SHOWS_25_40: ShowEntry[] = [\n [0, \"VOODOO_LOUNGE\"],\n [1, \"DEEP_BLUE_SEA\"],\n [2, \"AFTERNOON_SKY\"],\n [3, \"EMERALD\"],\n [4, \"SANGRIA\"],\n [5, \"CLOUD_WHITE\"],\n [6, \"TWILIGHT\"],\n [7, \"TRANQUILITY\"],\n [8, \"GEMSTONE\"],\n [9, \"USA\"],\n [10, \"MARDI_GRAS\"],\n [11, \"COOL_CABARET\"],\n];\n\nconst SHOWS_UCL_V2: ShowEntry[] = Object.entries(ColorLogicShow).map(\n ([name, value]) => [value, name],\n);\nconst SHOWS_UCL: ShowEntry[] = SHOWS_UCL_V2.filter(([value]) => value <= 16);\n\n// Pentair Color LED (P-COLOR)\nconst SHOWS_PENTAIR: ShowEntry[] = [\n [0, \"SAM\"],\n [1, \"PARTY\"],\n [2, \"ROMANCE\"],\n [3, \"CARIBBEAN\"],\n [4, \"AMERICAN\"],\n [5, \"CALIFORNIA_SUNSET\"],\n [6, \"ROYAL\"],\n [7, \"BLUE\"],\n [8, \"GREEN\"],\n [9, \"RED\"],\n [10, \"WHITE\"],\n [11, \"MAGENTA\"],\n];\n\n// Jandy Color LED (Z-Color)\nconst SHOWS_ZODIAC: ShowEntry[] = [\n [0, \"ALPINE_WHITE\"],\n [1, \"SKY_BLUE\"],\n [2, \"COBALT_BLUE\"],\n [3, \"CARIBBEAN_BLUE\"],\n [4, \"SPRING_GREEN\"],\n [5, \"EMERALD_GREEN\"],\n [6, \"EMERALD_ROSE\"],\n [7, \"MAGENTA\"],\n [8, \"VIOLET\"],\n [9, \"SLOW_COLOR_SPLASH\"],\n [10, \"FAST_COLOR_SPLASH\"],\n [11, \"AMERICA_THE_BEAUTIFUL\"],\n [12, \"FAT_TUESDAY\"],\n [13, \"DISCO_TECH\"],\n];\n\nexport type LightShowInfo = {\n value: number;\n name: string;\n};\n\nexport const getAvailableShows = (\n lightType: string,\n v2Active: boolean = false,\n) => {\n let entries: ShowEntry[];\n switch (lightType) {\n case \"COLOR_LOGIC_2_5\":\n case \"COLOR_LOGIC_4_0\":\n entries = SHOWS_25_40;\n break;\n case \"COLOR_LOGIC_UCL\":\n case \"COLOR_LOGIC_SAM\":\n entries = v2Active ? SHOWS_UCL_V2 : SHOWS_UCL;\n break;\n case \"CL_P_COLOR\":\n entries = SHOWS_PENTAIR;\n break;\n case \"CL_Z_COLOR\":\n entries = SHOWS_ZODIAC;\n break;\n default:\n entries = SHOWS_UCL;\n break;\n }\n return entries.map(([value, name]) => ({ value, name }));\n};\n","type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"off\";\n\ntype EmittedLevel = Exclude<LogLevel, \"off\">;\n\ntype LogFields = Record<string, unknown>;\n\ntype Logger = Record<\n EmittedLevel,\n (message: string, fields?: LogFields) => void\n>;\n\nconst LOG_RANK: Record<LogLevel, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n off: 100,\n};\n\nconst DEFAULT_LEVEL: LogLevel = \"warn\";\n\nconst isLogLevel = (value: unknown): value is LogLevel =>\n typeof value === \"string\" && Object.hasOwn(LOG_RANK, value);\n\nconst currentLevel = () => {\n const level = process.env.LOG_LEVEL;\n return isLogLevel(level) ? level : DEFAULT_LEVEL;\n};\n\nexport const createLogger = (namespace: string): Logger => {\n const emit = (level: EmittedLevel, message: string, fields?: LogFields) => {\n if (LOG_RANK[level] < LOG_RANK[currentLevel()]) {\n return;\n }\n\n const errors: Error[] = [];\n let tail = \"\";\n for (const [key, value] of Object.entries(fields ?? {})) {\n if (value instanceof Error) {\n errors.push(value);\n } else {\n tail += ` ${key}=${String(value)}`;\n }\n }\n console.error(\n `${level.padEnd(5)} [${namespace}] ${message}${tail}`,\n ...errors,\n );\n };\n\n return {\n trace: (message, fields) => emit(\"trace\", message, fields),\n debug: (message, fields) => emit(\"debug\", message, fields),\n info: (message, fields) => emit(\"info\", message, fields),\n warn: (message, fields) => emit(\"warn\", message, fields),\n error: (message, fields) => emit(\"error\", message, fields),\n };\n};\n","import { setTimeout } from \"node:timers/promises\";\n\nimport type { CommandOptions } from \"@/client/omnilogic\";\nimport { LIGHT_BRIGHTNESS, LIGHT_SPEED } from \"@/constants/labels\";\nimport {\n ColorLogicPowerState,\n getAvailableShows,\n isLightLit,\n powerStateName,\n} from \"@/constants/lightShows\";\nimport { Device } from \"@/equipment/device\";\nimport { timerParams } from \"@/utils/command\";\nimport {\n OmniLogicError,\n OmniTimeoutError,\n OmniValidationError,\n ReadingUnavailableError,\n} from \"@/utils/errors\";\nimport { findBySystemId, stringOf } from \"@/utils/helpers\";\nimport { createLogger } from \"@/utils/logger\";\n\nconst equipmentLog = createLogger(\"equipment\");\n\nexport type LightWriteOptions = Pick<\n CommandOptions,\n \"attempts\" | \"force\" | \"pollMs\" | \"timeoutMs\"\n> & {\n // \"1/16x\" to \"16x\", default the current speed\n speed?: string;\n // 20 to 100 in steps of 20, default the current brightness\n brightness?: number;\n // default true, false throws on a light mid-transition instead of waiting\n wait?: boolean;\n};\n\nconst encodeShow = (show: number, speed: string, brightness: number) => {\n const speedCode = Object.entries(LIGHT_SPEED).find(\n ([, label]) => label === speed,\n )?.[0];\n if (speedCode === undefined) {\n throw new OmniValidationError(\n `light speed \"${speed}\" is not one of ${Object.values(LIGHT_SPEED).join(\", \")}`,\n );\n }\n const brightnessCode = Object.entries(LIGHT_BRIGHTNESS).find(\n ([, percent]) => percent === brightness,\n )?.[0];\n if (brightnessCode === undefined) {\n throw new OmniValidationError(\n `light brightness ${brightness} is not one of ${Object.values(LIGHT_BRIGHTNESS).join(\", \")}`,\n );\n }\n return {\n data: show,\n field19: Number(speedCode),\n field1a: Number(brightnessCode),\n field1b: 0,\n };\n};\n\n// the wait between telemetry reads\nconst DEFAULT_POLL_MS = 4000;\n// a show change registers within this after the send\nconst DEFAULT_VERIFY_MS = 30000;\n// a light reaches OFF or ACTIVE within this\nconst SETTLE_MS = 60000;\n\nconst verifyOptions = (\n options: LightWriteOptions,\n verify: () => boolean,\n failure: string,\n) => ({\n verify,\n timeoutMs: options.timeoutMs ?? DEFAULT_VERIFY_MS,\n pollMs: options.pollMs ?? DEFAULT_POLL_MS,\n attempts: options.attempts,\n force: options.force,\n failure,\n});\n\nexport class Light extends Device {\n // undefined when telemetry has no row for this light\n get state() {\n return this.omni.telemetry.colorLogicLights.find(\n (l) => l.systemId === this.equipmentId,\n );\n }\n\n get #reported() {\n return this.running ? this.state : undefined;\n }\n\n get #config() {\n const light = findBySystemId(this.omni.config, this.equipmentId);\n return {\n type: stringOf(light?.type) ?? \"\",\n v2Active: light?.v2Active === true,\n };\n }\n\n get omniDirect() {\n return this.#config.v2Active;\n }\n\n get shows() {\n const { type, v2Active } = this.#config;\n return getAvailableShows(type, v2Active);\n }\n\n #readOr<T>(read: () => T | undefined, fallback: T) {\n try {\n const value = read();\n return value === undefined || value === \"Unknown\" ? fallback : value;\n } catch (error) {\n if (error instanceof ReadingUnavailableError) {\n return fallback;\n }\n throw error;\n }\n }\n\n get powerState() {\n const row = this.#reported;\n return row === undefined ? \"OFF\" : powerStateName(row.lightState);\n }\n\n get show() {\n this.requireRunning();\n const current = this.state?.currentShow;\n return this.shows.find((s) => s.value === current)?.name ?? \"Unknown\";\n }\n\n get speed() {\n this.requireRunning();\n const row = this.state;\n return row === undefined\n ? \"Unknown\"\n : (LIGHT_SPEED[row.speed] ?? \"Unknown\");\n }\n\n get brightness() {\n this.requireRunning();\n const row = this.state;\n return row === undefined ? undefined : LIGHT_BRIGHTNESS[row.brightness];\n }\n\n get isOn() {\n const row = this.#reported;\n return row !== undefined && isLightLit(row.lightState);\n }\n\n #requireOmniDirect(options: { speed?: string; brightness?: number }) {\n if (\n (options.speed !== undefined || options.brightness !== undefined) &&\n !this.omniDirect\n ) {\n throw new OmniValidationError(\n `\"${this.name}\" is not in OmniDirect mode, so it does not support speed or brightness`,\n );\n }\n }\n\n showParams(\n show: number,\n options: { speed?: string; brightness?: number } = {},\n ) {\n this.#requireOmniDirect(options);\n if (!this.omniDirect) {\n return { data: show, field19: 0, field1a: 0, field1b: 0 };\n }\n return encodeShow(\n show,\n options.speed ?? this.#readOr(() => this.speed, \"1x\"),\n options.brightness ?? this.#readOr(() => this.brightness, 100),\n );\n }\n\n async setShow(show: number, options: LightWriteOptions = {}) {\n this.#requireOmniDirect(options);\n await this.#waitUntilStable(`show ${show}`, options);\n if (!options.force && !this.shows.some((s) => s.value === show)) {\n throw new OmniValidationError(\n `\"${this.name}\" has no show ${show}; its shows are 0 to ${Math.max(...this.shows.map((s) => s.value))}`,\n );\n }\n await this.omni.command(\n \"SetStandAloneLightShow\",\n {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n ...this.showParams(show, options),\n ...timerParams(),\n },\n verifyOptions(\n options,\n () =>\n this.state?.currentShow === show &&\n (options.speed === undefined ||\n this.#readOr(() => this.speed, \"\") === options.speed) &&\n (options.brightness === undefined ||\n this.#readOr(() => this.brightness, -1) === options.brightness),\n `Unable to set \"${this.name}\" to show ${show}`,\n ),\n );\n }\n\n on(options: LightWriteOptions = {}) {\n return this.#setPower(true, options);\n }\n\n off(options: LightWriteOptions = {}) {\n return this.#setPower(false, options);\n }\n\n async #setPower(on: boolean, options: LightWriteOptions) {\n await this.#waitUntilStable(on ? \"power on\" : \"power off\", options);\n await this.omni.command(\n \"SetUIEquipmentCmd\",\n {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n isOn: Number(on),\n ...timerParams(),\n },\n verifyOptions(\n options,\n // any move away from the old state counts\n () => {\n const row = this.state;\n return (\n row !== undefined &&\n row.lightState !==\n (on ? ColorLogicPowerState.OFF : ColorLogicPowerState.ACTIVE)\n );\n },\n `Unable to turn \"${this.name}\" ${on ? \"on\" : \"off\"}`,\n ),\n );\n }\n\n async #waitUntilStable(action: string, options: LightWriteOptions) {\n const { wait = true, pollMs = DEFAULT_POLL_MS } = options;\n await this.omni.refresh({ refetch: true, force: options.force });\n if (this.state === undefined) {\n if (options.force) {\n return;\n }\n throw new OmniLogicError(\n `The controller reports no telemetry for \"${this.name}\"; pass { force: true } to send anyway`,\n );\n }\n if (this.#isStable()) {\n equipmentLog.trace(\"light is stable\", {\n light: this.name,\n state: powerStateName(this.state?.lightState),\n });\n return;\n }\n if (!wait) {\n throw new OmniValidationError(\n `\"${this.name}\" is transitioning ` +\n `(${powerStateName(this.state?.lightState)}); ${action} would be silently ignored`,\n );\n }\n equipmentLog.debug(\"light is transitioning; waiting for a stable state\", {\n light: this.name,\n state: powerStateName(this.state?.lightState),\n action,\n pollMs,\n settleTimeoutMs: SETTLE_MS,\n });\n const started = Date.now();\n const deadline = started + SETTLE_MS;\n while (Date.now() < deadline) {\n await setTimeout(pollMs);\n await this.omni\n .refresh({ refetch: true, force: options.force })\n .catch((error: unknown) => {\n equipmentLog.trace(\"refresh failed while waiting for the light\", {\n light: this.name,\n error,\n });\n });\n if (this.#isStable()) {\n equipmentLog.debug(\"light settled\", {\n light: this.name,\n state: powerStateName(this.state?.lightState),\n ms: Date.now() - started,\n });\n return;\n }\n equipmentLog.trace(\"light still transitioning\", {\n light: this.name,\n state: powerStateName(this.state?.lightState),\n ms: Date.now() - started,\n });\n }\n throw new OmniTimeoutError(\n `Timed out waiting for \"${this.name}\" to settle`,\n );\n }\n\n #isStable() {\n const s = this.state?.lightState;\n return s === ColorLogicPowerState.OFF || s === ColorLogicPowerState.ACTIVE;\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { RELAY_STATE, RELAY_WHY_ON } from \"@/constants/labels\";\nimport { Device } from \"@/equipment/device\";\nimport type { Relay as RelayConfig } from \"@/types/config\";\nimport { countdownParams, timerParams } from \"@/utils/command\";\n\nexport class Relay extends Device {\n #type: string;\n #function: string;\n\n constructor(omni: OmniLogic, poolId: number, config: RelayConfig) {\n super(omni, poolId, config.systemId, config.name);\n this.#type = config.type;\n this.#function = config.function;\n }\n\n get type() {\n return this.#type;\n }\n\n get function() {\n return this.#function;\n }\n\n // the filter pump speed set when this feature turns on, held until the next schedule\n get valveDefaultSpeed() {\n return this.bodyConfig?.relays.find((r) => r.systemId === this.equipmentId)\n ?.valveDefaultSpeed;\n }\n\n get #rows() {\n const t = this.omni.telemetry;\n return [...t.relays, ...t.valveActuators, ...t.smartValveActuators];\n }\n\n get state() {\n return this.telemetry(this.#rows);\n }\n\n get #reported() {\n return this.reportedIn(this.#rows);\n }\n\n get #position() {\n const row = this.state;\n return \"relayState\" in row ? row.relayState : row.valveActuatorState;\n }\n\n get status() {\n return this.#reported ? (RELAY_STATE[this.#position] ?? \"Unknown\") : \"Off\";\n }\n\n get isOn() {\n return this.#reported && this.#position !== 0;\n }\n\n // where a smart valve actuator is driving to, and undefined for the rest\n get smartValveTarget() {\n return this.omni.telemetry.smartValveActuators.find(\n (r) => r.systemId === this.equipmentId,\n )?.smartValveTarget;\n }\n\n get whyOn() {\n return this.#reported\n ? (RELAY_WHY_ON[this.state.whyOn] ?? \"Unknown\")\n : \"No Message\";\n }\n\n get onCountdown() {\n return this.#reported && this.state.whyOn === 6; // Countdown Timer\n }\n\n #setState(on: boolean) {\n return this.omni.command(\"SetUIEquipmentCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n isOn: Number(on),\n ...timerParams(),\n });\n }\n\n on() {\n return this.#setState(true);\n }\n\n off() {\n return this.#setState(false);\n }\n\n async remainingCountdownTime() {\n const r = await this.omni.command(\"GetRemainingCountdownTime\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n });\n return r.hour * 60 + r.minute;\n }\n\n setCountdownTime(minutes: number) {\n return this.omni.command(\"SetUIEquipmentCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n isOn: 1,\n ...countdownParams(minutes),\n });\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { isRunning } from \"@/constants/labels\";\nimport { WATER_TEMP_UNAVAILABLE } from \"@/constants/sentinels\";\nimport { Chlorinator } from \"@/equipment/chlorinator\";\nimport { CSAD } from \"@/equipment/csad\";\nimport { Filter } from \"@/equipment/filter\";\nimport { Heater } from \"@/equipment/heater\";\nimport { Light } from \"@/equipment/light\";\nimport { Pump } from \"@/equipment/pump\";\nimport { Relay } from \"@/equipment/relay\";\nimport type { BodyOfWater as BodyOfWaterConfig } from \"@/types/config\";\nimport { OmniLogicError } from \"@/utils/errors\";\nimport { hasSystemId } from \"@/utils/inventory\";\n\nexport class BodyOfWater {\n #systemId: number;\n #name: string;\n #type: string;\n #filter?: Filter;\n #pumps: Pump[];\n #heater?: Heater;\n #chlorinator?: Chlorinator;\n #csad?: CSAD;\n #lights: Light[];\n #relays: Relay[];\n #omni: OmniLogic;\n\n get systemId() {\n return this.#systemId;\n }\n\n get name() {\n return this.#name;\n }\n\n get type() {\n return this.#type;\n }\n\n get #config() {\n const found = this.#omni.config.backyard.bodiesOfWater.find(\n (b) => b.systemId === this.systemId,\n );\n if (found === undefined) {\n throw new OmniLogicError(`No configuration for \"${this.name}\"`);\n }\n return found;\n }\n\n get spilloverEnabled() {\n return this.#config.supportsSpillover;\n }\n\n get filter() {\n return this.#filter;\n }\n\n // every pump on the body, the filter pump first when there is one\n get pumps() {\n return [...this.#pumps];\n }\n\n get heater() {\n return this.#heater;\n }\n\n get chlorinator() {\n return this.#chlorinator;\n }\n\n get csad() {\n return this.#csad;\n }\n\n get lights() {\n return [...this.#lights];\n }\n\n get relays() {\n return [...this.#relays];\n }\n\n constructor(omni: OmniLogic, config: BodyOfWaterConfig) {\n const poolId = config.systemId;\n this.#omni = omni;\n this.#systemId = poolId;\n this.#name = config.name;\n this.#type = config.type;\n\n this.#filter = hasSystemId(config.filter)\n ? new Filter(omni, poolId, config.filter)\n : undefined;\n this.#pumps = [\n ...(this.#filter === undefined ? [] : [this.#filter]),\n ...config.pumps.map((p) => new Pump(omni, poolId, p)),\n ];\n this.#heater = hasSystemId(config.heater)\n ? new Heater(\n omni,\n poolId,\n config.heater.systemId,\n `${config.name} Heater`,\n )\n : undefined;\n this.#chlorinator = hasSystemId(config.chlorinator)\n ? new Chlorinator(\n omni,\n poolId,\n config.chlorinator.systemId,\n config.chlorinator.name,\n )\n : undefined;\n this.#csad = hasSystemId(config.csad)\n ? new CSAD(omni, poolId, config.csad)\n : undefined;\n this.#lights = config.colorLogicLights.map(\n (l) => new Light(omni, poolId, l.systemId, l.name),\n );\n this.#relays = config.relays.map((r) => new Relay(omni, poolId, r));\n }\n\n get state() {\n const row = this.#omni.telemetry.bodiesOfWater.find(\n (b) => b.systemId === this.systemId,\n );\n if (row === undefined) {\n throw new OmniLogicError(`No telemetry for \"${this.name}\"`);\n }\n return row;\n }\n\n get #reportedFilter() {\n const filter = this.filter;\n return filter !== undefined &&\n this.#omni.telemetry.filters.some(\n (r) => r.systemId === filter.equipmentId,\n )\n ? filter\n : undefined;\n }\n\n get waterTemp() {\n if (!isRunning(this.#omni.telemetry.backyard.state)) {\n return undefined;\n }\n const temp = this.state.waterTemp;\n return temp === WATER_TEMP_UNAVAILABLE ? undefined : temp;\n }\n\n get spilloverOn() {\n const filter = this.#reportedFilter;\n return (\n filter !== undefined && filter.running && filter.state.valvePosition === 3 // Spillover\n );\n }\n\n get spilloverOnCountdown() {\n const filter = this.#reportedFilter;\n return (\n filter !== undefined &&\n filter.running &&\n filter.state.whyFilterIsOn === 17 // Spillover Countdown Timer\n );\n }\n\n setSpilloverEnabled(on: boolean) {\n return this.#omni.command(\"SetSpaSpilloverEnable\", {\n poolId: this.systemId,\n data: Number(on),\n });\n }\n}\n","import type { OmniLogic, WriteOptions } from \"@/client/omnilogic\";\nimport { OmniValidationError } from \"@/utils/errors\";\nimport { matches } from \"@/utils/helpers\";\n\n// the data a theme favorite carries in place of a show\nexport const THEME_FAVORITE_DATA = 268435455;\n\nexport type FavoriteCreate = {\n equipmentId: number;\n // the show number for a light, 0 for anything else\n data: number;\n};\n\nexport class Favorites {\n #omni: OmniLogic;\n\n constructor(omni: OmniLogic) {\n this.#omni = omni;\n }\n\n list() {\n return this.#omni.config.favorites;\n }\n\n get(indexId: number) {\n return this.list().find((f) => f.indexId === indexId);\n }\n\n async create(spec: FavoriteCreate, options: WriteOptions = {}) {\n const record = { equipmentIdOrThemeId: spec.equipmentId, data: spec.data };\n const before = new Set(this.list().map((f) => f.systemId));\n const created = () =>\n this.list().find((f) => !before.has(f.systemId) && matches(f, record));\n await this.#omni.command(\n \"CreateUIFavoriteCmd\",\n { equipmentId: spec.equipmentId, data: spec.data },\n {\n verify: () => created() !== undefined,\n attempts: options.attempts,\n failure: `Unable to create favorite for equipment ${spec.equipmentId}`,\n },\n );\n return created()!;\n }\n\n createForTheme(themeId: number, options: WriteOptions = {}) {\n return this.create(\n { equipmentId: themeId, data: THEME_FAVORITE_DATA },\n options,\n );\n }\n\n async remove(indexId: number, options: WriteOptions = {}) {\n const favorite = this.get(indexId);\n if (favorite === undefined) {\n throw new OmniValidationError(\n `No favorite at index ${indexId} in the cached config`,\n );\n }\n // a favorite is identified by its system id, an index is a display slot\n const removed = favorite.systemId;\n await this.#omni.command(\n \"DeleteUIFavoriteCmd\",\n { data: indexId },\n {\n verify: () => !this.list().some((f) => f.systemId === removed),\n attempts: options.attempts,\n failure: `Unable to delete favorite ${indexId}`,\n },\n );\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport type { UnitSystem } from \"@/types/config\";\nimport { OmniValidationError } from \"@/utils/errors\";\n\nexport type SpeedFormat = \"RPM\" | \"Percent\";\nexport type ChlorinatorDisplay = \"Salt\" | \"Minerals\";\n\nexport class Panel {\n #omni: OmniLogic;\n\n constructor(omni: OmniLogic) {\n this.#omni = omni;\n }\n\n get omni() {\n return this.#omni;\n }\n\n get #system() {\n return this.omni.config.system;\n }\n\n async beeper() {\n const r = await this.omni.command(\"GetBeeper\");\n return r.enabled;\n }\n\n setBeeper(on: boolean) {\n return this.omni.command(\"SetBeeper\", { data: Number(on) });\n }\n\n async backLight() {\n const r = await this.omni.command(\"GetBackLight\");\n return r.state;\n }\n\n setBackLight(on: boolean) {\n return this.omni.command(\"SetBackLight\", { data: Number(on) });\n }\n\n async backLightBrightness() {\n const r = await this.omni.command(\"GetBackLightBrightness\");\n return r.brightness;\n }\n\n setBackLightBrightness(percent: number) {\n return this.omni.command(\"SetBackLightBrightness\", { data: percent });\n }\n\n async backLightTimeout() {\n const r = await this.omni.command(\"GetBackLightTimeout\");\n return r.timeout;\n }\n\n setBackLightTimeout(seconds: number) {\n return this.omni.command(\"SetBackLightTimeout\", { data: seconds });\n }\n\n get vspSpeedFormat(): SpeedFormat {\n return this.#system.mspVspSpeedFormat === \"RPM\" ? \"RPM\" : \"Percent\";\n }\n\n setVspSpeedFormat(format: SpeedFormat) {\n return this.omni.command(\"SetVSPSpeedFormat\", {\n data: format === \"RPM\" ? 1 : 0,\n });\n }\n\n get chlorinatorDisplay(): ChlorinatorDisplay {\n return this.#system.mspChlorDisplay === \"Salt\" ? \"Salt\" : \"Minerals\";\n }\n\n setChlorinatorDisplay(display: ChlorinatorDisplay) {\n return this.omni.command(\"SetCHLORDisplay\", {\n data: display === \"Salt\" ? 1 : 0,\n });\n }\n\n // the controller words it \"12 Hour Format\"\n get timeFormat() {\n return parseInt(this.#system.mspTimeFormat, 10);\n }\n\n setTimeFormat(hours: number) {\n if (hours !== 12 && hours !== 24) {\n throw new OmniValidationError(`Time format ${hours} is not 12 or 24`);\n }\n return this.omni.command(\"SetTimeFormat\", { data: hours });\n }\n\n async units() {\n const r = await this.omni.command(\"GetUnits\");\n return r.unitFormat ? \"Metric\" : \"Standard\";\n }\n\n setUnits(units: UnitSystem) {\n return this.omni.command(\"SetUnits\", {\n data: units === \"Metric\" ? 1 : 0,\n });\n }\n\n async coordinates() {\n const r = await this.omni.command(\"GetCoordinates\");\n return {\n latitude: r.latitude,\n longitude: r.longitude,\n };\n }\n\n setCoordinates(latitude: number, longitude: number) {\n return this.omni.command(\"SetCoordinates\", { latitude, longitude });\n }\n}\n","import type { OmniLogic, WriteOptions } from \"@/client/omnilogic\";\nimport type { ScheduleCreate } from \"@/equipment/schedules\";\nimport { countdownParams, timerParams } from \"@/utils/command\";\nimport { OmniValidationError } from \"@/utils/errors\";\n\nexport class Themes {\n #omni: OmniLogic;\n\n constructor(omni: OmniLogic) {\n this.#omni = omni;\n }\n\n list() {\n return this.#omni.config.themes;\n }\n\n // any body's id will do\n get #groupFields() {\n const [body] = this.#omni.config.backyard.bodiesOfWater;\n if (body === undefined) {\n throw new OmniValidationError(\"No body of water in the cached config\");\n }\n return { daysActive: 0, recurring: 0, poolId: body.systemId };\n }\n\n get activeIds() {\n return this.#omni.telemetry.themes\n .filter((g) => g.groupState !== 0)\n .map((g) => g.systemId);\n }\n\n get(themeId: number) {\n return this.list().find((g) => g.systemId === themeId);\n }\n\n async create(name: string, options: WriteOptions = {}) {\n const before = new Set(this.list().map((g) => g.systemId));\n const created = () =>\n this.list().find((g) => !before.has(g.systemId) && g.name === name);\n await this.#omni.command(\n \"SaveNewGroupCmd\",\n { name, ...this.#groupFields },\n {\n verify: () => created() !== undefined,\n attempts: options.attempts,\n failure: `Unable to create theme \"${name}\"`,\n },\n );\n return created()!;\n }\n\n async rename(themeId: number, name: string, options: WriteOptions = {}) {\n if (this.list().some((g) => g.systemId !== themeId && g.name === name)) {\n throw new OmniValidationError(`A theme named \"${name}\" already exists`);\n }\n await this.#omni.command(\n \"SetGroupCmd\",\n { equipmentId: themeId, name, ...this.#groupFields },\n {\n verify: () => this.get(themeId)?.name === name,\n attempts: options.attempts,\n failure: `Unable to rename theme ${themeId} to \"${name}\"`,\n },\n );\n }\n\n async run(\n themeId: number,\n on = true,\n { minutes }: { minutes?: number } = {},\n ) {\n await this.#omni.command(\"RunGroupCmd\", {\n equipmentId: themeId,\n data: on ? 1 : 0,\n ...(on && minutes !== undefined\n ? countdownParams(minutes)\n : timerParams()),\n });\n }\n\n schedule(\n themeId: number,\n window: Omit<ScheduleCreate, \"equipmentId\" | \"data\" | \"type\">,\n ) {\n return this.#omni.backyard.schedules.create({\n ...window,\n equipmentId: themeId,\n data: 1,\n type: \"theme\",\n });\n }\n\n async remove(themeId: number, options: WriteOptions = {}) {\n if (this.get(themeId) === undefined) {\n throw new OmniValidationError(`No theme ${themeId} in the cached config`);\n }\n await this.#omni.command(\n \"DeleteGroupCmd\",\n { equipmentId: themeId },\n {\n verify: () => this.get(themeId) === undefined,\n attempts: options.attempts,\n failure: `Unable to delete theme ${themeId}`,\n },\n );\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { isRunning, SYSTEM_STATE } from \"@/constants/labels\";\nimport { AIR_TEMP_UNAVAILABLE } from \"@/constants/sentinels\";\nimport { BodyOfWater } from \"@/equipment/bodyOfWater\";\nimport { Favorites } from \"@/equipment/favorites\";\nimport { Light } from \"@/equipment/light\";\nimport { Panel } from \"@/equipment/panel\";\nimport { Relay } from \"@/equipment/relay\";\nimport { Schedules } from \"@/equipment/schedules\";\nimport { Themes } from \"@/equipment/themes\";\nimport { OmniLogicError } from \"@/utils/errors\";\n\nexport class Backyard {\n #omni: OmniLogic;\n\n constructor(omni: OmniLogic) {\n this.#omni = omni;\n }\n\n get schedules() {\n return new Schedules(this.#omni);\n }\n\n get favorites() {\n return new Favorites(this.#omni);\n }\n\n get themes() {\n return new Themes(this.#omni);\n }\n\n get panel() {\n return new Panel(this.#omni);\n }\n\n get state() {\n return this.#omni.telemetry.backyard;\n }\n\n get running() {\n return isRunning(this.state.state);\n }\n\n get systemState() {\n return SYSTEM_STATE[this.state.state] ?? \"Unknown\";\n }\n\n get airTemp() {\n const temp = this.state.airTemp;\n return !this.running || temp === AIR_TEMP_UNAVAILABLE ? undefined : temp;\n }\n\n get bodies() {\n return this.#omni.config.backyard.bodiesOfWater.map(\n (raw) => new BodyOfWater(this.#omni, raw),\n );\n }\n\n get lights() {\n const backyard = this.#omni.config.backyard;\n return backyard.colorLogicLights.map(\n (l) => new Light(this.#omni, backyard.systemId, l.systemId, l.name),\n );\n }\n\n get relays() {\n const backyard = this.#omni.config.backyard;\n return backyard.relays.map(\n (r) => new Relay(this.#omni, backyard.systemId, r),\n );\n }\n\n body(nameOrId: string | number) {\n return this.bodies.find((b) =>\n typeof nameOrId === \"number\"\n ? b.systemId === nameOrId\n : b.name.toLowerCase() === nameOrId.toLowerCase(),\n );\n }\n\n get pool() {\n return this.#ofType(\"BOW_POOL\");\n }\n\n get spa() {\n return this.#ofType(\"BOW_SPA\");\n }\n\n #ofType(type: string) {\n const matches = this.bodies.filter((b) => b.type === type);\n if (matches.length > 1) {\n throw new OmniLogicError(\n `This system has more than one body of water of type ${type}; use body(nameOrId) or bodies`,\n );\n }\n return matches[0];\n }\n}\n","import type { CommandOpcode, SWITCH_OPCODE } from \"@/client/spec\";\n\n// acknowledgment of a controller message, sent with that message's id\nexport const OUTBOUND_ACK = 0;\n\nexport const INBOUND_FRAME = {\n ack: 1002,\n // an unsolicited telemetry push, always compressed\n telemetryUpdate: 1004,\n // header of a split payload, declaring how many blocks follow\n leadMessage: 1998,\n // one block of a split payload\n blockMessage: 1999,\n} as const;\n\nexport type SendableOpcode =\n | CommandOpcode\n | (typeof SWITCH_OPCODE)[keyof typeof SWITCH_OPCODE]\n | typeof OUTBOUND_ACK;\n\nexport const isAck = (opCode: number) =>\n opCode === OUTBOUND_ACK || opCode === INBOUND_FRAME.ack;\n\nexport class OmniLogicMessage {\n id: number;\n opCode: number;\n payload: Buffer;\n // 0=request with body, 1=bare request, 2=panel, 3=peer controller\n clientType: number;\n version: string;\n timestamp: number = Math.floor(Date.now() / 1000);\n compressed: boolean = false;\n\n constructor(\n messageId: number,\n opCode: number,\n payload: string | null = null,\n version: string = \"1.19\",\n ) {\n this.id = messageId;\n this.opCode = opCode;\n this.clientType = payload !== null ? 0 : 1;\n this.payload = Buffer.from(\n payload !== null ? `${payload}\\x00` : \"\",\n \"utf-8\",\n );\n this.version = version;\n }\n\n toBytes() {\n const header = Buffer.alloc(24);\n header.writeUInt32BE(this.id, 0);\n header.writeBigUInt64BE(BigInt(this.timestamp), 4);\n header.write(this.version, 12, \"ascii\");\n header.writeUInt32BE(this.opCode, 16);\n header.writeUInt8(this.clientType, 20);\n header.writeUInt8(this.compressed ? 1 : 0, 22);\n return Buffer.concat([header, this.payload]);\n }\n\n toString() {\n const head =\n `ID: ${this.id}, Type: ${this.opCode}, Compressed: ${this.compressed}, ` +\n `Client: ${this.clientType}, Version: ${this.version}, Timestamp: ${this.timestamp}`;\n // a block or compressed payload is not text\n if (this.opCode === INBOUND_FRAME.blockMessage || this.compressed) {\n return head;\n }\n return `${head}, Body: ${this.payload.subarray(0, -1).toString(\"utf-8\")}`;\n }\n\n static fromBytes(data: Buffer) {\n if (data.length < 24) {\n throw new Error(\"Invalid message: too short\");\n }\n const header = data.subarray(0, 24);\n const version = header\n .subarray(12, 16)\n .toString(\"ascii\")\n .replace(/\\0/g, \"\");\n const message = new OmniLogicMessage(\n header.readUInt32BE(0),\n header.readUInt32BE(16),\n null,\n version,\n );\n message.timestamp = Number(header.readBigUInt64BE(4));\n message.clientType = header.readUInt8(20);\n message.compressed =\n header.readUInt8(22) === 1 ||\n message.opCode === INBOUND_FRAME.telemetryUpdate;\n message.payload = data.subarray(24);\n return message;\n }\n}\n","import type { OmniLogicMessage } from \"@/transport/message\";\nimport { OmniTimeoutError } from \"@/utils/errors\";\nimport { createLogger } from \"@/utils/logger\";\n\nconst protocolLog = createLogger(\"protocol\");\n\ntype PendingResolver = {\n resolve: (value: OmniLogicMessage) => void;\n reject: (reason: Error) => void;\n};\n\nexport class MessageQueue {\n #pendingResolvers: PendingResolver[] = [];\n #queue: OmniLogicMessage[] = [];\n // the error that ended the socket\n #failure: Error | undefined;\n\n add(message: OmniLogicMessage) {\n const next = this.#pendingResolvers.shift();\n if (next) {\n next.resolve(message);\n } else {\n this.#queue.push(message);\n }\n }\n\n next(timeoutMs: number, timeoutMessage: string): Promise<OmniLogicMessage> {\n if (this.#failure !== undefined) {\n return Promise.reject(this.#failure);\n }\n const message = this.#queue.shift();\n if (message !== undefined) {\n return Promise.resolve(message);\n }\n return new Promise((resolve, reject) => {\n const pending: PendingResolver = {\n resolve: (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n reject: (reason) => {\n clearTimeout(timer);\n reject(reason);\n },\n };\n const timer = setTimeout(() => {\n this.#pendingResolvers = this.#pendingResolvers.filter(\n (p) => p !== pending,\n );\n reject(new OmniTimeoutError(timeoutMessage));\n }, timeoutMs);\n this.#pendingResolvers.push(pending);\n });\n }\n\n reset(failure?: Error) {\n this.#failure = failure ?? this.#failure;\n if (this.#pendingResolvers.length > 0 || this.#queue.length > 0) {\n protocolLog.trace(\"queue reset\", {\n waiters: this.#pendingResolvers.length,\n buffered: this.#queue.length,\n });\n }\n for (const pending of this.#pendingResolvers) {\n pending.reject(\n failure ?? new OmniTimeoutError(\"The operation was closed\"),\n );\n }\n this.#pendingResolvers = [];\n this.#queue = [];\n }\n}\n","import { createSocket, type Socket } from \"node:dgram\";\nimport { setTimeout } from \"node:timers/promises\";\nimport { inflateSync } from \"node:zlib\";\n\nimport { SWITCH_OPCODE } from \"@/client/spec\";\nimport {\n INBOUND_FRAME,\n isAck,\n OmniLogicMessage,\n OUTBOUND_ACK,\n type SendableOpcode,\n} from \"@/transport/message\";\nimport { MessageQueue } from \"@/transport/queue\";\nimport { OmniLogicError, OmniTimeoutError } from \"@/utils/errors\";\nimport { defined, isRecord } from \"@/utils/helpers\";\nimport { createLogger } from \"@/utils/logger\";\nimport {\n buildMessageXml,\n parametersByName,\n parseXML,\n type ResponseMessage,\n} from \"@/utils/xml\";\n\nconst protocolLog = createLogger(\"protocol\");\n\n// how many blocks follow and how many bytes of them are payload\nconst parseLeadMessage = (payload: Buffer) => {\n const xml = payload.subarray(0, -1).toString(\"utf-8\");\n const parsed: ResponseMessage = parseXML(xml);\n if (!isRecord(parsed.response) || !isRecord(parsed.response.parameters)) {\n throw new OmniLogicError(`Malformed reply header: ${JSON.stringify(xml)}`);\n }\n const params = parametersByName(parsed.response.parameters.parameter);\n const count = params.msgBlockCount;\n if (typeof count !== \"number\") {\n throw new OmniLogicError(\n `Malformed reply header parameters: ${JSON.stringify(params)}`,\n );\n }\n const size = params.msgSize;\n return {\n blockCount: count,\n msgSize: typeof size === \"number\" && size > 0 ? size : undefined,\n };\n};\n\ntype Connection = {\n socket: Socket;\n queue: MessageQueue;\n timings: Timings;\n};\n\nexport type Timings = {\n // per attempt, before retransmitting\n ackTimeoutMs: number;\n // for the reply, after the send is acknowledged\n nextMessageTimeoutMs: number;\n // after one operation ends and before the next starts, 0 for no gap\n minSendGapMs: number;\n // after a settling command, the pause once the controller answers again\n settleGraceMs: number;\n};\n\nexport const DEFAULT_TIMINGS: Timings = {\n ackTimeoutMs: 5000,\n // the controller retransmits five times at 2.1 s\n nextMessageTimeoutMs: 2.1 * 5 * 1000,\n minSendGapMs: 500,\n settleGraceMs: 2000,\n};\n\nexport type OperationOptions = {\n timings?: Partial<Timings>;\n // the controller goes quiet after this send\n settle?: boolean;\n // how many times to send when the controller acknowledges but never replies, default 1\n attempts?: number;\n // the opcode the reply carries when it arrives in one frame, any other frame is skipped\n reply?: number;\n};\n\nconst ACK_ATTEMPTS = 5;\n\nconst newId = () => Math.floor(Math.random() * 0xffffffff);\n\n// the end of the last queued operation\nlet queueTail = Promise.resolve(0);\n\nexport class OmniLogicProtocol {\n #host: string;\n #port: number;\n #timings: Timings;\n\n constructor(host: string, port: number, timings: Partial<Timings> = {}) {\n this.#host = host;\n this.#port = port;\n this.#timings = { ...DEFAULT_TIMINGS, ...defined(timings) };\n }\n\n get #key() {\n return `${this.#host}:${this.#port}`;\n }\n\n async #waitForTurn(timings: Timings, previous: Promise<number>) {\n const started = Date.now();\n const ended = await previous;\n protocolLog.trace(\"previous operation ended\", {\n key: this.#key,\n waitedMs: Date.now() - started,\n });\n // capped at the gap\n const wait = Math.min(\n timings.minSendGapMs,\n ended + timings.minSendGapMs - Date.now(),\n );\n if (wait > 0) {\n protocolLog.debug(\"throttling\", { key: this.#key, waitMs: wait });\n await setTimeout(wait);\n }\n }\n\n async #settle(timings: Timings) {\n protocolLog.debug(\"settling\", { key: this.#key });\n const started = Date.now();\n let conn: Connection;\n try {\n conn = await this.#open(timings);\n } catch (error) {\n protocolLog.warn(\"could not open a socket to settle; releasing\", {\n key: this.#key,\n error,\n });\n return;\n }\n try {\n await this.#send(conn, SWITCH_OPCODE.GetTelemetry, null);\n await this.#processResponse(conn, INBOUND_FRAME.telemetryUpdate);\n protocolLog.trace(\"controller answered the settle probe\", {\n key: this.#key,\n ms: Date.now() - started,\n });\n } catch (error) {\n protocolLog.warn(\"controller did not answer while settling; releasing\", {\n key: this.#key,\n error,\n });\n } finally {\n this.#close(conn);\n }\n if (timings.settleGraceMs > 0) {\n protocolLog.trace(\"settle grace\", {\n key: this.#key,\n ms: timings.settleGraceMs,\n });\n await setTimeout(timings.settleGraceMs);\n }\n protocolLog.debug(\"settled; releasing queued operations\", {\n key: this.#key,\n ms: Date.now() - started,\n });\n }\n\n async #withConnection<T>(\n options: OperationOptions,\n fn: (conn: Connection) => Promise<T>,\n ) {\n const timings = { ...this.#timings, ...defined(options.timings ?? {}) };\n const previous = queueTail;\n const { promise: ended, resolve: end } = Promise.withResolvers<number>();\n queueTail = ended;\n try {\n await this.#waitForTurn(timings, previous);\n const started = Date.now();\n const conn = await this.#open(timings);\n try {\n const result = await fn(conn);\n protocolLog.trace(\"operation complete\", {\n key: this.#key,\n ms: Date.now() - started,\n });\n return result;\n } finally {\n this.#close(conn);\n }\n } finally {\n if (options.settle) {\n void this.#settle(timings).finally(() => end(Date.now()));\n } else {\n end(Date.now());\n }\n }\n }\n\n #close(conn: Connection) {\n conn.queue.reset();\n try {\n conn.socket.close();\n } catch {\n // already closed\n }\n protocolLog.trace(\"socket closed\");\n }\n\n #open(timings: Timings): Promise<Connection> {\n return new Promise((resolve, reject) => {\n const socket = createSocket(\"udp4\");\n const queue = new MessageQueue();\n const conn: Connection = { socket, queue, timings };\n let connected = false;\n\n socket.on(\"error\", (err) => {\n protocolLog.debug(\"socket error\", { err });\n if (connected) {\n queue.reset(err);\n } else {\n socket.close();\n reject(err);\n }\n });\n\n socket.on(\"message\", (data: Buffer) => {\n try {\n const message = OmniLogicMessage.fromBytes(data);\n protocolLog.trace(\"received message\", {\n message: message.toString(),\n });\n queue.add(message);\n } catch (error) {\n protocolLog.warn(\"dropped a malformed datagram\", {\n bytes: data.length,\n error,\n });\n }\n });\n\n socket.on(\"connect\", () => {\n connected = true;\n protocolLog.debug(\"socket open\");\n resolve(conn);\n });\n\n protocolLog.debug(\"opening socket\", {\n host: this.#host,\n port: this.#port,\n });\n try {\n socket.connect(this.#port, this.#host);\n } catch (err) {\n socket.close();\n reject(err);\n }\n });\n }\n\n async sendMessage(\n opCode: SendableOpcode,\n payload: string | null,\n options: OperationOptions = {},\n ) {\n return this.#withConnection(options, (conn) =>\n this.#send(conn, opCode, payload),\n );\n }\n\n async sendAndReceive(\n opCode: SendableOpcode,\n payload: string | null,\n options: OperationOptions = {},\n ) {\n const attempts = Math.max(1, options.attempts ?? 1);\n return this.#withConnection(options, async (conn) => {\n for (let attempt = 1; ; attempt++) {\n const message = await this.#send(conn, opCode, payload);\n protocolLog.debug(\"waiting for response\", { id: message.id });\n try {\n const response = await this.#processResponse(conn, options.reply);\n protocolLog.debug(\"received response\", {\n id: message.id,\n opCode,\n length: response.length,\n });\n return response;\n } catch (error) {\n if (!(error instanceof OmniTimeoutError) || attempt >= attempts) {\n throw error;\n }\n protocolLog.warn(\"acknowledged but no reply, sending again\", {\n id: message.id,\n opCode,\n attempt,\n of: attempts,\n });\n }\n }\n });\n }\n\n async #nextReply(conn: Connection, reply: number | undefined) {\n protocolLog.debug(\"waiting for the reply\", { reply });\n for (;;) {\n const message = await conn.queue.next(\n conn.timings.nextMessageTimeoutMs,\n \"No reply from the controller\",\n );\n if (isAck(message.opCode)) {\n protocolLog.trace(\"ACK received, skipping\", { id: message.id });\n continue;\n }\n // a long reply arrives as a lead message whatever its opcode\n if (\n reply !== undefined &&\n message.opCode !== reply &&\n message.opCode !== INBOUND_FRAME.leadMessage\n ) {\n protocolLog.trace(\"message of another kind, skipping\", {\n id: message.id,\n opCode: message.opCode,\n reply,\n });\n await this.#sendAck(conn, message.id);\n continue;\n }\n protocolLog.debug(\"reply received\", { id: message.id });\n return message;\n }\n }\n\n async #waitForAck(conn: Connection, ackId: number) {\n protocolLog.debug(\"waiting for ACK\", { id: ackId });\n const message = await conn.queue.next(\n conn.timings.ackTimeoutMs,\n `No acknowledgment from the controller (message ${ackId})`,\n );\n if (message.id !== ackId) {\n protocolLog.trace(\"reply arrived before the ACK; putting it back\", {\n id: message.id,\n expected: ackId,\n opCode: message.opCode,\n });\n conn.queue.add(message);\n }\n }\n\n async #sendAck(conn: Connection, messageId: number) {\n const message = buildMessageXml(\"Ack\");\n protocolLog.debug(\"sending ACK\", { id: messageId });\n await this.#send(conn, OUTBOUND_ACK, message, messageId);\n }\n\n async #send(\n conn: Connection,\n opCode: SendableOpcode,\n payload: string | null,\n messageId?: number,\n ) {\n let message = new OmniLogicMessage(messageId ?? newId(), opCode, payload);\n protocolLog.debug(\"sending message\", { message: message.toString() });\n\n for (let attempt = 0; attempt < ACK_ATTEMPTS; attempt++) {\n // the controller takes a retransmission as a new request\n if (attempt > 0 && messageId === undefined) {\n message = new OmniLogicMessage(newId(), opCode, payload);\n }\n const bytes = message.toBytes();\n conn.socket.send(bytes, (err) => {\n if (err) {\n protocolLog.warn(\"send failed\", { id: message.id, err: err.message });\n conn.queue.reset(err);\n }\n });\n protocolLog.trace(\"sent\", {\n id: message.id,\n opCode,\n attempt: attempt + 1,\n bytes: bytes.length,\n });\n if (isAck(message.opCode)) {\n break;\n }\n\n try {\n await this.#waitForAck(conn, message.id);\n protocolLog.debug(\"ACK received\", { id: message.id });\n break;\n } catch (error) {\n if (\n !(error instanceof OmniTimeoutError) ||\n attempt === ACK_ATTEMPTS - 1\n ) {\n throw error;\n }\n protocolLog.warn(\"ACK not received, retrying\", {\n id: message.id,\n attempt: attempt + 1,\n });\n }\n }\n\n return message;\n }\n\n async #processResponse(conn: Connection, reply?: number) {\n const message = await this.#nextReply(conn, reply);\n await this.#sendAck(conn, message.id);\n\n let payload: Buffer;\n if (message.opCode === INBOUND_FRAME.leadMessage) {\n const { blockCount, msgSize } = parseLeadMessage(message.payload);\n protocolLog.trace(\"received lead message\", { blockCount });\n if (blockCount === 0) {\n protocolLog.trace(\n \"empty response: the lead message announced no blocks\",\n );\n return \"\";\n }\n\n const blocks: Map<number, Buffer> = new Map();\n while (blocks.size < blockCount) {\n const block = await conn.queue.next(\n conn.timings.nextMessageTimeoutMs,\n \"The controller stopped partway through its reply\",\n );\n // a resend means the controller missed the ack\n if (\n block.id === message.id ||\n (block.opCode === INBOUND_FRAME.blockMessage && blocks.has(block.id))\n ) {\n protocolLog.trace(\"duplicate message, acknowledging again\", {\n id: block.id,\n });\n await this.#sendAck(conn, block.id);\n continue;\n }\n if (block.opCode !== INBOUND_FRAME.blockMessage) {\n protocolLog.trace(\"message of another kind, skipping\", {\n id: block.id,\n opCode: block.opCode,\n });\n await this.#sendAck(conn, block.id);\n continue;\n }\n await this.#sendAck(conn, block.id);\n // a block's first 8 bytes are a header\n blocks.set(block.id, block.payload.subarray(8));\n protocolLog.trace(\"block received\", {\n id: block.id,\n received: blocks.size,\n of: blockCount,\n bytes: block.payload.length - 8,\n });\n }\n payload = Buffer.concat(\n Array.from(blocks.entries())\n .toSorted((a, b) => a[0] - b[0])\n .map(([, data]) => data),\n );\n if (msgSize !== undefined && msgSize < payload.length) {\n protocolLog.trace(\"trimming padding past the announced size\", {\n from: payload.length,\n to: msgSize,\n });\n payload = payload.subarray(0, msgSize);\n }\n protocolLog.trace(\"blocks reassembled\", {\n blocks: blockCount,\n bytes: payload.length,\n });\n } else {\n payload = message.payload;\n }\n\n if (message.compressed && payload.length > 0) {\n try {\n const compressedBytes = payload.length;\n payload = inflateSync(payload);\n protocolLog.trace(\"decompressed\", {\n from: compressedBytes,\n to: payload.length,\n });\n } catch (error: unknown) {\n protocolLog.debug(\"decompression failed\", {\n opCode: message.opCode,\n error,\n });\n throw new OmniLogicError(\"Could not decompress the reply\", {\n cause: error,\n });\n }\n }\n\n return payload.toString(\"utf-8\").replace(/\\0$/, \"\");\n }\n}\n","import { setTimeout } from \"node:timers/promises\";\n\nimport {\n COMMANDS,\n type CommandName,\n type CommandParams,\n type CommandResult,\n SWITCH_OPCODE,\n} from \"@/client/spec\";\nimport { isRunning } from \"@/constants/labels\";\nimport { Backyard } from \"@/equipment/backyard\";\nimport {\n DEFAULT_TIMINGS,\n OmniLogicProtocol,\n type Timings,\n} from \"@/transport/protocol\";\nimport type { MSPConfig } from \"@/types/config\";\nimport type { SysInfo } from \"@/types/sysinfo\";\nimport type { Telemetry } from \"@/types/telemetry\";\nimport { buildCommandXml, parseCommandResponse } from \"@/utils/command\";\nimport {\n CommandFailedError,\n EquipmentNotInstalledError,\n FirmwareTooOldError,\n OmniLogicError,\n OmniValidationError,\n SystemStateError,\n ReadingUnavailableError,\n} from \"@/utils/errors\";\nimport { defined, findBySystemId, numberOf, stringOf } from \"@/utils/helpers\";\nimport {\n INVENTORY_PATHS,\n discover,\n presenceAt,\n systemIdAt,\n type Inventory,\n type InventoryPath,\n type Presence,\n} from \"@/utils/inventory\";\nimport { createLogger } from \"@/utils/logger\";\nimport {\n buildMessageXml,\n parseConfig,\n parseSysInfo,\n parseTelemetry,\n} from \"@/utils/xml\";\n\nconst DEFAULT_CACHE_TTL_SECONDS = 30;\nconst DEFAULT_READ_ATTEMPTS = 3;\n\nexport const MIN_MSP_VERSION = \"R0502000\";\n\nconst MSP_VERSION_SHAPE = /^R\\d{7}$/;\n\nexport const DEFAULT_PORT = 10444;\n\nexport type OmniLogicOptions = {\n host: string;\n port?: number;\n // seconds\n cacheTTL?: number;\n // ignored when protocol is supplied\n timings?: Partial<Timings>;\n // how many times a read is sent when the controller acknowledges it but never replies, default 3\n readAttempts?: number;\n // for testing purposes only\n protocol?: OmniLogicProtocol;\n // a cached config to start from, refetched when the checksum moves\n config?: MSPConfig;\n};\n\nexport type CommandOptions = {\n // send even where the SDK would refuse\n force?: boolean;\n timings?: Partial<Timings>;\n // whether the command took\n verify?: () => boolean;\n // default 0: one check\n timeoutMs?: number;\n // default 4000\n pollMs?: number;\n // sends of a write until verify passes, or of a read until the controller replies, default 1 and the session's readAttempts\n attempts?: number;\n // default \"<name> failed\"\n failure?: string;\n // the reply as sent, unparsed\n raw?: boolean;\n};\n\nexport type WriteOptions = Pick<CommandOptions, \"attempts\">;\n\nexport type ReadOptions<R extends boolean = boolean> = { raw?: R };\ntype Fetched<R extends boolean, T> = Promise<R extends true ? string : T>;\n\n// the opcode each fetch answers with\nconst FETCH_REPLY: Record<keyof typeof SWITCH_OPCODE, number> = {\n RequestConfiguration: 1003,\n GetTelemetry: 1004,\n GetSysInfo: 1411,\n};\n\nconst omnilogicLog = createLogger(\"omnilogic\");\nconst commandLog = createLogger(\"command\");\n\nconst ACTUATES_VALVE: Set<CommandName> = new Set([\n \"SetUIPoolSpaSpilloverCmd\",\n \"SetUISpilloverCmd\",\n \"SetUIValveCmd\",\n \"SetUISmartValveCmd\",\n \"SetUISmartValveTargetCmd\",\n]);\n\nconst isInventoryPath = (value: string): value is InventoryPath =>\n INVENTORY_PATHS.some((path) => path === value);\n\n// a check that reads while the controller is off has not passed yet\nconst verified = (verify: () => boolean) => {\n try {\n return verify();\n } catch (error) {\n if (error instanceof ReadingUnavailableError) {\n return false;\n }\n throw error;\n }\n};\n\nexport class OmniLogic {\n #protocol: OmniLogicProtocol;\n #backyard = new Backyard(this);\n #mspConfig: MSPConfig | null = null;\n #telemetry: Telemetry | null = null;\n #configChecksum: number = 0;\n #telemetryLastUpdated: number = 0;\n #cacheTTL: number;\n #timings: Timings;\n #readAttempts: number;\n #inventory: Inventory | null = null;\n\n #telemetryDirty: boolean = true;\n // resolves when the first refresh has finished\n #firstRefresh: Promise<void> | null = null;\n #refreshStarted: number = 0;\n #telemetryCachedFrom: number = 0;\n #writes: number = 0;\n\n constructor(options: OmniLogicOptions) {\n const {\n host,\n port = DEFAULT_PORT,\n cacheTTL = DEFAULT_CACHE_TTL_SECONDS,\n timings = {},\n readAttempts = DEFAULT_READ_ATTEMPTS,\n protocol,\n config,\n } = options;\n this.#cacheTTL = cacheTTL;\n this.#readAttempts = readAttempts;\n this.#timings = { ...DEFAULT_TIMINGS, ...defined(timings) };\n this.#protocol =\n protocol ?? new OmniLogicProtocol(host, port, this.#timings);\n if (config !== undefined) {\n this.#adopt(config);\n this.#configChecksum = config.checksum;\n }\n }\n\n get timings() {\n return this.#timings;\n }\n\n get backyard() {\n return this.#backyard;\n }\n\n get configChecksum() {\n return this.#configChecksum;\n }\n\n get mspVersion() {\n return this.#telemetry?.backyard.mspVersion;\n }\n\n // whether the cached telemetry may be out of date\n get telemetryDirty() {\n return this.#telemetryDirty;\n }\n\n get config() {\n if (this.#mspConfig === null) {\n throw new OmniLogicError(\"No config cached; call refresh() first\");\n }\n return this.#mspConfig;\n }\n\n get telemetry() {\n if (this.#telemetry === null) {\n throw new OmniLogicError(\"No telemetry cached; call refresh() first\");\n }\n return this.#telemetry;\n }\n\n get inventory() {\n if (this.#inventory === null) {\n throw new OmniLogicError(\"No config cached; call refresh() first\");\n }\n return this.#inventory;\n }\n\n #adopt(config: MSPConfig) {\n this.#mspConfig = config;\n const inventory = discover(config);\n this.#inventory = inventory;\n const listed = new Set(inventory.bodies.map((b) => b.systemId));\n for (const bow of config.backyard.bodiesOfWater) {\n if (!listed.has(bow.systemId)) {\n omnilogicLog.debug(\"body without an id left out of the inventory\", {\n name: bow.name,\n });\n }\n }\n const unknown: string[] = [];\n for (const body of inventory.bodies) {\n const presences: Record<string, Presence> = {};\n for (const path of INVENTORY_PATHS) {\n const presence = presenceAt(body, path);\n presences[path] = presence;\n if (presence === \"unknown\") {\n unknown.push(`${body.systemId}:${path}`);\n }\n }\n omnilogicLog.trace(\"body inventory\", {\n poolId: body.systemId,\n ...presences,\n });\n }\n omnilogicLog.debug(\"inventory discovered\", {\n bodies: inventory.bodies.length,\n unknown: unknown.length === 0 ? \"none\" : unknown.join(\",\"),\n });\n }\n\n /**\n * Send a command to the controller\n */\n command<N extends CommandName>(\n name: N,\n params: CommandParams<N> | undefined,\n options: CommandOptions & { raw: true },\n ): Promise<string | undefined>;\n command<N extends CommandName>(\n name: N,\n ...rest: CommandParams<N> extends Record<string, never>\n ? [params?: CommandParams<N>, options?: CommandOptions]\n : [params: CommandParams<N>, options?: CommandOptions]\n ): Promise<CommandResult<N>>;\n command<N extends CommandName>(\n name: N,\n params: CommandParams<N>,\n options?: CommandOptions,\n ): Promise<CommandResult<N>>;\n command<N extends CommandName>(\n name: CommandName extends N ? N : never,\n params: Record<string, number | string> | undefined,\n options: CommandOptions & { raw: true },\n ): Promise<string | undefined>;\n command<N extends CommandName>(\n name: CommandName extends N ? N : never,\n params?: Record<string, number | string>,\n options?: CommandOptions,\n ): Promise<unknown>;\n async command(\n name: CommandName,\n params: Record<string, number | string> = {},\n options: CommandOptions = {},\n ): Promise<unknown> {\n if (options.force) {\n omnilogicLog.trace(\"checks skipped (forced)\", { command: name });\n } else {\n if (this.#telemetry === null) {\n omnilogicLog.debug(\"no config or telemetry cached, refreshing first\", {\n command: name,\n });\n this.#firstRefresh ??= this.refresh().finally(() => {\n this.#firstRefresh = null;\n });\n await this.#firstRefresh;\n }\n this.#gate(name, params);\n }\n this.#warnValveWhilePumping(name, params);\n const send = async () => {\n if (!options.force) {\n this.#refuseOutsideNormalOperation(name);\n }\n const result = await this.#send(name, params, options);\n if (COMMANDS[name].read !== true) {\n this.#writes++;\n this.#telemetryDirty = true;\n omnilogicLog.trace(\"telemetry marked dirty\", { command: name });\n }\n return result;\n };\n\n const { verify } = options;\n if (verify === undefined) {\n return send();\n }\n const attempts = Math.max(1, options.attempts ?? 1);\n const timeoutMs = options.timeoutMs ?? 0;\n const pollMs = options.pollMs ?? 4000;\n omnilogicLog.trace(\"verifying\", {\n command: name,\n attempts,\n timeoutMs,\n pollMs,\n });\n let sendError: unknown;\n for (let attempt = 1; attempt <= attempts; attempt++) {\n sendError = undefined;\n const result = await send().catch((error: unknown) => {\n if (\n error instanceof OmniValidationError ||\n error instanceof SystemStateError\n ) {\n throw error;\n }\n omnilogicLog.warn(\"send failed; checking whether it took\", {\n command: name,\n attempt,\n error,\n });\n sendError = error;\n return undefined;\n });\n const deadline = Date.now() + timeoutMs;\n for (let check = 1; ; check++) {\n try {\n await this.refresh({ refetch: true, force: options.force });\n } catch (error) {\n omnilogicLog.warn(\"refresh failed, so the command is unverified\", {\n command: name,\n attempt,\n check,\n error,\n });\n throw new CommandFailedError({\n message: options.failure ?? `${name} failed`,\n command: name,\n attempts: attempt,\n cause: error,\n });\n }\n if (verified(verify)) {\n omnilogicLog.trace(\"verified\", { command: name, attempt, check });\n // a read with no reply has nothing to return\n if (sendError !== undefined && COMMANDS[name].response) {\n throw sendError;\n }\n return result;\n }\n if (Date.now() >= deadline) {\n omnilogicLog.trace(\"not verified within the timeout\", {\n command: name,\n attempt,\n check,\n });\n break;\n }\n omnilogicLog.trace(\"not verified yet, polling\", {\n command: name,\n attempt,\n check,\n pollMs,\n });\n await setTimeout(pollMs);\n }\n }\n throw new CommandFailedError({\n message: options.failure ?? `${name} failed`,\n command: name,\n attempts,\n cause: sendError,\n });\n }\n\n async #send(\n name: CommandName,\n params: Record<string, number | string>,\n options: CommandOptions,\n ) {\n const spec = COMMANDS[name];\n if (spec.caveat !== undefined) {\n const { effect, alternative } = spec.caveat;\n commandLog.warn(\n `${name} ${effect}`,\n alternative === undefined ? undefined : { alternative },\n );\n }\n commandLog.debug(name, { opcode: spec.opcode, ...params });\n\n const { xml, unknown } = buildCommandXml(name, params);\n for (const key of unknown) {\n commandLog.warn(\"ignoring unknown parameter (not in spec)\", {\n name,\n key,\n });\n }\n commandLog.trace(\"payload\", {\n name,\n bytes: Buffer.byteLength(xml, \"utf8\"),\n xml,\n });\n\n const started = Date.now();\n const operation = {\n timings: options.timings,\n settle: spec.settle,\n attempts:\n spec.read === true ? (options.attempts ?? this.#readAttempts) : 1,\n reply: spec.response?.opcode,\n };\n try {\n if (spec.response) {\n const responseXml = await this.#protocol.sendAndReceive(\n spec.opcode,\n xml,\n operation,\n );\n commandLog.trace(\"response\", {\n name,\n ms: Date.now() - started,\n xml: responseXml,\n });\n\n const parsed = parseCommandResponse(spec.response, responseXml);\n if (!parsed.ok) {\n throw new OmniLogicError(\n parsed.actual === 0\n ? `${name} answered nothing`\n : `${name} answered with ${parsed.actual} parameters, not the ${parsed.expected} of ${spec.response.name}`,\n );\n }\n\n if (options.raw) {\n return responseXml === \"\" ? undefined : responseXml;\n }\n\n commandLog.debug(\"parsed response\", { name, ...parsed.params });\n return parsed.params;\n }\n\n const message = await this.#protocol.sendMessage(\n spec.opcode,\n xml,\n operation,\n );\n commandLog.debug(\"sent\", {\n name,\n id: message.id,\n ms: Date.now() - started,\n });\n return undefined;\n } catch (error) {\n commandLog.debug(\"failed\", { name, opcode: spec.opcode, error });\n throw error;\n }\n }\n\n async #fetch(name: keyof typeof SWITCH_OPCODE) {\n omnilogicLog.debug(name);\n const started = Date.now();\n const xml = await this.#protocol.sendAndReceive(\n SWITCH_OPCODE[name],\n buildMessageXml(name),\n { attempts: this.#readAttempts, reply: FETCH_REPLY[name] },\n );\n omnilogicLog.debug(\"fetched\", {\n name,\n ms: Date.now() - started,\n bytes: Buffer.byteLength(xml, \"utf8\"),\n });\n return xml;\n }\n\n fetchConfig<R extends boolean = false>(\n options?: ReadOptions<R>,\n ): Fetched<R, MSPConfig>;\n async fetchConfig(options: ReadOptions = {}) {\n const xmlResponse = await this.#fetch(\"RequestConfiguration\");\n if (options.raw) {\n return xmlResponse;\n }\n const config = parseConfig(xmlResponse);\n omnilogicLog.trace(\"config parsed\", {\n checksum: config.checksum,\n bodies: config.backyard.bodiesOfWater.length,\n schedules: config.schedules.length,\n favorites: config.favorites.length,\n themes: config.themes.length,\n });\n return config;\n }\n\n fetchTelemetry<R extends boolean = false>(\n options?: ReadOptions<R>,\n ): Fetched<R, Telemetry>;\n async fetchTelemetry(options: ReadOptions = {}) {\n const xmlResponse = await this.#fetch(\"GetTelemetry\");\n if (options.raw) {\n return xmlResponse;\n }\n const telemetry = parseTelemetry(xmlResponse);\n omnilogicLog.trace(\"telemetry parsed\", {\n version: telemetry.version,\n checksum: telemetry.backyard.configChksum,\n bodies: telemetry.bodiesOfWater.length,\n });\n return telemetry;\n }\n\n fetchSysInfo<R extends boolean = false>(\n options?: ReadOptions<R>,\n ): Fetched<R, SysInfo>;\n async fetchSysInfo(options: ReadOptions = {}) {\n const xmlResponse = await this.#fetch(\"GetSysInfo\");\n if (options.raw) {\n return xmlResponse;\n }\n const info = parseSysInfo(xmlResponse);\n omnilogicLog.trace(\"sysinfo parsed\", {\n components: info.components.length,\n });\n return info;\n }\n\n // a command that moves a valve, or a relay command aimed at a valve actuator\n #movesAValve(name: CommandName, params: Record<string, unknown>) {\n if (ACTUATES_VALVE.has(name)) {\n return true;\n }\n if (name !== \"SetUIEquipmentCmd\" && name !== \"SetUIRelayCmd\") {\n return false;\n }\n const equipmentId = numberOf(params.equipmentId);\n const type = stringOf(\n equipmentId === undefined\n ? undefined\n : findBySystemId(this.#mspConfig, equipmentId)?.type,\n );\n return type === \"RLY_VALVE_ACTUATOR\" || type === \"RLY_SMART_VALVE_ACTUATOR\";\n }\n\n #warnValveWhilePumping(name: CommandName, params: Record<string, unknown>) {\n if (!this.#movesAValve(name, params)) {\n return;\n }\n const poolId = numberOf(params.poolId);\n if (poolId === undefined) {\n return;\n }\n let pumpOn = false;\n try {\n pumpOn = this.backyard.body(poolId)?.filter?.isOn ?? false;\n } catch {\n omnilogicLog.trace(\"no telemetry to check the pump against\", {\n command: name,\n poolId,\n });\n }\n if (!pumpOn) {\n return;\n }\n omnilogicLog.warn(\n \"valve command sent while the filter pump looks to be running, which can deadhead it\",\n { command: name, poolId },\n );\n }\n\n #refuseUnsupportedFirmware(telemetry: Telemetry) {\n const version = telemetry.backyard.mspVersion;\n if (version === undefined || !MSP_VERSION_SHAPE.test(version)) {\n omnilogicLog.debug(\"firmware version unrecognized, not checked\", {\n version,\n });\n return;\n }\n // string order is version order\n if (version < MIN_MSP_VERSION) {\n throw new FirmwareTooOldError({ version, minimum: MIN_MSP_VERSION });\n }\n omnilogicLog.trace(\"firmware supported\", { version });\n }\n\n #refuseOutsideNormalOperation(name: CommandName) {\n const { state } = this.telemetry.backyard;\n if (COMMANDS[name].read !== true && !isRunning(state)) {\n throw new SystemStateError({ command: name, backyardState: state });\n }\n }\n\n #gate(name: CommandName, params: Record<string, unknown>) {\n const inventory = this.inventory;\n\n const { requires = [], target } = COMMANDS[name];\n if (requires.length === 0 && target === undefined) {\n return;\n }\n omnilogicLog.trace(\"gate\", { command: name, requires, target });\n\n if (inventory.bodies.length === 0) {\n omnilogicLog.debug(\"no bodies discovered; sending anyway\", {\n command: name,\n });\n return;\n }\n\n const poolId = numberOf(params.poolId);\n if (poolId === undefined) {\n omnilogicLog.trace(\"no poolId to gate on; sending\", { command: name });\n return;\n }\n\n const body = inventory.bodies.find((b) => b.systemId === poolId);\n if (body === undefined) {\n throw new EquipmentNotInstalledError({\n command: name,\n requirement: \"body\",\n poolId,\n inventory,\n });\n }\n\n const refuse = (requirement: string, hint?: string) => {\n throw new EquipmentNotInstalledError({\n command: name,\n requirement,\n poolId,\n hint,\n inventory,\n });\n };\n\n for (const path of requires) {\n const presence = presenceAt(body, path);\n if (presence === \"absent\") {\n refuse(path);\n }\n if (presence === \"unknown\") {\n omnilogicLog.debug(\"inventory unknown; sending anyway\", {\n command: name,\n path,\n poolId,\n });\n }\n }\n\n // refuses the parent's id where the part's is wanted\n if (target === undefined || !target.includes(\".\")) {\n return;\n }\n const dot = target.indexOf(\".\");\n const ownerPath = target.slice(0, dot);\n if (!isInventoryPath(ownerPath)) {\n return;\n }\n const wanted = systemIdAt(body, target);\n const owner = systemIdAt(body, ownerPath);\n if (\n wanted !== undefined &&\n owner !== undefined &&\n params.equipmentId === owner &&\n owner !== wanted\n ) {\n refuse(\n target,\n `it takes the ${target.slice(dot + 1)} id (${wanted}), not the ${ownerPath}'s (${owner})`,\n );\n }\n }\n\n /**\n * Fetch and cache the latest telemetry and config\n */\n async refresh(\n options: {\n // refetch when a write marked the cached telemetry stale, default true\n ifDirty?: boolean;\n // seconds the cached telemetry may be old, default the session's cache TTL\n ifOlderThan?: number;\n // fetch even when the cached config and telemetry are fresh\n refetch?: boolean;\n // fetch even from a controller the SDK would refuse\n force?: boolean;\n } = {},\n ) {\n const {\n ifDirty = true,\n ifOlderThan = this.#cacheTTL,\n refetch = false,\n force = false,\n } = options;\n\n const now = Date.now() / 1000;\n const age = Math.max(0, Math.round(now - this.#telemetryLastUpdated));\n const isStale = age > ifOlderThan;\n const dirty = ifDirty && this.#telemetryDirty;\n const shouldUpdate = refetch || dirty || isStale;\n\n if (!shouldUpdate) {\n omnilogicLog.trace(\"refresh skipped (not dirty, not stale)\", {\n ageSeconds: age,\n ttlSeconds: ifOlderThan,\n });\n return;\n }\n\n omnilogicLog.debug(\"refresh starting\", {\n refetch,\n dirty,\n stale: isStale,\n ageSeconds: age,\n });\n const started = Date.now();\n const seq = ++this.#refreshStarted;\n const writes = this.#writes;\n const telemetry = await this.fetchTelemetry();\n if (!force) {\n this.#refuseUnsupportedFirmware(telemetry);\n }\n const newChecksum = telemetry.backyard.configChksum;\n omnilogicLog.trace(\"telemetry fetched\", {\n ms: Date.now() - started,\n checksum: newChecksum,\n });\n\n if (\n refetch ||\n this.#mspConfig === null ||\n newChecksum !== this.#configChecksum\n ) {\n omnilogicLog.debug(\"fetching config\", {\n reason: refetch\n ? \"refetching\"\n : this.#mspConfig === null\n ? \"none cached\"\n : \"checksum changed\",\n checksum: newChecksum,\n previous: this.#configChecksum,\n });\n const configStarted = Date.now();\n const config = await this.fetchConfig();\n this.#configChecksum = newChecksum;\n omnilogicLog.trace(\"config fetched\", { ms: Date.now() - configStarted });\n this.#adopt(config);\n } else {\n omnilogicLog.trace(\"config checksum unchanged, skipping fetch\", {\n checksum: newChecksum,\n });\n }\n if (this.#telemetryCachedFrom > seq) {\n omnilogicLog.trace(\"telemetry superseded by a later refresh\", {\n ms: Date.now() - started,\n });\n return;\n }\n this.#telemetry = telemetry;\n this.#telemetryCachedFrom = seq;\n this.#telemetryLastUpdated = now;\n this.#telemetryDirty = this.#writes !== writes;\n }\n}\n"],"mappings":"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CjE,GAAG;CACH,GAAG;CACH,GAAG;AACL;AAEA,MAAa,qBAA6C;CACxD,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,KAAK;AACP;AASA,MAAa,qBAAoC;CAC/C;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ,EACN,GAAG,oBACL;CACF;CACA;EACE,OAAO;EACP,QAAQ,EACN,GAAG,mBACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ,EACN,GAAG,uBACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ,EACN,GAAG,aACL;CACF;AACF;AAEA,MAAa,qBAAoC;CAC/C;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;AACF;AAEA,MAAa,cAAsC;CACjD,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;AACL;AAEA,MAAa,eAAuC;CAClD,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,IAAI;AACN;AAEA,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"}
1
+ {"version":3,"file":"index.js","names":["setTimeout","protocolLog","setTimeout","setTimeout"],"sources":["../src/client/spec.ts","../src/constants/labels.ts","../src/constants/sentinels.ts","../src/utils/errors.ts","../src/utils/helpers.ts","../src/utils/inventory.ts","../src/equipment/device.ts","../src/utils/decode.ts","../src/equipment/chlorinator.ts","../src/equipment/csad.ts","../src/equipment/schedules.ts","../src/utils/xml.ts","../src/utils/command.ts","../src/equipment/pump.ts","../src/equipment/filter.ts","../src/equipment/heaterAppliance.ts","../src/equipment/heater.ts","../src/constants/lightShows.ts","../src/utils/logger.ts","../src/equipment/light.ts","../src/equipment/relay.ts","../src/equipment/bodyOfWater.ts","../src/equipment/favorites.ts","../src/equipment/panel.ts","../src/equipment/themes.ts","../src/equipment/backyard.ts","../src/transport/message.ts","../src/transport/queue.ts","../src/transport/protocol.ts","../src/client/omnilogic.ts"],"sourcesContent":["import type { InventoryPath } from \"@/utils/inventory\";\nimport type { DataType } from \"@/utils/xml\";\n\n// a request parameter's type, which is never a bool\nexport type CommandWireType = Exclude<DataType, \"bool\">;\n\ntype CommandNumericParam = {\n name: string;\n type: Exclude<CommandWireType, \"string\">;\n};\n\ntype CommandStringParam = {\n name: string;\n type: \"string\";\n // the longest value the firmware keeps intact\n maxLength: number;\n values?: string[];\n};\n\nexport type CommandRequestParam = CommandNumericParam | CommandStringParam;\n\ntype CommandResponseParam = {\n name: string;\n dataType: DataType;\n unit?: string;\n};\n\nexport type CommandResponseSpec = {\n name: string;\n opcode: number;\n parameters: CommandResponseParam[];\n};\n\ntype CommandSpec<Name extends string = string> = {\n opcode: number;\n // wire order\n request: CommandRequestParam[];\n // the reply's opcode\n response?: CommandResponseSpec;\n // the cache stays clean after one\n read?: true;\n // the controller goes quiet for 12–22 s after acknowledging this and drops what arrives meanwhile\n settle?: true;\n // inventory paths that must not be absent for this command to apply\n requires?: InventoryPath[];\n // the equipment whose id this command takes\n target?: InventoryPath;\n caveat?: {\n // what the command does that a caller would not expect\n effect: string;\n // the command to use instead\n alternative?: Name;\n };\n};\n\nconst defineSpec = <\n const S extends Record<string, CommandSpec<keyof S & string>>,\n>(\n spec: S,\n) => spec;\n\nconst SPEC = defineSpec({\n SetUIPoolSpaSpilloverCmd: {\n opcode: 6,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"moves the return valve. On some installs it is plumbed the other way around, so turning spillover on has the opposite effect and stops it\",\n },\n },\n GetUIPoolSpaSpilloverCmd: {\n read: true,\n opcode: 7,\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"UIPoolSpaSpilloverRsp\",\n opcode: 1007,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"position\", dataType: \"int\" },\n ],\n },\n },\n SetUIPoolFilterCmd: {\n opcode: 8,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n SetUIFilterSpeedCmd: {\n opcode: 9,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIFilterSpeedCmd: {\n read: true,\n opcode: 10,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIFilterSpeedRsp\",\n opcode: 1010,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n { name: \"speed\", dataType: \"int\", unit: \"RPM\" },\n ],\n },\n },\n SetUIHeaterCmd: {\n opcode: 11,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIHeaterCmd: {\n read: true,\n opcode: 12,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIHeaterRsp\",\n opcode: 1012,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"temp\", dataType: \"int\", unit: \"F\" },\n ],\n },\n },\n SetUIHeaterPriorityCmd: {\n opcode: 13,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIHeaterPriorityCmd: {\n read: true,\n opcode: 14,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUISuperCHLORCmd: {\n opcode: 15,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"stops the filter pump when it turns superchlorination off, even a pump turned on by hand, so send the filter's speed again afterwards\",\n },\n },\n GetUISuperCHLORCmd: {\n read: true,\n opcode: 16,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UISuperCHLORRsp\",\n opcode: 1016,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"isOn\", dataType: \"byte\" },\n ],\n },\n },\n SetUISuperCHLORTimeoutCmd: {\n opcode: 17,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n SetUIORPCHLORTimeoutCmd: {\n opcode: 18,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"is acknowledged and then ignored: the controller does nothing with it and sends no reply\",\n },\n },\n SetUISuperCHLOROutputCmd: {\n opcode: 19,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"is acknowledged and then ignored: the controller does nothing with it and sends no reply\",\n },\n },\n GetUISuperCHLOROutputCmd: {\n read: true,\n opcode: 20,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"is acknowledged and then ignored: the controller does nothing with it and sends no reply\",\n },\n },\n SetUIRelayCmd: {\n opcode: 21,\n caveat: {\n effect:\n \"does nothing with isOn 1 unless a start and end time are given, and then runs the relay as a schedule without enforcing the end time\",\n alternative: \"SetUIEquipmentCmd\",\n },\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"isOn\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n GetUIRelayCmd: {\n read: true,\n opcode: 22,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIRelayRsp\",\n opcode: 1022,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"relayId\", dataType: \"int\" },\n { name: \"isOn\", dataType: \"int\" },\n ],\n },\n },\n SetUIValveCmd: {\n opcode: 23,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n GetUIValveCmd: {\n read: true,\n opcode: 24,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIValveRsp\",\n opcode: 1024,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"vaid\", dataType: \"int\" },\n { name: \"valveState\", dataType: \"int\" },\n ],\n },\n },\n GetUIPoolTempCmd: {\n read: true,\n opcode: 25,\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"UIGetPoolTempRsp\",\n opcode: 1025,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"temp\", dataType: \"int\", unit: \"F\" },\n ],\n },\n },\n GetUIAirTempCmd: {\n read: true,\n opcode: 26,\n request: [],\n response: {\n name: \"UIGetAirTempRsp\",\n opcode: 1026,\n parameters: [{ name: \"temp\", dataType: \"int\", unit: \"F\" }],\n },\n },\n GetUIFlowSensor: {\n read: true,\n opcode: 27,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetUIFlowSensorRsp\",\n opcode: 1027,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"reading\", dataType: \"int\" },\n ],\n },\n },\n GetUISensor: {\n read: true,\n opcode: 28,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"is acknowledged and then ignored: the controller does nothing with it and sends no reply\",\n },\n },\n GetUISolarTempCmd: {\n read: true,\n opcode: 29,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UiSetManualLastSpeed: {\n opcode: 34,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n GetAutoTime: {\n read: true,\n opcode: 35,\n request: [],\n response: {\n name: \"GetAutoTimeRsp\",\n opcode: 1035,\n parameters: [\n { name: \"year\", dataType: \"int\" },\n { name: \"month\", dataType: \"int\" },\n { name: \"day\", dataType: \"int\" },\n { name: \"format\", dataType: \"bool\" },\n { name: \"hour\", dataType: \"int\" },\n { name: \"minute\", dataType: \"int\" },\n { name: \"amPm\", dataType: \"string\" },\n { name: \"autoUpdateTime\", dataType: \"bool\" },\n ],\n },\n },\n SetUISolarSetPointCmd: {\n opcode: 40,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetSetUISolarSetPointCmd: {\n read: true,\n opcode: 41,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UISolarSetPointCmdRsp\",\n opcode: 1041,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"temp\", dataType: \"int\", unit: \"F\" },\n ],\n },\n },\n SetUIHeaterModeCmd: {\n opcode: 42,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIHeaterModeCmd: {\n read: true,\n opcode: 43,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIGetHeaterModeCmdRsp\",\n opcode: 1043,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"mode\", dataType: \"int\" },\n ],\n },\n },\n SetHeaterAutoDifferential: {\n opcode: 44,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterAutoDifferential: {\n read: true,\n opcode: 45,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIGetHeaterAutoDifferentialRsp\",\n opcode: 1045,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"data\", dataType: \"int\" },\n ],\n },\n },\n GetHeaterDiagnostic: {\n read: true,\n opcode: 46,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetHeaterPowerUsage: {\n read: true,\n opcode: 47,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetHeaterSensor: {\n read: true,\n opcode: 48,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetHeaterSilentMode: {\n opcode: 49,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterSilentMode: {\n read: true,\n opcode: 50,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterSilentModeRsp\",\n opcode: 1050,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetUISmartValveCmd: {\n opcode: 60,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n GetUISmartValveCmd: {\n read: true,\n opcode: 61,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIGetSmartValveRsp\",\n opcode: 1061,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"isOn\", dataType: \"byte\" },\n { name: \"target\", dataType: \"byte\" },\n { name: \"data3\", dataType: \"byte\" },\n { name: \"data4\", dataType: \"byte\" },\n ],\n },\n },\n SetUISmartValveTargetCmd: {\n opcode: 62,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n SetUISmartValveForTheme: {\n opcode: 63,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n ],\n },\n GetFlowControlPortStatus: {\n read: true,\n opcode: 64,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetFlowControlPortConfig: {\n read: true,\n opcode: 65,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetFlowControlDiagnostic: {\n read: true,\n opcode: 66,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetFlowControlPortErrors: {\n read: true,\n opcode: 67,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n FlowControlHomePortsCmd: {\n opcode: 68,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUIFlowControlForTheme: {\n opcode: 69,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"field1c\", type: \"byte\" },\n { name: \"field1d\", type: \"byte\" },\n { name: \"field1e\", type: \"byte\" },\n { name: \"field1f\", type: \"byte\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n { name: \"field27\", type: \"byte\" },\n ],\n },\n SetTime2: {\n opcode: 100,\n request: [\n { name: \"is24Hour\", type: \"byte\" },\n { name: \"hour\", type: \"byte\" },\n { name: \"minute\", type: \"byte\" },\n { name: \"second\", type: \"byte\" },\n // ignored on a 24-hour clock\n {\n name: \"amPm\",\n type: \"string\",\n maxLength: 9,\n values: [\"AM\", \"PM\"],\n },\n ],\n },\n SetDateTime: {\n opcode: 101,\n caveat: {\n effect:\n \"is acknowledged but the clock does not move; SetTime2 and SetDate together set everything this takes\",\n alternative: \"SetTime2\",\n },\n request: [\n // stored as two bytes, century and year within the century\n { name: \"year\", type: \"int\" },\n { name: \"month\", type: \"byte\" },\n { name: \"day\", type: \"byte\" },\n { name: \"is24Hour\", type: \"byte\" },\n { name: \"hour\", type: \"byte\" },\n { name: \"minute\", type: \"byte\" },\n // ignored on a 24-hour clock\n {\n name: \"amPm\",\n type: \"string\",\n maxLength: 9,\n values: [\"AM\", \"PM\"],\n },\n ],\n },\n GetDateTime: {\n read: true,\n opcode: 102,\n request: [],\n response: {\n name: \"GetDateTimeRsp\",\n opcode: 1102,\n parameters: [\n { name: \"year\", dataType: \"int\" },\n { name: \"month\", dataType: \"int\" },\n { name: \"day\", dataType: \"int\" },\n { name: \"format\", dataType: \"bool\" },\n { name: \"hour\", dataType: \"int\" },\n { name: \"minute\", dataType: \"int\" },\n { name: \"amPm\", dataType: \"string\" },\n ],\n },\n },\n SetDate: {\n opcode: 103,\n request: [\n // stored as two bytes, century and year within the century\n { name: \"year\", type: \"int\" },\n { name: \"month\", type: \"byte\" },\n { name: \"day\", type: \"byte\" },\n ],\n caveat: {\n effect:\n \"ends every schedule window in progress and rebooks each daily schedule from the new date, so a day moved back to runs no schedule until each is edited or re-enabled\",\n },\n },\n GetDate: {\n read: true,\n opcode: 104,\n request: [],\n response: {\n name: \"GetDateRsp\",\n opcode: 1104,\n parameters: [\n { name: \"year\", dataType: \"int\" },\n { name: \"month\", dataType: \"int\" },\n { name: \"day\", dataType: \"int\" },\n ],\n },\n },\n SetTime: {\n opcode: 105,\n request: [\n { name: \"is24Hour\", type: \"byte\" },\n { name: \"hour\", type: \"byte\" },\n { name: \"minute\", type: \"byte\" },\n // ignored on a 24-hour clock\n {\n name: \"amPm\",\n type: \"string\",\n maxLength: 9,\n values: [\"AM\", \"PM\"],\n },\n ],\n },\n GetTime: {\n read: true,\n opcode: 106,\n request: [],\n response: {\n name: \"GetTimeRsp\",\n opcode: 1106,\n parameters: [\n { name: \"format\", dataType: \"bool\" },\n { name: \"hour\", dataType: \"int\" },\n { name: \"minute\", dataType: \"int\" },\n { name: \"amPm\", dataType: \"string\" },\n ],\n },\n },\n SetBackLight: {\n opcode: 107,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetBackLight: {\n read: true,\n opcode: 108,\n request: [],\n response: {\n name: \"GetBackLightRsp\",\n opcode: 1108,\n parameters: [{ name: \"state\", dataType: \"bool\" }],\n },\n },\n SetBackLightBrightness: {\n opcode: 109,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetBackLightBrightness: {\n read: true,\n opcode: 110,\n request: [],\n response: {\n name: \"GetBackLightBrightnessRsp\",\n opcode: 1110,\n parameters: [{ name: \"brightness\", dataType: \"int\" }],\n },\n },\n SetBackLightTimeout: {\n opcode: 111,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetBackLightTimeout: {\n read: true,\n opcode: 112,\n request: [],\n response: {\n name: \"GetBackLightTimeoutRsp\",\n opcode: 1112,\n parameters: [{ name: \"timeout\", dataType: \"int\", unit: \"second\" }],\n },\n },\n SetBeeper: {\n opcode: 113,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetBeeper: {\n read: true,\n opcode: 114,\n request: [],\n response: {\n name: \"GetBeeperRsp\",\n opcode: 1114,\n parameters: [{ name: \"enabled\", dataType: \"bool\" }],\n },\n },\n SetTimeFormat: {\n opcode: 115,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetTimeFormat: {\n read: true,\n opcode: 116,\n request: [],\n response: {\n name: \"GetTimeFormatRsp\",\n opcode: 1116,\n parameters: [{ name: \"format\", dataType: \"int\" }],\n },\n },\n SetUnits: {\n opcode: 117,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetUnits: {\n read: true,\n opcode: 118,\n request: [],\n response: {\n name: \"GetUnitsRsp\",\n opcode: 1118,\n parameters: [{ name: \"unitFormat\", dataType: \"bool\" }],\n },\n },\n SetVSPSpeedFormat: {\n opcode: 119,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetVSPSpeedFormat: {\n read: true,\n opcode: 120,\n request: [],\n response: {\n name: \"GetVSPSpeedFormatRsp\",\n opcode: 1120,\n parameters: [{ name: \"format\", dataType: \"bool\" }],\n },\n },\n SetCHLOREnable: {\n opcode: 121,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetCHLOREnable: {\n read: true,\n opcode: 122,\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetCHLOREnableRsp\",\n opcode: 1122,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetCHLORDisplay: {\n opcode: 123,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetCHLORDisplay: {\n read: true,\n opcode: 124,\n request: [],\n response: {\n name: \"GetCHLORDisplayRsp\",\n opcode: 1124,\n parameters: [{ name: \"enabled\", dataType: \"bool\" }],\n },\n },\n SetSpaSpilloverEnable: {\n opcode: 127,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetSpaSpilloverEnable: {\n read: true,\n opcode: 128,\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetSpaSpilloverEnableRsp\",\n opcode: 1128,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetFilterOperation: {\n opcode: 129,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFilterOperation: {\n read: true,\n opcode: 130,\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFilterOperationRsp\",\n opcode: 1130,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"operation\", dataType: \"int\" },\n ],\n },\n },\n SetFilterOffValveChg: {\n opcode: 131,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFilterOffValveChg: {\n read: true,\n opcode: 132,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFilterOffValveChgRsp\",\n opcode: 1132,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetFilterLowSpeed: {\n opcode: 133,\n requires: [\"filter\", \"filter.vsp\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFilterLowSpeed: {\n read: true,\n opcode: 134,\n requires: [\"filter\", \"filter.vsp\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetFilterLowSpeedRsp\",\n opcode: 1134,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n // the minimum speed whatever the speed format\n { name: \"speed\", dataType: \"int\" },\n ],\n },\n },\n SetFilterHighSpeed: {\n opcode: 135,\n requires: [\"filter\", \"filter.vsp\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFilterHighSpeed: {\n read: true,\n opcode: 136,\n requires: [\"filter\", \"filter.vsp\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetFilterHighSpeedRsp\",\n opcode: 1136,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n // the maximum speed whatever the speed format\n { name: \"speed\", dataType: \"int\" },\n ],\n },\n },\n SetFreezeProtect: {\n opcode: 137,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFreezeProtect: {\n read: true,\n opcode: 138,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFreezeProtectRsp\",\n opcode: 1138,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetFreezeProtectSpeed: {\n opcode: 139,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFreezeProtectSpeed: {\n read: true,\n opcode: 140,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFreezeProtectSpeedRsp\",\n opcode: 1140,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"speed\", dataType: \"int\", unit: \"RPM\" },\n ],\n },\n },\n SetFreezeProtectTemp: {\n opcode: 141,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFreezeProtectTemp: {\n read: true,\n opcode: 142,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFreezeProtectTempRsp\",\n opcode: 1142,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"temp\", dataType: \"int\", unit: \"F\" },\n ],\n },\n },\n SetFlowMonitor: {\n opcode: 143,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetFlowMonitor: {\n read: true,\n opcode: 144,\n requires: [\"filter\"],\n request: [{ name: \"poolId\", type: \"int\" }],\n response: {\n name: \"GetFlowMonitorRsp\",\n opcode: 1144,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetExternalInterLock: {\n opcode: 145,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"field1c\", type: \"byte\" },\n { name: \"field1d\", type: \"byte\" },\n { name: \"field1e\", type: \"byte\" },\n { name: \"field1f\", type: \"byte\" },\n { name: \"field20\", type: \"int\" },\n { name: \"field24\", type: \"int\" },\n ],\n },\n GetExternalInterLock: {\n read: true,\n opcode: 146,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n // zero-based index into the equipment's interlock list, one past the count silently ignored\n { name: \"data\", type: \"int\" },\n ],\n },\n SetHeaterEnable: {\n opcode: 147,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterEnable: {\n read: true,\n opcode: 148,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterEnableRsp\",\n opcode: 1148,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetHeaterCoolDown: {\n opcode: 149,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterCoolDown: {\n read: true,\n opcode: 150,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterCoolDownRsp\",\n opcode: 1150,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetHeaterExtend: {\n opcode: 151,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterExtend: {\n read: true,\n opcode: 152,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterExtendRsp\",\n opcode: 1152,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetHeaterAllowedLowSpeed: {\n opcode: 153,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterAllowedLowSpeed: {\n read: true,\n opcode: 154,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterAllowedLowSpeedRsp\",\n opcode: 1154,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n // the appliance id, not the thermostat's\n { name: \"heaterId\", dataType: \"int\" },\n // the allow-low-speed flag\n { name: \"speed\", dataType: \"int\", unit: \"RPM\" },\n ],\n },\n },\n SetCHLORParams: {\n opcode: 155,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n // a byte code the config does not carry\n { name: \"cfgState\", type: \"byte\" },\n { name: \"opMode\", type: \"byte\" },\n // a byte code the config does not carry\n { name: \"bowType\", type: \"byte\" },\n // a byte code the config does not carry\n { name: \"cellType\", type: \"byte\" },\n { name: \"timedPercent\", type: \"byte\" },\n { name: \"scTimeout\", type: \"byte\" },\n { name: \"orpTimeout\", type: \"byte\" },\n ],\n },\n GetCHLORParams: {\n read: true,\n opcode: 156,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCHLORParamsRsp\",\n opcode: 1156,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"cfgState\", dataType: \"byte\" },\n { name: \"opMode\", dataType: \"byte\" },\n { name: \"bowType\", dataType: \"byte\" },\n { name: \"cellType\", dataType: \"byte\" },\n { name: \"timedPercent\", dataType: \"byte\" },\n { name: \"scTimeout\", dataType: \"byte\", unit: \"hour\" },\n { name: \"orpTimeout\", dataType: \"byte\", unit: \"hour\" },\n ],\n },\n },\n GetCHLORStatus: {\n opcode: 157,\n read: true,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n target: \"chlorinator.cell\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCHLORStatusRsp\",\n opcode: 1157,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"opState\", dataType: \"byte\" },\n { name: \"scState\", dataType: \"byte\" },\n { name: \"alertStatus\", dataType: \"byte\" },\n { name: \"instantSaltHigh\", dataType: \"byte\" },\n { name: \"instantSaltLow\", dataType: \"byte\" },\n { name: \"averageSaltHigh\", dataType: \"byte\" },\n { name: \"averageSaltLow\", dataType: \"byte\" },\n { name: \"activelyDispensing\", dataType: \"byte\" },\n ],\n },\n },\n GetCHLORAlert: {\n opcode: 158,\n read: true,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n target: \"chlorinator.cell\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCHLORAlertRsp\",\n opcode: 1158,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"alertHighByte\", dataType: \"byte\" },\n { name: \"alertLowByte\", dataType: \"byte\" },\n ],\n },\n },\n GetCHLORError: {\n opcode: 159,\n read: true,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n target: \"chlorinator.cell\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCHLORErrorRsp\",\n opcode: 1159,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"errorHighByte\", dataType: \"byte\" },\n { name: \"errorLowByte\", dataType: \"byte\" },\n ],\n },\n },\n CHLORSaltCalcRestart: {\n opcode: 160,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n CHLORRelayPolarityReverse: {\n opcode: 161,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n CHLORCellRuntimeRestart: {\n opcode: 162,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetCHLORMeasurement: {\n opcode: 163,\n read: true,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n target: \"chlorinator.cell\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n // byte pairs are big-endian u16 (high * 256 + low): salt in ppm, the rest ADC counts\n response: {\n name: \"GetCHLORMeasurementRsp\",\n opcode: 1163,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"voltageHighByte\", dataType: \"byte\" },\n { name: \"voltageLowByte\", dataType: \"byte\" },\n { name: \"currentHighByte\", dataType: \"byte\" },\n { name: \"currentLowByte\", dataType: \"byte\" },\n { name: \"cellTempHighByte\", dataType: \"byte\" },\n { name: \"cellTempLowByte\", dataType: \"byte\" },\n { name: \"boardTempHighByte\", dataType: \"byte\" },\n { name: \"boardTempLowByte\", dataType: \"byte\" },\n { name: \"instantSaltLevelHighByte\", dataType: \"byte\" },\n { name: \"instantSaltLevelLowByte\", dataType: \"byte\" },\n { name: \"averageSaltLevelHighByte\", dataType: \"byte\" },\n { name: \"averageSaltLevelLowByte\", dataType: \"byte\" },\n ],\n },\n },\n SetUIEquipmentCmd: {\n opcode: 164,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n // a filter speed for a filter, 0/1 for everything else\n { name: \"isOn\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n GetScVersionCmd: {\n opcode: 167,\n read: true,\n request: [\n // a bus address, never 0\n { name: \"data\", type: \"int\" },\n ],\n response: {\n name: \"GetScVersionRsp\",\n opcode: 1167,\n parameters: [\n { name: \"stageMajor\", dataType: \"byte\" },\n { name: \"minorRev\", dataType: \"byte\" },\n { name: \"incremRev\", dataType: \"byte\" },\n { name: \"specRev1\", dataType: \"byte\" },\n { name: \"specRev2\", dataType: \"byte\" },\n { name: \"specRev3\", dataType: \"byte\" },\n ],\n },\n },\n SetScLedCmd: {\n opcode: 168,\n request: [\n { name: \"data\", type: \"int\" },\n { name: \"field1c\", type: \"int\" },\n ],\n },\n SetCHLORTimePercent: {\n opcode: 172,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetCHLORRelayPolarity: {\n opcode: 174,\n read: true,\n requires: [\"chlorinator\", \"chlorinator.cell\"],\n target: \"chlorinator.cell\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCHLORRelayPolarityRsp\",\n opcode: 1174,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"relaySetting\", dataType: \"byte\" },\n ],\n },\n },\n GetUICLLightStatus: {\n read: true,\n opcode: 199,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUICLLightStatusRsp\",\n opcode: 1199,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"colorLogicId\", dataType: \"int\" },\n { name: \"lightState\", dataType: \"byte\" },\n { name: \"whyLightIsOn\", dataType: \"byte\" },\n { name: \"currentShow\", dataType: \"byte\" },\n { name: \"speed\", dataType: \"byte\" },\n { name: \"brightness\", dataType: \"byte\" },\n { name: \"specialEffect\", dataType: \"byte\" },\n ],\n },\n },\n GetUICLIMStatus: {\n read: true,\n opcode: 200,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetCLSerialIdentifyStart: {\n opcode: 201,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLSerialIdentifyStop: {\n opcode: 202,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetUICLIMAuthenticate: {\n read: true,\n opcode: 203,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLIMUnlock: {\n opcode: 204,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetNetworkedLightStatus: {\n read: true,\n opcode: 205,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumAssignSeqStandard: {\n opcode: 206,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumAssignSeqCustom: {\n opcode: 207,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumAssignSeqStationary: {\n opcode: 208,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumUnassignAux: {\n opcode: 209,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumIdentifyStart: {\n opcode: 210,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLLightNumIdentifyStop: {\n opcode: 211,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxLightOnOff: {\n opcode: 212,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxUpdateSettingStationary: {\n opcode: 213,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxUpdateSettingStandard: {\n opcode: 214,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxUpdateSettingCustom: {\n opcode: 215,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxUpdateBrightness: {\n opcode: 216,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAuxRelease: {\n opcode: 217,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAllFindLightsStart: {\n opcode: 218,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAllFindLightsStop: {\n opcode: 219,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetUICLAllFindLightsReport: {\n read: true,\n opcode: 220,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAllResetToDefaults: {\n opcode: 221,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICLAllOnWhite: {\n opcode: 222,\n requires: [\"light\", \"light.networked\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetLightMode: {\n opcode: 223,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n IDV2Light: {\n opcode: 224,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetV2Mode: {\n opcode: 225,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetLightModeByRelay: {\n opcode: 226,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"field1c\", type: \"int\" },\n ],\n },\n SetV2ModeByRelay: {\n opcode: 227,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n CreateUIScheduleAltCmd: {\n opcode: 229,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"event\", type: \"int\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"enabled\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n CreateUIScheduleCmd: {\n opcode: 230,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n // the opcode the scheduler replays: 164 SetUIEquipmentCmd, 311 SetUISpilloverCmd, 317 RunGroupCmd\n { name: \"event\", type: \"int\" },\n { name: \"startHour\", type: \"byte\" },\n { name: \"startMinute\", type: \"byte\" },\n { name: \"endHour\", type: \"byte\" },\n { name: \"endMinute\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"enabled\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n DeleteUIScheduleCmd: {\n opcode: 231,\n request: [{ name: \"scheduleId\", type: \"int\" }],\n },\n SetUIScheduleEnableCmd: {\n opcode: 232,\n request: [\n { name: \"scheduleId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n // replaces the whole schedule\n EditUIScheduleCmd: {\n opcode: 233,\n request: [\n { name: \"scheduleId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n // the replayed opcode, as on CreateUIScheduleCmd\n { name: \"event\", type: \"int\" },\n { name: \"startHour\", type: \"byte\" },\n { name: \"startMinute\", type: \"byte\" },\n { name: \"endHour\", type: \"byte\" },\n { name: \"endMinute\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"enabled\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n EditUIScheduleAltCmd: {\n opcode: 234,\n request: [\n { name: \"scheduleId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"event\", type: \"int\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"enabled\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n UIGetCSADForcedOnTimeout: {\n read: true,\n opcode: 246,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADForcedOnTimeout: {\n opcode: 247,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n UIGetCSADAutoTimeout: {\n read: true,\n opcode: 248,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADAutoTimeout: {\n opcode: 249,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n UIGetCSADStatus: {\n read: true,\n opcode: 250,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIGetCSADStatusRsp\",\n opcode: 1250,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"csadid\", dataType: \"int\" },\n { name: \"ph\", dataType: \"float\" },\n { name: \"orp\", dataType: \"int\" },\n ],\n },\n },\n UIGetCSADRevision: {\n read: true,\n opcode: 251,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UIGetCSADTargetValue: {\n read: true,\n opcode: 252,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADTargetValue: {\n opcode: 253,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"targetValue\", type: \"float\" },\n ],\n },\n UIGetCSADPHAlarmLevel: {\n read: true,\n opcode: 256,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADPHAlarmLevel: {\n opcode: 257,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"float\" },\n { name: \"field1c\", type: \"float\" },\n ],\n },\n UIGetCSADEnabled: {\n read: true,\n opcode: 258,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADEnabled: {\n opcode: 259,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n UIGetCSADExtendEnabled: {\n read: true,\n opcode: 262,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADExtendEnabled: {\n opcode: 263,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n UIGetCSADType: {\n read: true,\n opcode: 264,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADType: {\n opcode: 265,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n UIGetCSADMode: {\n read: true,\n opcode: 266,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADMode: {\n opcode: 267,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n SetUISystemStateCmd: {\n opcode: 268,\n request: [\n // 0 off, 1 on, 2 service, 3 config, 4 timed service\n { name: \"data\", type: \"int\" },\n // the timed minutes\n { name: \"field1c\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"int\" },\n ],\n },\n GetUISuperCHLORTimeRemaining: {\n read: true,\n opcode: 270,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUISuperCHLORTimeRemainingRsp\",\n opcode: 1270,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"superChlorTimeRemaining\", dataType: \"int\" },\n ],\n },\n },\n UIGetCSADCalibrationValue: {\n read: true,\n opcode: 274,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UISetCSADCalibrationValue: {\n opcode: 275,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"calibrationValue\", type: \"float\" },\n ],\n },\n // the service or config state, answered with no opcode + 1000 reply\n GetUISystemStateCmd: {\n read: true,\n opcode: 278,\n request: [],\n },\n SetUICHLOROperatingMode: {\n opcode: 279,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUICHLOROperatingMode: {\n read: true,\n opcode: 280,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUICHLOROperatingModeRsp\",\n opcode: 1280,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"chlorId\", dataType: \"int\" },\n { name: \"operatingMode\", dataType: \"int\" },\n ],\n },\n },\n SetUICSADORPTargetLevel: {\n opcode: 281,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUICSADORPTargetLevel: {\n read: true,\n opcode: 282,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUICSADORPAlarmLevel: {\n opcode: 283,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"field1c\", type: \"int\" },\n ],\n },\n GetUICSADORPAlarmLevel: {\n read: true,\n opcode: 284,\n requires: [\"csad\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUIMultiHeaterPriorityCmd: {\n opcode: 289,\n requires: [\"heater\"],\n // the body's heat sources by appliance id, first priority first\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"rank1\", type: \"int\" },\n { name: \"rank2\", type: \"int\" },\n { name: \"rank3\", type: \"int\" },\n { name: \"rank4\", type: \"int\" },\n { name: \"rank5\", type: \"int\" },\n ],\n },\n SetChlorinatorScheduleCmd: {\n opcode: 290,\n requires: [\"chlorinator\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n caveat: {\n effect:\n \"sets a chlorinator percent override the firmware never clears on its own: the effective percent sticks, surviving even a restart, and masks later percent writes until RestoreChlorinatorPercentCmd clears it\",\n alternative: \"SetCHLORTimePercent\",\n },\n },\n RestoreChlorinatorPercentCmd: {\n opcode: 291,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n caveat: {\n effect:\n \"exists only to clear the percent override SetChlorinatorScheduleCmd leaves behind, and has no other use\",\n alternative: \"SetCHLORTimePercent\",\n },\n },\n ClearUIAlarmCmd: {\n opcode: 303,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIFilterStatus: {\n read: true,\n opcode: 306,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUIFilterStatusRsp\",\n opcode: 1306,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n { name: \"filterSpeed\", dataType: \"int\" },\n { name: \"filterState\", dataType: \"int\" },\n { name: \"whyFilterIsOn\", dataType: \"int\" },\n { name: \"valvePosition\", dataType: \"int\" },\n ],\n },\n },\n GetUIHeaterStatus: {\n read: true,\n opcode: 307,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUIHeaterStatusRsp\",\n opcode: 1307,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"isHeaterIsOn\", dataType: \"byte\" },\n { name: \"whyHeaterIsOn\", dataType: \"byte\" },\n { name: \"currentTemp\", dataType: \"byte\" },\n { name: \"setTemp\", dataType: \"byte\" },\n ],\n },\n },\n SetStandAloneLightShow: {\n opcode: 308,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n ResetStandAloneLight: {\n opcode: 309,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n GetStandAloneLightShow: {\n read: true,\n opcode: 310,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetStandAloneLightShowRsp\",\n opcode: 1310,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"lightId\", dataType: \"int\" },\n { name: \"show\", dataType: \"int\" },\n { name: \"speed\", dataType: \"int\" },\n { name: \"brightness\", dataType: \"int\" },\n { name: \"specialEffect\", dataType: \"int\" },\n ],\n },\n },\n SetUISpilloverCmd: {\n opcode: 311,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n caveat: {\n effect:\n \"moves the return valve. On some installs it is plumbed the other way around, so turning spillover on has the opposite effect and stops it\",\n },\n },\n GetUIPumpStatus: {\n read: true,\n opcode: 312,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetHeaterScheduleAltCmd: {\n opcode: 314,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n SetHeaterScheduleCmd: {\n opcode: 315,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n RestoreHeaterSetPointCmd: {\n opcode: 316,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n RunGroupCmd: {\n settle: true,\n opcode: 317,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n SaveNewGroupCmd: {\n settle: true,\n opcode: 318,\n request: [\n { name: \"name\", type: \"string\", maxLength: 12 },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n { name: \"poolId\", type: \"int\" },\n ],\n },\n SaveExistingGroupCmd: {\n opcode: 319,\n request: [{ name: \"equipmentId\", type: \"int\" }],\n },\n DeleteGroupCmd: {\n settle: true,\n opcode: 320,\n request: [{ name: \"equipmentId\", type: \"int\" }],\n },\n SetGroupCmd: {\n opcode: 321,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"name\", type: \"string\", maxLength: 12 },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n { name: \"poolId\", type: \"int\" },\n ],\n },\n TurnOnOffForGroup: {\n opcode: 322,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n // optional, 0 when absent\n { name: \"field1c\", type: \"int\" },\n ],\n },\n CreateUIFavoriteAltCmd: {\n opcode: 324,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n ],\n },\n CreateUIFavoriteCmd: {\n opcode: 325,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n DeleteUIFavoriteCmd: {\n opcode: 326,\n request: [{ name: \"data\", type: \"int\" }],\n },\n ModifyUIFavoriteCmd: {\n opcode: 327,\n request: [{ name: \"data\", type: \"int\" }],\n caveat: {\n effect: \"is acknowledged but does nothing\",\n alternative: \"DeleteUIFavoriteCmd\",\n },\n },\n UpdateButtonOnTerm: {\n opcode: 328,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"field1c\", type: \"int\" },\n { name: \"field20\", type: \"int\" },\n ],\n },\n GetRemainingCountdownTime: {\n read: true,\n opcode: 330,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetRemainingCountdownTimeRsp\",\n opcode: 1330,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"hour\", dataType: \"byte\" },\n { name: \"minute\", dataType: \"byte\" },\n { name: \"second\", dataType: \"byte\" },\n ],\n },\n },\n GetRemainingSCTime: {\n read: true,\n opcode: 331,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n UiEditConfigObjectName: {\n opcode: 332,\n request: [\n { name: \"equipmentId\", type: \"int\" },\n { name: \"name\", type: \"string\", maxLength: 13 },\n ],\n },\n UiGetConfigObjectName: {\n read: true,\n opcode: 333,\n request: [{ name: \"equipmentId\", type: \"int\" }],\n response: {\n name: \"UiGetConfigObjectNameRsp\",\n opcode: 1333,\n parameters: [\n { name: \"systemId\", dataType: \"int\" },\n { name: \"name\", dataType: \"string\" },\n ],\n },\n },\n SetSolarScheduleCmd: {\n opcode: 334,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n RestoreSolarSetPointCmd: {\n opcode: 335,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n RestoreIdleState: {\n opcode: 340,\n request: [],\n },\n SetDemandResponseCmd: {\n opcode: 341,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n { name: \"isCountDownTimer\", type: \"byte\" },\n { name: \"startTimeHours\", type: \"byte\" },\n { name: \"startTimeMinutes\", type: \"byte\" },\n { name: \"endTimeHours\", type: \"byte\" },\n { name: \"endTimeMinutes\", type: \"byte\" },\n { name: \"daysActive\", type: \"byte\" },\n { name: \"recurring\", type: \"byte\" },\n ],\n },\n SetPrimingDuration: {\n opcode: 350,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetPrimingDuration: {\n read: true,\n opcode: 351,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetPrimingDurationRsp\",\n opcode: 1351,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"duration\", dataType: \"int\" },\n ],\n },\n },\n SetCooldownDuration: {\n opcode: 352,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetCooldownDuration: {\n read: true,\n opcode: 353,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetCooldownDurationRsp\",\n opcode: 1353,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"duration\", dataType: \"int\" },\n ],\n },\n },\n SetSharedFilterTimeout: {\n opcode: 354,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetSharedFilterTimeout: {\n read: true,\n opcode: 355,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetSharedFilterTimeoutRsp\",\n opcode: 1355,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"timeout\", dataType: \"int\" },\n ],\n },\n },\n SetHeaterAllowLowSpeed: {\n opcode: 356,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterAllowLowSpeed: {\n read: true,\n opcode: 357,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterAllowLowSpeedRsp\",\n opcode: 1357,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n // the appliance id, not the thermostat's\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetHeaterLowSpeed: {\n opcode: 358,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetHeaterLowSpeed: {\n read: true,\n opcode: 359,\n requires: [\"heater\", \"heater.unit\"],\n target: \"heater.unit\",\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetHeaterLowSpeedRsp\",\n opcode: 1359,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n // the appliance id, not the thermostat's\n { name: \"heaterId\", dataType: \"int\" },\n { name: \"speed\", dataType: \"int\", unit: \"percent\" },\n ],\n },\n },\n SetUITestModeEnter: {\n opcode: 361,\n request: [],\n },\n SetUIDisplayModeState: {\n opcode: 378,\n request: [{ name: \"data\", type: \"int\" }],\n },\n GetUIDisplayModeState: {\n read: true,\n opcode: 379,\n request: [],\n response: {\n name: \"GetUIDisplayModeStateRsp\",\n // not opcode + 1000\n opcode: 1368,\n parameters: [{ name: \"state\", dataType: \"string\" }],\n },\n },\n SetUIPumpSpeed: {\n opcode: 380,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIPumpSpeed: {\n read: true,\n opcode: 381,\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n },\n SetUIFreezeProtectOverride: {\n opcode: 382,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIFreezeProtectOverride: {\n read: true,\n opcode: 383,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIFreezeProtectOverrideRsp\",\n // not opcode + 1000\n opcode: 1370,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n { name: \"enabled\", dataType: \"bool\" },\n ],\n },\n },\n SetUIFreezeProtectOverrideInterval: {\n opcode: 384,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n GetUIFreezeProtectOverrideInterval: {\n read: true,\n opcode: 385,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"UIFreezeProtectOverrideIntervalRsp\",\n // not opcode + 1000\n opcode: 1371,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"filterId\", dataType: \"int\" },\n { name: \"interval\", dataType: \"int\" },\n ],\n },\n },\n // power in BCD watts, revisions in ASCII\n GetUIFilterDiagnosticInfo: {\n read: true,\n opcode: 386,\n requires: [\"filter\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n ],\n response: {\n name: \"GetUIFilterDiagnosticInfoRsp\",\n opcode: 1386,\n parameters: [\n { name: \"poolId\", dataType: \"int\" },\n { name: \"equipmentId\", dataType: \"int\" },\n { name: \"powerLsb\", dataType: \"byte\" },\n { name: \"powerMsb\", dataType: \"byte\" },\n { name: \"errorStatus\", dataType: \"byte\" },\n { name: \"displayFwRevisionB1\", dataType: \"byte\" },\n { name: \"displayFwRevisionB2\", dataType: \"byte\" },\n { name: \"displayFwRevisionB3\", dataType: \"byte\" },\n { name: \"displayFwRevisionB4\", dataType: \"byte\" },\n { name: \"displayFwRevisionB5\", dataType: \"byte\" },\n { name: \"displayFwRevisionB6\", dataType: \"byte\" },\n { name: \"driveFwRevisionB1\", dataType: \"byte\" },\n { name: \"driveFwRevisionB2\", dataType: \"byte\" },\n { name: \"driveFwRevisionB3\", dataType: \"byte\" },\n { name: \"driveFwRevisionB4\", dataType: \"byte\" },\n { name: \"driveFwRevisionB5\", dataType: \"byte\" },\n { name: \"driveFwRevisionB6\", dataType: \"byte\" },\n ],\n },\n },\n SetUITemporaryHeaterEnable: {\n opcode: 400,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"int\" },\n ],\n },\n SetUITemporaryHeaterPriorityCmd: {\n opcode: 401,\n requires: [\"heater\"],\n // the body's heat sources by appliance id, first priority first\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"rank1\", type: \"int\" },\n { name: \"rank2\", type: \"int\" },\n { name: \"rank3\", type: \"int\" },\n { name: \"rank4\", type: \"int\" },\n { name: \"rank5\", type: \"int\" },\n ],\n },\n SetUITemporaryHeaterMaintainPriorityCmd: {\n opcode: 402,\n requires: [\"heater\"],\n request: [\n { name: \"poolId\", type: \"int\" },\n { name: \"equipmentId\", type: \"int\" },\n { name: \"data\", type: \"byte\" },\n { name: \"field19\", type: \"byte\" },\n { name: \"field1a\", type: \"byte\" },\n { name: \"field1b\", type: \"byte\" },\n { name: \"field1c\", type: \"byte\" },\n ],\n },\n SetCoordinates: {\n opcode: 416,\n request: [\n { name: \"latitude\", type: \"float\" },\n { name: \"longitude\", type: \"float\" },\n ],\n },\n GetCoordinates: {\n read: true,\n opcode: 417,\n request: [],\n response: {\n name: \"GetCoordinatesRsp\",\n opcode: 1417,\n parameters: [\n { name: \"latitude\", dataType: \"float\" },\n { name: \"longitude\", dataType: \"float\" },\n ],\n },\n },\n Unknown1414: {\n opcode: 1414,\n request: [],\n caveat: {\n effect:\n \"is acknowledged and then ignored: the controller does nothing with it and sends no reply\",\n },\n },\n});\n\nexport type CommandName = keyof typeof SPEC;\n\nexport type CommandOpcode = (typeof SPEC)[CommandName][\"opcode\"];\n\n// the three fetches, sent with no parameters and answered without an opcode + 1000 reply\nexport const SWITCH_OPCODE = {\n RequestConfiguration: 1,\n GetTelemetry: 300,\n GetSysInfo: 411,\n} as const;\n\nexport const COMMANDS: Record<\n CommandName,\n Omit<CommandSpec<CommandName>, \"opcode\"> & { opcode: CommandOpcode }\n> = SPEC;\n\ntype ParamValue<P> = P extends { values: (infer V)[] }\n ? V\n : P extends { type: \"string\" }\n ? string\n : number;\n\nexport type CommandParams<K extends CommandName> =\n (typeof SPEC)[K][\"request\"] extends (infer P extends CommandRequestParam)[]\n ? { [Q in P as Q[\"name\"]]: ParamValue<Q> }\n : Record<string, never>;\n\ntype ResultValue<D> = D extends \"bool\"\n ? boolean\n : D extends \"string\"\n ? string\n : number;\n\nexport type CommandResult<K extends CommandName> = (typeof SPEC)[K] extends {\n response: {\n parameters: (infer P extends CommandResponseParam)[];\n };\n}\n ? { [Q in P as Q[\"name\"]]: ResultValue<Q[\"dataType\"]> }\n : void;\n","export const FILTER_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"On\",\n 2: \"Priming\",\n 3: \"Waiting To Turn Off\",\n 4: \"Waiting To Turn Off (Manual)\",\n 5: \"Heater Extend\",\n 6: \"Cooldown\",\n 7: \"Suspend\",\n 8: \"CSAD Extend\",\n 9: \"Superchlorinate\",\n 10: \"Force Priming\",\n 11: \"Waiting For Pump To Turn Off\",\n 12: \"Waiting To Change Valves\",\n};\n\n// why a pump other than the filter pump is running\nexport const PUMP_WHY_ON: Record<number, string> = {\n 0: \"No Message\",\n 1: \"Freeze Protect\",\n 2: \"Interlock\",\n 3: \"Group On\",\n 4: \"Group Off\",\n 5: \"Manual Off\",\n 6: \"Countdown Done\",\n 7: \"End Schedule\",\n 8: \"Manual On\",\n 9: \"Countdown Timer\",\n 10: \"Schedule On\",\n};\n\nexport const PUMP_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"On\",\n 2: \"On (Freeze Protect)\",\n 3: \"Off (Valves Changing)\",\n 4: \"Priming\",\n // the firmware names no state 5\n 6: \"Waiting For Interlock\",\n 7: \"Paused\",\n};\n\nexport const SPEED_PRESET: Record<number, string> = {\n 0: \"Low\",\n 1: \"Medium\",\n 2: \"High\",\n};\n\nexport const FILTER_VALVE_POSITION: Record<number, string> = {\n 1: \"Pool Only\",\n 2: \"Spa Only\",\n 3: \"Spillover\",\n 4: \"Low Priority Heat\",\n 5: \"High Priority Heat\",\n};\n\nexport const FILTER_WHY_ON: Record<number, string> = {\n 0: \"Off\",\n 1: \"No Water Flow\",\n 2: \"Cooldown\",\n 3: \"CSAD Extend\",\n 4: \"Heater Extend\",\n 5: \"Pause\",\n 6: \"Off (Valve Changing)\",\n 7: \"Force High Speed\",\n 8: \"External Interlock\",\n 9: \"Superchlorinate\",\n 10: \"Countdown Timer\",\n 11: \"Manual On\",\n 12: \"Manual Spillover\",\n 13: \"Timed Spillover\",\n 14: \"Timed Event\",\n 15: \"Freeze Protect\",\n 16: \"Set Pool/Spa/Spillover\",\n 17: \"Spillover Countdown Timer\",\n 18: \"Group Command\",\n 19: \"Spillover Interlock\",\n 20: \"Max Value\",\n};\n\nexport const LIGHT_SPEED: Record<number, string> = {\n 0: \"1/16x\",\n 1: \"1/8x\",\n 2: \"1/4x\",\n 3: \"1/2x\",\n 4: \"1x\",\n 5: \"2x\",\n 6: \"4x\",\n 7: \"8x\",\n 8: \"16x\",\n};\n\nexport const LIGHT_BRIGHTNESS: Record<number, number> = {\n 0: 20,\n 1: 40,\n 2: 60,\n 3: 80,\n 4: 100,\n};\n\nexport const SYSTEM_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"On\",\n 2: \"Service Mode\",\n 3: \"Config Mode\",\n 4: \"Timed Service Mode\",\n};\n\n// the backyard is On\nexport const isRunning = (state: number) => state === 1;\n\nexport const HEATER_MODE: Record<number, string> = {\n 0: \"Heat\",\n 1: \"Cool\",\n 2: \"Auto\",\n 3: \"Off\",\n};\n\n// what the chemistry module is doing with the pH reducer\nexport const CSAD_MODE: Record<number, string> = {\n 0: \"Off\",\n 1: \"Auto\",\n 2: \"Forced On\",\n 3: \"Monitoring\",\n 4: \"Dispense Off\",\n};\n\n// the rank an appliance takes among a body's heat sources\nexport const HEATER_PRIORITY: Record<number, string> = {\n 0: \"Priority 1\",\n 1: \"Priority 2\",\n 2: \"Priority 3\",\n 3: \"Priority 4\",\n 4: \"Priority 5\",\n // not a rank, but the panel setting that puts solar ahead of everything\n 254: \"Solar First\",\n};\n\nexport const HEATER_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"On\",\n 2: \"Pause\",\n 3: \"Cool Down\",\n};\n\nexport const CHLORINATOR_OP_MODE: Record<number, string> = {\n 0: \"Not Config\",\n 1: \"Timed\",\n 2: \"ORP Auto\",\n};\n\nexport const CHLORINATOR_OPERATING_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"Paused\",\n 2: \"Generating\",\n};\n\nexport const CHLORINATOR_STATUS: Record<number, string> = {\n 1: \"Error Present\",\n 2: \"Alert Present\",\n 4: \"Generating\",\n 8: \"System Paused\",\n 16: \"Local Paused\",\n 32: \"Authenticated\",\n 64: \"K1 Active\",\n 128: \"K2 Active\",\n};\n\n// a word packed as fields from bit 0 up\nexport type PackedField = {\n // bits\n width: number;\n values: Record<number, string>;\n};\n\nexport const CHLORINATOR_ALERTS: PackedField[] = [\n {\n width: 2,\n values: {\n 1: \"Low Salt\",\n 2: \"Very Low Salt\",\n },\n },\n {\n width: 1,\n values: {\n 1: \"High Cell Current\",\n },\n },\n {\n width: 1,\n values: {\n 1: \"Low Cell Voltage\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Low Water Temp\",\n 2: \"Water Temp Scaleback\",\n 3: \"High Water Temp\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"High Board Temp\",\n 2: \"Board Temp Clearing\",\n },\n },\n {\n width: 1,\n values: {\n 1: \"ORP Overfeed Timeout\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Superchlorinating\",\n 2: \"Superchlorinate Timeout\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Clean Cell\",\n },\n },\n];\n\nexport const CHLORINATOR_ERRORS: PackedField[] = [\n {\n width: 2,\n values: {\n 1: \"Cell Current Sensor Shorted\",\n 2: \"Cell Current Sensor Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Cell Voltage Sensor Shorted\",\n 2: \"Cell Voltage Sensor Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Cell Temp Sensor Shorted\",\n 2: \"Cell Temp Sensor Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Board Temp Sensor Shorted\",\n 2: \"Board Temp Sensor Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Relay K1 Shorted\",\n 2: \"Relay K1 Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Relay K2 Shorted\",\n 2: \"Relay K2 Open\",\n },\n },\n {\n width: 2,\n values: {\n 1: \"Non-Hayward Cell\",\n 2: \"Cell Authentication Error\",\n },\n },\n];\n\nexport const RELAY_STATE: Record<number, string> = {\n 0: \"Off\",\n 1: \"On\",\n 2: \"On (Freeze Protect)\",\n 3: \"Waiting For Interlock\",\n 4: \"Paused\",\n 5: \"Waiting For Filter\",\n};\n\nexport const RELAY_WHY_ON: Record<number, string> = {\n 0: \"No Message\",\n 1: \"Manual Off\",\n 2: \"Countdown Done\",\n 3: \"End Schedule\",\n 4: \"Group Off\",\n 5: \"Manual On\",\n 6: \"Countdown Timer\",\n 7: \"Schedule On\",\n 8: \"Group On\",\n 9: \"Freeze Protect\",\n 10: \"Interlock\",\n};\n\nexport const bitmaskNames = (raw: number, map: Record<number, string>) => {\n const names: string[] = [];\n for (const [bit, name] of Object.entries(map)) {\n if ((raw & Number(bit)) !== 0) {\n names.push(name);\n }\n }\n if (names.length > 0) {\n return names.join(\", \");\n }\n return raw === 0 ? \"None\" : \"Unknown\";\n};\n\nexport const packedNames = (raw: number, fields: PackedField[]) => {\n const names: string[] = [];\n let shift = 0;\n for (const field of fields) {\n const value = (raw >> shift) & ((1 << field.width) - 1);\n if (value !== 0) {\n names.push(field.values[value] ?? \"Unknown\");\n }\n shift += field.width;\n }\n return names.length > 0 ? names.join(\", \") : \"None\";\n};\n","// the water temperature while the filter pump is off or the sensor reports nothing\nexport const WATER_TEMP_UNAVAILABLE = -1;\n\n// the air temperature while the backyard sensor is unplugged or faulted\nexport const AIR_TEMP_UNAVAILABLE = -1;\n\n// the heater temperature with no valid reading\nexport const HEATER_TEMP_UNAVAILABLE = 65535;\n\n// the ORP with no reading from the probe\nexport const ORP_UNAVAILABLE = -1;\n\n// the pH with no reading from the probe\nexport const PH_UNAVAILABLE = 0;\n","import { SYSTEM_STATE } from \"@/constants/labels\";\nimport type { Inventory } from \"@/utils/inventory\";\n\nconst stateName = (state: number) => SYSTEM_STATE[state] ?? String(state);\n\nexport class OmniLogicError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"OmniLogicError\";\n }\n}\n\nexport class OmniTimeoutError extends OmniLogicError {\n constructor(message: string) {\n super(message);\n this.name = \"OmniTimeoutError\";\n }\n}\n\nexport class OmniValidationError extends OmniLogicError {\n constructor(message: string) {\n super(message);\n this.name = \"OmniValidationError\";\n }\n}\n\nexport class CommandFailedError extends OmniLogicError {\n command: string;\n attempts: number;\n\n constructor(details: {\n message: string;\n command: string;\n attempts: number;\n cause?: unknown;\n }) {\n super(details.message, { cause: details.cause });\n this.name = \"CommandFailedError\";\n this.command = details.command;\n this.attempts = details.attempts;\n }\n}\n\nexport class ReadingUnavailableError extends OmniLogicError {\n backyardState: number;\n\n constructor(details: { name: string; backyardState: number }) {\n super(\n `\"${details.name}\" telemetry is not reliable while the controller is not in normal operating state (state: ${stateName(details.backyardState)})`,\n );\n this.name = \"ReadingUnavailableError\";\n this.backyardState = details.backyardState;\n }\n}\n\nexport class SystemStateError extends OmniLogicError {\n command: string;\n backyardState: number;\n\n constructor(details: { command: string; backyardState: number }) {\n super(\n `${details.command} refused: the controller must be in a normal operating state (state: ${stateName(details.backyardState)}).\\n\\nPass { force: true } to ignore this error.`,\n );\n this.name = \"SystemStateError\";\n this.command = details.command;\n this.backyardState = details.backyardState;\n }\n}\n\nexport class FirmwareTooOldError extends OmniLogicError {\n version: string;\n minimum: string;\n\n constructor(details: { version: string; minimum: string }) {\n super(\n `This controller reports firmware ${details.version}, below the ${details.minimum} this library was built against, so nothing it sends can be trusted.\\n\\nPass { force: true } to refresh() or command() to ignore this error; fetchTelemetry() works either way.`,\n );\n this.name = \"FirmwareTooOldError\";\n this.version = details.version;\n this.minimum = details.minimum;\n }\n}\n\nexport class EquipmentNotInstalledError extends OmniLogicError {\n command: string;\n requirement: string;\n poolId: number;\n hint: string | undefined;\n inventory: Inventory;\n\n constructor(details: {\n command: string;\n requirement: string;\n poolId: number;\n hint?: string;\n inventory: Inventory;\n }) {\n const why =\n details.hint ??\n (details.requirement === \"body\"\n ? `no body of water with id ${details.poolId}`\n : `${details.requirement} is absent on body ${details.poolId}`);\n super(\n `${details.command} refused: ${why}.\\n\\nPass { force: true } to ignore this error.`,\n );\n this.name = \"EquipmentNotInstalledError\";\n this.command = details.command;\n this.requirement = details.requirement;\n this.poolId = details.poolId;\n this.hint = details.hint;\n this.inventory = details.inventory;\n }\n}\n","export const numberOf = (v: unknown) =>\n typeof v === \"number\" && Number.isFinite(v) ? v : undefined;\n\nexport const stringOf = (v: unknown) =>\n typeof v === \"string\" && v !== \"\" ? v : undefined;\n\nexport const defined = <T extends object>(obj: T) => {\n const out: Partial<T> = {};\n for (const key in obj) {\n if (obj[key] !== undefined) {\n out[key] = obj[key];\n }\n }\n return out;\n};\n\nexport const matches = <E extends object>(\n actual: { [K in keyof E]?: unknown } | undefined,\n expected: E,\n) => {\n if (actual === undefined) {\n return false;\n }\n for (const key in expected) {\n if (actual[key] !== expected[key]) {\n return false;\n }\n }\n return true;\n};\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== \"object\") {\n return false;\n }\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n};\n\nexport const findBySystemId = (\n parent: unknown,\n systemId: number,\n): Record<string, unknown> | undefined => {\n if (!isRecord(parent)) {\n return undefined;\n }\n for (const value of Object.values(parent)) {\n for (const item of Array.isArray(value) ? value : [value]) {\n if (!isRecord(item)) {\n continue;\n }\n if (Number(item.systemId) === systemId) {\n return item;\n }\n const found = findBySystemId(item, systemId);\n if (found !== undefined) {\n return found;\n }\n }\n }\n return undefined;\n};\n","import type { BodyOfWater, MSPConfig } from \"@/types/config\";\nimport { OmniLogicError } from \"@/utils/errors\";\nimport { isRecord, numberOf, stringOf } from \"@/utils/helpers\";\n\nexport type Presence = \"installed\" | \"absent\" | \"unknown\";\n\ntype Slot<T = object> =\n | ({ presence: \"installed\"; systemId: number } & T)\n | { presence: \"absent\" }\n | { presence: \"unknown\" };\n\ntype CellSlot = Slot<{\n cellType: string | undefined;\n feeder: Presence;\n}>;\n\ntype HeaterUnitSlot = Slot<{ heaterType: string | undefined }>;\n\ntype BodyInventory = {\n systemId: number;\n // a pool and spa sharing one filter pump\n spillover: Presence;\n csad: Slot;\n filter: Slot<{ vsp: Presence }>;\n heater: Slot<{\n heaterType: string | undefined;\n gas: Presence;\n unit: HeaterUnitSlot;\n }>;\n chlorinator: Slot<{\n cell: CellSlot;\n }>;\n light: Slot<{ networked: Presence }>;\n blower: Slot;\n};\n\nexport type Inventory = {\n bodies: BodyInventory[];\n};\n\nexport const INVENTORY_PATHS = [\n \"filter\",\n \"filter.vsp\",\n \"heater\",\n \"heater.gas\",\n \"heater.unit\",\n \"chlorinator\",\n \"chlorinator.cell\",\n \"chlorinator.feeder\",\n \"csad\",\n \"light\",\n \"light.networked\",\n \"blower\",\n \"spillover\",\n] as const;\n\nexport type InventoryPath = (typeof INVENTORY_PATHS)[number];\n\nconst unreachablePath = (path: never) => {\n throw new OmniLogicError(`Unhandled inventory path ${String(path)}`);\n};\n\nconst VARIABLE_SPEED_FILTER_TYPES: Set<string> = new Set([\n \"FMT_VARIABLE_SPEED_PUMP\",\n]);\n\nconst SINGLE_SPEED_FILTER_TYPES: Set<string> = new Set([\n \"FMT_SINGLE_SPEED\",\n \"FMT_DUAL_SPEED\",\n]);\n\nconst GAS_HEATER_TYPES: Set<string> = new Set([\"HTR_GAS\", \"HTR_SMART_GAS\"]);\n\nconst OTHER_HEATER_TYPES: Set<string> = new Set([\n \"HTR_HEAT_PUMP\",\n \"HTR_SOLAR\",\n \"HTR_ELECTRIC\",\n \"HTR_GEOTHERMAL\",\n \"HTR_CHILLER\",\n \"HTR_SMART_HEAT_PUMP\",\n \"HTR_SMART_VSHP\",\n]);\n\nexport const hasSystemId = <T>(node: T): node is T & { systemId: number } =>\n isRecord(node) && numberOf(node.systemId) !== undefined;\n\nconst presenceByType = (\n type: string | undefined,\n installedTypes: Set<string>,\n absentTypes: Set<string>,\n): Presence => {\n if (type === undefined) {\n return \"unknown\";\n }\n if (installedTypes.has(type)) {\n return \"installed\";\n }\n if (absentTypes.has(type)) {\n return \"absent\";\n }\n return \"unknown\";\n};\n\nconst filterOf = (bow: BodyOfWater): BodyInventory[\"filter\"] => {\n const filter = bow.filter;\n if (!hasSystemId(filter)) {\n return { presence: \"absent\" };\n }\n return {\n presence: \"installed\",\n systemId: filter.systemId,\n vsp: presenceByType(\n stringOf(filter.filterType),\n VARIABLE_SPEED_FILTER_TYPES,\n SINGLE_SPEED_FILTER_TYPES,\n ),\n };\n};\n\nconst heaterOf = (bow: BodyOfWater): BodyInventory[\"heater\"] => {\n const heater = bow.heater;\n if (!hasSystemId(heater)) {\n return { presence: \"absent\" };\n }\n const appliances = heater.operations.flatMap((o) => o.heaterEquipment ?? []);\n const types = appliances.map((e) => stringOf(e.heaterType));\n const first = appliances[0];\n const heaterType = types[0];\n const unit: HeaterUnitSlot = hasSystemId(first)\n ? { presence: \"installed\", systemId: first.systemId, heaterType }\n : { presence: \"absent\" };\n const burnsGas = types.map((t) =>\n presenceByType(t, GAS_HEATER_TYPES, OTHER_HEATER_TYPES),\n );\n const gas: Presence = burnsGas.includes(\"installed\")\n ? \"installed\"\n : burnsGas.length > 0 && burnsGas.every((p) => p === \"absent\")\n ? \"absent\"\n : \"unknown\";\n return {\n presence: \"installed\",\n systemId: heater.systemId,\n heaterType,\n gas,\n unit,\n };\n};\n\nconst FEEDER_CELL_TYPES = new Set([\"CELL_TYPE_LIQUID\", \"CELL_TYPE_TABLET\"]);\n\nconst SALT_CELL_TYPES = new Set([\n \"CELL_TYPE_T3\",\n \"CELL_TYPE_T5\",\n \"CELL_TYPE_T9\",\n \"CELL_TYPE_T15\",\n \"CELL_TYPE_T15_LS\",\n \"CELL_TYPE_TCELLS315\",\n \"CELL_TYPE_TCELLS325\",\n \"CELL_TYPE_TCELLS340\",\n]);\n\nconst flag = (value: boolean): Presence => (value ? \"installed\" : \"absent\");\n\nconst chlorinatorOf = (bow: BodyOfWater): BodyInventory[\"chlorinator\"] => {\n const chlorinator = bow.chlorinator;\n if (!hasSystemId(chlorinator)) {\n return { presence: \"absent\" };\n }\n const cell = chlorinator.operations\n .map((o) => o.chlorinatorEquipment)\n .find(hasSystemId);\n const cellType = stringOf(chlorinator.cellType);\n return {\n presence: \"installed\",\n systemId: chlorinator.systemId,\n cell:\n cell === undefined\n ? { presence: \"absent\" }\n : {\n presence: \"installed\",\n systemId: cell.systemId,\n cellType,\n feeder: presenceByType(\n cellType,\n FEEDER_CELL_TYPES,\n SALT_CELL_TYPES,\n ),\n },\n };\n};\n\nconst slotOf = (node: unknown): Slot =>\n hasSystemId(node)\n ? { presence: \"installed\", systemId: node.systemId }\n : { presence: \"absent\" };\n\nconst lightOf = (bow: BodyOfWater): BodyInventory[\"light\"] => {\n const light = bow.colorLogicLights[0];\n if (!hasSystemId(light)) {\n return { presence: \"absent\" };\n }\n return {\n presence: \"installed\",\n systemId: light.systemId,\n networked: flag(light.networked),\n };\n};\n\nconst blowerOf = (bow: BodyOfWater): Slot =>\n slotOf(bow.relays.find((r) => stringOf(r.function) === \"RLY_BLOWER\"));\n\nconst spilloverOf = (bow: BodyOfWater, bodies: BodyOfWater[]): Presence => {\n const sharedType = stringOf(bow.sharedType);\n if (sharedType === \"BOW_SHARED_EQUIPMENT\") {\n const partner = bodies.find(\n (b) => b.systemId === bow.sharedEquipmentSystemId,\n );\n return partner !== undefined && partner.type !== bow.type\n ? \"installed\"\n : \"unknown\";\n }\n return sharedType === undefined || sharedType === \"BOW_NO_EQUIPMENT_SHARED\"\n ? \"absent\"\n : \"unknown\";\n};\n\nconst bodyOf = (bow: BodyOfWater, bodies: BodyOfWater[]): BodyInventory => {\n return {\n systemId: bow.systemId,\n spillover: spilloverOf(bow, bodies),\n csad: slotOf(bow.csad),\n filter: filterOf(bow),\n heater: heaterOf(bow),\n chlorinator: chlorinatorOf(bow),\n light: lightOf(bow),\n blower: blowerOf(bow),\n };\n};\n\nexport const discover = (config: MSPConfig): Inventory => ({\n bodies: config.backyard.bodiesOfWater\n .filter(hasSystemId)\n .map((bow) => bodyOf(bow, config.backyard.bodiesOfWater)),\n});\n\nexport const presenceAt = (body: BodyInventory, path: InventoryPath) => {\n switch (path) {\n case \"filter\":\n return body.filter.presence;\n case \"filter.vsp\":\n return body.filter.presence === \"installed\"\n ? body.filter.vsp\n : body.filter.presence;\n case \"heater\":\n return body.heater.presence;\n case \"heater.gas\":\n return body.heater.presence === \"installed\"\n ? body.heater.gas\n : body.heater.presence;\n case \"heater.unit\":\n return body.heater.presence === \"installed\"\n ? body.heater.unit.presence\n : body.heater.presence;\n case \"chlorinator\":\n return body.chlorinator.presence;\n case \"chlorinator.cell\":\n return body.chlorinator.presence === \"installed\"\n ? body.chlorinator.cell.presence\n : body.chlorinator.presence;\n case \"chlorinator.feeder\":\n return body.chlorinator.presence === \"installed\"\n ? body.chlorinator.cell.presence === \"installed\"\n ? body.chlorinator.cell.feeder\n : body.chlorinator.cell.presence\n : body.chlorinator.presence;\n case \"csad\":\n return body.csad.presence;\n case \"light\":\n return body.light.presence;\n case \"light.networked\":\n return body.light.presence === \"installed\"\n ? body.light.networked\n : body.light.presence;\n case \"blower\":\n return body.blower.presence;\n case \"spillover\":\n return body.spillover;\n default:\n return unreachablePath(path);\n }\n};\n\nexport const systemIdAt = (body: BodyInventory, path: InventoryPath) => {\n const slot = (() => {\n switch (path) {\n case \"filter\":\n case \"filter.vsp\":\n return body.filter;\n case \"heater\":\n case \"heater.gas\":\n return body.heater;\n case \"heater.unit\":\n return body.heater.presence === \"installed\"\n ? body.heater.unit\n : undefined;\n case \"chlorinator\":\n return body.chlorinator;\n case \"chlorinator.cell\":\n case \"chlorinator.feeder\":\n return body.chlorinator.presence === \"installed\"\n ? body.chlorinator.cell\n : undefined;\n case \"light\":\n case \"light.networked\":\n return body.light;\n case \"blower\":\n return body.blower;\n case \"csad\":\n return body.csad;\n case \"spillover\":\n return undefined;\n default:\n return unreachablePath(path);\n }\n })();\n return slot?.presence === \"installed\" ? slot.systemId : undefined;\n};\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { isRunning } from \"@/constants/labels\";\nimport { OmniLogicError, ReadingUnavailableError } from \"@/utils/errors\";\nimport { systemIdAt, type InventoryPath } from \"@/utils/inventory\";\n\nexport class Device {\n #poolId: number;\n #equipmentId: number;\n #name: string;\n #omni: OmniLogic;\n\n constructor(\n omni: OmniLogic,\n poolId: number,\n equipmentId: number,\n name: string,\n ) {\n this.#omni = omni;\n this.#poolId = poolId;\n this.#equipmentId = equipmentId;\n this.#name = name;\n }\n\n get omni() {\n return this.#omni;\n }\n\n // the body of water this one belongs to\n get poolId() {\n return this.#poolId;\n }\n\n get equipmentId() {\n return this.#equipmentId;\n }\n\n get name() {\n return this.#name;\n }\n\n get running() {\n return isRunning(this.omni.telemetry.backyard.state);\n }\n\n // this device's body in the cached config\n get bodyConfig() {\n return this.omni.config.backyard.bodiesOfWater.find(\n (b) => b.systemId === this.poolId,\n );\n }\n\n // this device's body in the inventory\n get inventoryBody() {\n const found = this.omni.inventory.bodies.find(\n (b) => b.systemId === this.poolId,\n );\n if (found === undefined) {\n throw new OmniLogicError(`No inventory for \"${this.name}\"`);\n }\n return found;\n }\n\n // a part's system id, or this device's id\n idAt(path: InventoryPath) {\n return systemIdAt(this.inventoryBody, path) ?? this.equipmentId;\n }\n\n requireRunning() {\n if (!this.running) {\n throw new ReadingUnavailableError({\n name: this.name,\n backyardState: this.omni.telemetry.backyard.state,\n });\n }\n }\n\n // whether the controller is on and reports this device\n reportedIn(list: { systemId: number }[]) {\n return this.running && list.some((r) => r.systemId === this.equipmentId);\n }\n\n // a config node of this device, which must be there\n configured<T>(node: T | undefined): T {\n if (node === undefined) {\n throw new OmniLogicError(`No configuration for \"${this.name}\"`);\n }\n return node;\n }\n\n telemetry<T extends { systemId: number }>(list: T[]) {\n const found = list.find((r) => r.systemId === this.equipmentId);\n if (found === undefined) {\n throw new OmniLogicError(`No telemetry for \"${this.name}\"`);\n }\n return found;\n }\n}\n","// the cell thermistor curve, tenths of °F\nconst THERMISTOR: number[] = [\n 8000, 3740, 3136, 2817, 2603, 2444, 2318, 2214, 2125, 2048, 1980, 1919, 1864,\n 1813, 1767, 1723, 1683, 1645, 1610, 1576, 1544, 1514, 1485, 1458, 1431, 1406,\n 1381, 1358, 1335, 1313, 1291, 1270, 1250, 1230, 1211, 1193, 1174, 1156, 1139,\n 1122, 1105, 1088, 1072, 1056, 1041, 1025, 1010, 995, 980, 966, 951, 937, 923,\n 909, 895, 881, 868, 854, 841, 828, 815, 802, 789, 776, 763, 750, 737, 725,\n 712, 699, 687, 674, 661, 649, 636, 624, 611, 598, 586, 573,\n];\n\n// a 16-bit value sent as two bytes\nexport const word = (high: number, low: number) => high * 256 + low;\n\n// cell voltage: ADC count → volts\nexport const cellVolts = (raw: number) => ((raw * 5) / 255) * 8.15;\n\n// cell current: ADC count → amps, a raw 0 reported as 0\nexport const cellAmps = (raw: number) =>\n raw === 0 ? 0 : (raw * 5) / 255 / 0.489;\n\n// thermistor count → °F, NaN past the table's end (raw ≥ 640)\nexport const thermistorF = (raw: number) => {\n const i = raw >> 3;\n const lo = THERMISTOR[i];\n if (lo === undefined) {\n return Number.NaN;\n }\n const hi = THERMISTOR[i + 1] ?? lo;\n return (lo + ((raw & 7) / 8) * (hi - lo)) / 10;\n};\n\n// two BCD nibbles → the decimal they spell (0x58 → 58)\nconst bcd = (byte: number) => (byte >> 4) * 10 + (byte & 0x0f);\n\n// the pump drive's power: two BCD bytes spelling watts\nexport const bcdWatts = (msb: number, lsb: number) => bcd(msb) * 100 + bcd(lsb);\n\n// six ASCII bytes → their digits, spaces and nulls dropped (\"1015 \" → \"1015\")\nconst revisionDigits = (bytes: number[]) =>\n String.fromCharCode(...bytes).replaceAll(/[^0-9]/g, \"\");\n\n// the display board's revision as the panel shows it: \"1015\" → \"10.1.5\"\nexport const displayRevision = (bytes: number[]) => {\n const d = revisionDigits(bytes);\n return d.length >= 4\n ? `${d.slice(0, 2)}.${d.slice(2, 3)}.${d.slice(3, 4)}`\n : d;\n};\n\n// the drive's revision as the panel shows it: \"0073\" → \"0.73\"\nexport const driveRevision = (bytes: number[]) => {\n const d = revisionDigits(bytes);\n return d.length >= 4 ? `${Number(d.slice(0, 2))}.${d.slice(2, 4)}` : d;\n};\n","import type { ReadOptions } from \"@/client/omnilogic\";\nimport {\n bitmaskNames,\n CHLORINATOR_ALERTS,\n CHLORINATOR_ERRORS,\n CHLORINATOR_OP_MODE,\n CHLORINATOR_OPERATING_STATE,\n CHLORINATOR_STATUS,\n packedNames,\n} from \"@/constants/labels\";\nimport { Device } from \"@/equipment/device\";\nimport { cellAmps, cellVolts, thermistorF, word } from \"@/utils/decode\";\nimport { OmniValidationError } from \"@/utils/errors\";\nimport { presenceAt } from \"@/utils/inventory\";\n\nexport type CellStatus = {\n // a label, or the code with { raw: true }\n opState: number | string;\n scState: number;\n alertStatus: number;\n // ppm\n instantSalt: number;\n averageSalt: number;\n // only a liquid or tablet feeder dispenses\n activelyDispensing?: boolean;\n};\n\nexport type CellMeasurement = {\n // volts, or the ADC count with { raw: true }\n voltage: number;\n // amps, or the ADC count with { raw: true }\n current: number;\n // °F, or the thermistor count with { raw: true }\n cellTemp: number;\n boardTemp: number;\n // ppm\n instantSalt: number;\n averageSalt: number;\n};\n\nexport class Chlorinator extends Device {\n get state() {\n return this.telemetry(this.omni.telemetry.chlorinators);\n }\n\n get #reported() {\n return this.reportedIn(this.omni.telemetry.chlorinators);\n }\n\n get #runningState() {\n this.requireRunning();\n return this.state;\n }\n\n get #config() {\n return this.configured(this.bodyConfig?.chlorinator);\n }\n\n get enabled() {\n return this.#runningState.enable !== 0;\n }\n\n setEnabled(on: boolean) {\n return this.omni.command(\"SetCHLOREnable\", {\n poolId: this.poolId,\n data: Number(on),\n });\n }\n\n get timedPercent() {\n return this.#config.timedPercent;\n }\n\n setTimedPercent(percent: number) {\n if (!Number.isInteger(percent) || percent < 0 || percent > 100) {\n throw new OmniValidationError(\n `Timed percent ${percent} is not a whole number from 0 to 100`,\n );\n }\n return this.omni.command(\"SetCHLORTimePercent\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: percent,\n });\n }\n\n get operatingState() {\n return this.#reported\n ? (CHLORINATOR_OPERATING_STATE[this.state.operatingState] ?? \"Unknown\")\n : \"Off\";\n }\n\n // whether a probe or the clock decides the output\n get operatingMode() {\n return this.#reported\n ? (CHLORINATOR_OP_MODE[this.state.operatingMode] ?? \"Unknown\")\n : \"Not Config\";\n }\n\n // every condition the cell reports at once, such as \"Generating, K1 Active\"\n get conditions() {\n return this.#reported\n ? bitmaskNames(this.state.status, CHLORINATOR_STATUS)\n : \"None\";\n }\n\n // what the cell is warning about, such as \"Low Salt, Clean Cell\"\n get alert() {\n return packedNames(this.#runningState.chlrAlert, CHLORINATOR_ALERTS);\n }\n\n // the faults the cell reports, such as \"Relay K1 Open\"\n get error() {\n return packedNames(this.#runningState.chlrError, CHLORINATOR_ERRORS);\n }\n\n // ppm\n get averageSalt() {\n return this.#runningState.avgSaltLevel;\n }\n\n // ppm\n get instantSalt() {\n return this.#runningState.instantSaltLevel;\n }\n\n get isSuperchlorinating() {\n return this.#reported && this.state.scMode !== 0;\n }\n\n superchlorinate(on = true) {\n return this.omni.command(\"SetUISuperCHLORCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n get superchlorinateHours() {\n return this.#config.superChlorTimeout;\n }\n\n setSuperchlorinateHours(hours: number) {\n return this.omni.command(\"SetUISuperCHLORTimeoutCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: hours,\n });\n }\n\n async superchlorinateMinutesRemaining() {\n const r = await this.omni.command(\"GetUISuperCHLORTimeRemaining\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n });\n return r.superChlorTimeRemaining;\n }\n\n async relayPolarity() {\n const r = await this.omni.command(\"GetCHLORRelayPolarity\", {\n poolId: this.poolId,\n equipmentId: this.idAt(\"chlorinator.cell\"),\n });\n return r.relaySetting;\n }\n\n async cellStatus(options: ReadOptions = {}): Promise<CellStatus> {\n const r = await this.omni.command(\"GetCHLORStatus\", {\n poolId: this.poolId,\n equipmentId: this.idAt(\"chlorinator.cell\"),\n });\n const opState = r.opState;\n const reading: CellStatus = {\n opState: options.raw\n ? opState\n : (CHLORINATOR_OPERATING_STATE[opState] ?? \"Unknown\"),\n scState: r.scState,\n alertStatus: r.alertStatus,\n instantSalt: word(r.instantSaltHigh, r.instantSaltLow),\n averageSalt: word(r.averageSaltHigh, r.averageSaltLow),\n };\n if (presenceAt(this.inventoryBody, \"chlorinator.feeder\") !== \"absent\") {\n reading.activelyDispensing = r.activelyDispensing === 1;\n }\n return reading;\n }\n\n async cellMeasurement(options: ReadOptions = {}): Promise<CellMeasurement> {\n const r = await this.omni.command(\"GetCHLORMeasurement\", {\n poolId: this.poolId,\n equipmentId: this.idAt(\"chlorinator.cell\"),\n });\n const voltage = word(r.voltageHighByte, r.voltageLowByte);\n const current = word(r.currentHighByte, r.currentLowByte);\n const cellTemp = word(r.cellTempHighByte, r.cellTempLowByte);\n const boardTemp = word(r.boardTempHighByte, r.boardTempLowByte);\n const salt = {\n instantSalt: word(r.instantSaltLevelHighByte, r.instantSaltLevelLowByte),\n averageSalt: word(r.averageSaltLevelHighByte, r.averageSaltLevelLowByte),\n };\n if (options.raw) {\n return { voltage, current, cellTemp, boardTemp, ...salt };\n }\n return {\n voltage: cellVolts(voltage),\n current: cellAmps(current),\n cellTemp: thermistorF(cellTemp),\n boardTemp: thermistorF(boardTemp),\n ...salt,\n };\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { CSAD_MODE } from \"@/constants/labels\";\nimport { ORP_UNAVAILABLE, PH_UNAVAILABLE } from \"@/constants/sentinels\";\nimport { Device } from \"@/equipment/device\";\nimport type { CSAD as CSADConfig } from \"@/types/config\";\nimport { OmniValidationError } from \"@/utils/errors\";\n\ntype Scale = { min: number; max: number; step: number };\n\n// the scales the panel offers\nconst PH_SCALE: Scale = { min: 7, max: 8, step: 0.1 };\nconst ORP_SCALE: Scale = { min: 400, max: 900, step: 5 };\n\nconst onScale = (value: number, { min, max, step }: Scale, what: string) => {\n const steps = Math.round((value - min) / step);\n if (value < min || value > max || min + steps * step !== value) {\n throw new OmniValidationError(\n `${what} ${value} is not between ${min} and ${max} in steps of ${step}`,\n );\n }\n return value;\n};\n\n// chemistry sense and dispense\nexport class CSAD extends Device {\n constructor(omni: OmniLogic, poolId: number, config: CSADConfig) {\n super(omni, poolId, config.systemId, config.name);\n }\n\n get #config() {\n return this.configured(this.bodyConfig?.csad);\n }\n\n // what reduces the pH: ACID or CO2\n get type() {\n return this.#config.type;\n }\n\n get enabled() {\n return this.#config.enabled;\n }\n\n get phTarget() {\n return Number(this.#config.targetValue);\n }\n\n // the offset between the tested and the displayed reading\n get phCalibration() {\n return Number(this.#config.calibrationValue);\n }\n\n get phLowAlarm() {\n return Number(this.#config.phLowAlarmLevel);\n }\n\n get phHighAlarm() {\n return Number(this.#config.phHighAlarmLevel);\n }\n\n get orpTarget() {\n return this.#config.orpTargetLevel;\n }\n\n get orpLowAlarm() {\n return this.#config.orpLowAlarmLevel;\n }\n\n get orpHighAlarm() {\n return this.#config.orpHighAlarmLevel;\n }\n\n get state() {\n return this.telemetry(this.omni.telemetry.csads);\n }\n\n get #reported() {\n return this.reportedIn(this.omni.telemetry.csads);\n }\n\n // without the calibration offset applied\n get ph() {\n if (!this.#reported) {\n return undefined;\n }\n const ph = Number(this.state.ph);\n return ph === PH_UNAVAILABLE ? undefined : ph;\n }\n\n get orp() {\n if (!this.#reported) {\n return undefined;\n }\n const orp = this.state.orp;\n return orp === ORP_UNAVAILABLE ? undefined : orp;\n }\n\n get mode() {\n return this.#reported ? (CSAD_MODE[this.state.mode] ?? \"Unknown\") : \"Off\";\n }\n\n get isDispensing() {\n return this.#reported && this.state.status === 1;\n }\n\n setPhTarget(ph: number) {\n return this.omni.command(\"UISetCSADTargetValue\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n targetValue: onScale(ph, PH_SCALE, \"pH\"),\n });\n }\n\n setOrpTarget(millivolts: number) {\n return this.omni.command(\"SetUICSADORPTargetLevel\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: onScale(millivolts, ORP_SCALE, \"ORP\"),\n });\n }\n}\n","import type { OmniLogic, WriteOptions } from \"@/client/omnilogic\";\nimport { OmniValidationError } from \"@/utils/errors\";\nimport { defined, matches } from \"@/utils/helpers\";\n\nexport const SCHEDULE_MONDAY = 1;\nexport const SCHEDULE_TUESDAY = 2;\nexport const SCHEDULE_WEDNESDAY = 4;\nexport const SCHEDULE_THURSDAY = 8;\nexport const SCHEDULE_FRIDAY = 16;\nexport const SCHEDULE_SATURDAY = 32;\nexport const SCHEDULE_SUNDAY = 64;\nexport const SCHEDULE_EVERY_DAY = 127;\n\nexport const SCHEDULE_SUNRISE_HOUR = 25;\nexport const SCHEDULE_SUNSET_HOUR = 26;\nexport const SCHEDULE_SUNRISE_SUNSET_MINUTE = 25;\n\nexport const SCHEDULE_TYPE = {\n equipment: 164,\n spillover: 311,\n theme: 317,\n} as const;\n\nexport type ScheduleType = keyof typeof SCHEDULE_TYPE;\n\nexport const scheduleTypeOf = (event: number) =>\n ([\"equipment\", \"spillover\", \"theme\"] as const).find(\n (type) => SCHEDULE_TYPE[type] === event,\n );\n\nexport type ScheduleCreate = {\n equipmentId: number;\n // the value to set: a speed, a show, a percent, a set point, 1/0 for a relay\n data: number;\n // default \"equipment\"\n type?: ScheduleType;\n startHour: number;\n startMinute?: number;\n endHour: number;\n endMinute?: number;\n // a bit per day, the constants above added together\n days: number;\n // default true\n enabled?: boolean;\n // default true\n recurring?: boolean;\n};\n\nexport type ScheduleUpdate = Partial<Omit<ScheduleCreate, \"equipmentId\">>;\n\nexport class Schedules {\n #omni: OmniLogic;\n\n constructor(omni: OmniLogic) {\n this.#omni = omni;\n }\n\n list() {\n return this.#omni.config.schedules;\n }\n\n for(equipmentId: number) {\n return this.list().filter((s) => s.equipmentId === equipmentId);\n }\n\n get(scheduleId: number) {\n return this.list().find((s) => s.scheduleSystemId === scheduleId);\n }\n\n async create(spec: ScheduleCreate, options: WriteOptions = {}) {\n const {\n type = \"equipment\",\n startMinute = 0,\n endMinute = 0,\n days: daysActive,\n enabled = true,\n recurring = true,\n ...rest\n } = spec;\n const record = {\n ...rest,\n event: SCHEDULE_TYPE[type],\n startMinute,\n endMinute,\n daysActive,\n enabled: Number(enabled),\n recurring: Number(recurring),\n };\n const before = new Set(this.list().map((s) => s.scheduleSystemId));\n const created = () =>\n this.list().find(\n (s) => !before.has(s.scheduleSystemId) && matches(s, record),\n );\n await this.#omni.command(\"CreateUIScheduleCmd\", record, {\n verify: () => created() !== undefined,\n attempts: options.attempts,\n failure: \"Unable to create the schedule\",\n });\n return created()!;\n }\n\n async update(\n scheduleId: number,\n changes: ScheduleUpdate,\n options: WriteOptions = {},\n ) {\n const current = this.get(scheduleId);\n if (current === undefined) {\n throw new OmniValidationError(\n `No schedule ${scheduleId} in the cached config`,\n );\n }\n const { bowSystemId, equipmentId, scheduleSystemId, ...stored } = current;\n const { type, days, enabled, recurring, ...rest } = changes;\n const next = {\n ...stored,\n ...defined({\n ...rest,\n event: type === undefined ? undefined : SCHEDULE_TYPE[type],\n daysActive: days,\n enabled: enabled === undefined ? undefined : Number(enabled),\n recurring: recurring === undefined ? undefined : Number(recurring),\n }),\n };\n await this.#omni.command(\n \"EditUIScheduleCmd\",\n { scheduleId, ...next },\n {\n verify: () => matches(this.get(scheduleId), next),\n attempts: options.attempts,\n failure: `Unable to update schedule ${scheduleId}`,\n },\n );\n }\n\n async setEnabled(\n scheduleId: number,\n enabled: boolean,\n options: WriteOptions = {},\n ) {\n const flag = Number(enabled);\n await this.#omni.command(\n \"SetUIScheduleEnableCmd\",\n { scheduleId, data: flag },\n {\n verify: () => this.get(scheduleId)?.enabled === flag,\n attempts: options.attempts,\n failure: `Unable to ${enabled ? \"enable\" : \"disable\"} schedule ${scheduleId}`,\n },\n );\n }\n\n async remove(scheduleId: number, options: WriteOptions = {}) {\n if (this.get(scheduleId) === undefined) {\n throw new OmniValidationError(\n `No schedule ${scheduleId} in the cached config`,\n );\n }\n await this.#omni.command(\n \"DeleteUIScheduleCmd\",\n { scheduleId },\n {\n verify: () => this.get(scheduleId) === undefined,\n attempts: options.attempts,\n failure: `Unable to delete schedule ${scheduleId}`,\n },\n );\n }\n}\n","import Builder from \"fast-xml-builder\";\nimport { XMLParser } from \"fast-xml-parser\";\n\nimport type {\n Action,\n Backyard,\n BodyOfWater,\n Chlorinator,\n ChlorinatorEquipment,\n ColorLogicLight,\n CSAD,\n CSADEquipment,\n Device,\n Favorite,\n Filter,\n Heater,\n HeaterEquipment,\n MSPConfig,\n Operation,\n Pump,\n Relay,\n Schedule,\n Sensor,\n Theme,\n ThemeCommand,\n} from \"@/types/config\";\nimport type * as telemetry from \"@/types/telemetry\";\nimport { OmniLogicError, OmniValidationError } from \"@/utils/errors\";\nimport { isRecord } from \"@/utils/helpers\";\n\n// illegal XML 1.0 characters\nconst ILLEGAL =\n /[\\0-\\x08\\x0B\\f\\x0E-\\x1F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nconst legal = (value: string) => {\n const hit = ILLEGAL.exec(value);\n if (hit !== null) {\n throw new OmniValidationError(\n `Invalid character in string: ${value} at index ${hit.index}`,\n );\n }\n return value;\n};\n\nconst checked = (value: unknown) =>\n typeof value === \"string\" ? legal(value) : value;\n\nconst builder = new Builder({\n ignoreAttributes: false,\n attributeNamePrefix: \"@\",\n textNodeName: \"_\",\n suppressEmptyNode: true,\n tagValueProcessor: (_name, value) => checked(value),\n attributeValueProcessor: (_name, value) => checked(value),\n});\n\ntype XMLBody = {\n Request: {\n \"@xmlns\": string;\n Name: string;\n Parameters?: {\n Parameter: {\n \"@name\": string;\n \"@dataType\": DataType;\n _: string;\n }[];\n };\n };\n};\n\nexport type DataType = \"int\" | \"bool\" | \"byte\" | \"float\" | \"string\";\n\nexport type Parameter = {\n name: string;\n dataType: DataType;\n value: string;\n};\n\nexport const buildMessageXml = (name: string, parameters?: Parameter[]) => {\n const body: XMLBody = {\n Request: { \"@xmlns\": \"http://nextgen.hayward.com/api\", Name: name },\n };\n if (parameters && parameters.length > 0) {\n body.Request.Parameters = {\n Parameter: parameters.map(({ name: n, dataType, value }) => ({\n \"@name\": n,\n \"@dataType\": dataType,\n _: value,\n })),\n };\n }\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>${builder.build(body)}`;\n};\n\nconst coerceText = (value: string) => {\n if (value === \"yes\") {\n return true;\n }\n if (value === \"no\") {\n return false;\n }\n const num = parseInt(value, 10);\n return !Number.isNaN(num) && num.toString() === value ? num : value;\n};\n\nconst CONFIG_LISTS = new Set([\n \"action\",\n \"bodyOfWater\",\n \"colorLogicLight\",\n \"component\",\n \"device\",\n \"favorite\",\n \"group\",\n \"operation\",\n \"parameter\",\n \"pump\",\n \"relay\",\n \"request\",\n \"sche\",\n \"sensor\",\n]);\n\nconst TELEMETRY_LISTS = new Set([\n \"bodyOfWater\",\n \"chlorinator\",\n \"colorLogicLight\",\n \"csad\",\n \"filter\",\n \"group\",\n \"heater\",\n \"pump\",\n \"relay\",\n \"smartValveActuator\",\n \"valveActuator\",\n \"virtualHeater\",\n]);\n\nconst toCamelCase = (str: string) =>\n str\n .trim()\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\")\n .replace(/([a-z\\d])([A-Z])/g, \"$1 $2\")\n .split(/[\\s_-]+/)\n .map((word, index) => {\n const lower = word.toLowerCase();\n return index === 0\n ? lower\n : lower.charAt(0).toUpperCase() + lower.slice(1);\n })\n .join(\"\");\n\nconst parser = new XMLParser({\n ignoreAttributes: false,\n ignoreDeclaration: true,\n jPath: true,\n attributeNamePrefix: \"\",\n textNodeName: \"_\",\n parseTagValue: false,\n parseAttributeValue: false,\n transformTagName: toCamelCase,\n transformAttributeName: toCamelCase,\n tagValueProcessor: (tag, value, jPath) =>\n jPath === \"response.parameters.parameter\" ||\n tag === \"name\" ||\n tag === \"deviceName\"\n ? value\n : coerceText(value),\n attributeValueProcessor: (_attr, value) => coerceText(value),\n isArray: (tag, path, _leaf, isAttribute) =>\n !isAttribute &&\n (String(path).startsWith(\"status.\")\n ? TELEMETRY_LISTS.has(tag)\n : CONFIG_LISTS.has(tag)),\n});\n\nexport const parseXML = (xml: string) => parser.parse(xml);\n\ntype ResponseParameter = {\n _: string | number | boolean;\n name: string;\n dataType: DataType;\n};\n\nexport type ResponseMessage = {\n response: {\n xmlns: string;\n name: string;\n parameters: {\n parameter: ResponseParameter[];\n };\n };\n};\n\nexport const coerceParameterValue = (\n dataType: DataType,\n value: string | number | boolean,\n) => {\n const text = String(value);\n switch (dataType) {\n case \"int\":\n case \"byte\": {\n const num = parseInt(text, 10);\n return isNaN(num) ? 0 : num;\n }\n case \"float\": {\n const num = parseFloat(text);\n return isNaN(num) ? 0 : num;\n }\n case \"bool\":\n return text === \"1\";\n default:\n return value;\n }\n};\n\nexport const parametersByName = (parameters: ResponseParameter[]) => {\n return Object.fromEntries(\n parameters.map(({ _, dataType, name }) => {\n return [toCamelCase(name), coerceParameterValue(dataType, _)];\n }),\n );\n};\n\ntype List<T> = T[] | undefined;\n\ntype RawEquipment<T extends { operations: Operation[] }> = Omit<\n T,\n \"operations\"\n> & { operation: List<RawOperation> };\n\ntype RawOperation = {\n action: List<Action>;\n chlorinatorEquipment?: RawEquipment<ChlorinatorEquipment>;\n csadEquipment?: RawEquipment<CSADEquipment>;\n heaterEquipment?: RawEquipment<HeaterEquipment>;\n};\n\ntype RawBodyOfWater = Omit<\n BodyOfWater,\n | \"chlorinator\"\n | \"colorLogicLights\"\n | \"csad\"\n | \"filter\"\n | \"heater\"\n | \"pumps\"\n | \"relays\"\n | \"sensors\"\n> & {\n chlorinator?: RawEquipment<Chlorinator>;\n csad?: RawEquipment<CSAD>;\n colorLogicLight: List<RawEquipment<ColorLogicLight>>;\n filter?: RawEquipment<Filter>;\n heater?: RawEquipment<Heater>;\n pump: List<RawEquipment<Pump>>;\n relay: List<RawEquipment<Relay>>;\n sensor: List<RawEquipment<Sensor>>;\n};\n\ntype RawParameter = Omit<ThemeCommand[\"parameters\"][number], \"value\"> & {\n _: number | string;\n};\n\ntype RawThemeCommand = Omit<ThemeCommand, \"parameters\"> & {\n parameters?: { parameter: List<RawParameter> } | string;\n};\n\ntype RawTheme = Omit<Theme, \"commands\"> & { request: List<RawThemeCommand> };\n\ntype RawDevice = Omit<Device, \"devices\"> & {\n devices: { device: List<RawDevice> } | string;\n};\n\ntype RawConfig = {\n mspConfig: Omit<\n MSPConfig,\n \"backyard\" | \"devices\" | \"favorites\" | \"themes\" | \"schedules\"\n > & {\n backyard: Omit<\n Backyard,\n \"bodiesOfWater\" | \"colorLogicLights\" | \"relays\" | \"sensors\"\n > & {\n bodyOfWater: List<RawBodyOfWater>;\n colorLogicLight: List<RawEquipment<ColorLogicLight>>;\n relay: List<RawEquipment<Relay>>;\n sensor: List<RawEquipment<Sensor>>;\n };\n dmt: { device: List<RawDevice> } | string;\n favorites: { favorite: List<Favorite> } | string;\n groups: { group: List<RawTheme> } | string;\n schedules: { sche: List<Schedule> } | string;\n };\n};\n\nconst operations = (raw: List<RawOperation>): Operation[] =>\n (raw ?? []).map(\n ({ action, chlorinatorEquipment, csadEquipment, heaterEquipment }) => ({\n actions: action ?? [],\n ...(chlorinatorEquipment && {\n chlorinatorEquipment: withOperations(chlorinatorEquipment),\n }),\n ...(csadEquipment && {\n csadEquipment: withOperations(csadEquipment),\n }),\n ...(heaterEquipment && {\n heaterEquipment: withOperations(heaterEquipment),\n }),\n }),\n );\n\nconst withOperations = <T extends { operations: Operation[] }>({\n operation,\n ...rest\n}: RawEquipment<T>) => ({ ...rest, operations: operations(operation) });\n\nconst devices = (raw: List<RawDevice>): Device[] =>\n (raw ?? []).map(({ devices: children, ...rest }) => ({\n ...rest,\n devices: devices(isRecord(children) ? children.device : undefined),\n }));\n\nconst bodyOfWater = ({\n chlorinator,\n colorLogicLight,\n csad,\n filter,\n heater,\n pump,\n relay,\n sensor,\n ...rest\n}: RawBodyOfWater) => ({\n ...rest,\n ...(chlorinator && { chlorinator: withOperations(chlorinator) }),\n colorLogicLights: (colorLogicLight ?? []).map(withOperations),\n ...(csad && { csad: withOperations(csad) }),\n ...(filter && { filter: withOperations(filter) }),\n ...(heater && { heater: withOperations(heater) }),\n pumps: (pump ?? []).map(withOperations),\n relays: (relay ?? []).map(withOperations),\n sensors: (sensor ?? []).map(withOperations),\n});\n\nconst section = <T>(\n wrapper: { [k: string]: List<T> } | string | undefined,\n tag: string,\n) => (isRecord(wrapper) ? (wrapper[tag] ?? []) : []);\n\nconst theme = ({ request, ...rest }: RawTheme) => ({\n ...rest,\n commands: (request ?? []).map(({ parameters, ...command }) => ({\n ...command,\n parameters: section(parameters, \"parameter\").map(({ _, ...parameter }) => ({\n ...parameter,\n value: _,\n })),\n })),\n});\n\nexport const parseConfig = (xml: string) => {\n const raw: RawConfig = parseXML(xml);\n if (!isRecord(raw.mspConfig)) {\n throw new OmniLogicError(\"Malformed reply: no <MSPConfig> element\");\n }\n const {\n backyard: {\n bodyOfWater: bodies,\n colorLogicLight,\n relay,\n sensor,\n ...backyard\n },\n dmt,\n favorites,\n groups,\n schedules,\n ...rest\n } = raw.mspConfig;\n return {\n ...rest,\n backyard: {\n ...backyard,\n bodiesOfWater: (bodies ?? []).map(bodyOfWater),\n colorLogicLights: (colorLogicLight ?? []).map(withOperations),\n relays: (relay ?? []).map(withOperations),\n sensors: (sensor ?? []).map(withOperations),\n },\n devices: devices(section(dmt, \"device\")),\n favorites: section(favorites, \"favorite\"),\n themes: section(groups, \"group\").map(theme),\n schedules: section(schedules, \"sche\"),\n };\n};\n\ntype RawTelemetry = {\n version: string;\n backyard: telemetry.Backyard;\n bodyOfWater: List<telemetry.BodyOfWater>;\n chlorinator: List<telemetry.Chlorinator>;\n colorLogicLight: List<telemetry.ColorLogicLight>;\n csad: List<telemetry.CSAD>;\n filter: List<telemetry.Filter>;\n group: List<telemetry.Theme>;\n heater: List<telemetry.Heater>;\n pump: List<telemetry.Pump>;\n relay: List<telemetry.Relay>;\n smartValveActuator: List<telemetry.SmartValveActuator>;\n valveActuator: List<telemetry.ValveActuator>;\n virtualHeater: List<telemetry.VirtualHeater>;\n};\n\nexport const parseTelemetry = (xml: string) => {\n const raw: { status: RawTelemetry } = parseXML(xml);\n const t = raw.status;\n if (!isRecord(t)) {\n throw new OmniLogicError(\"Malformed reply: no <STATUS> element\");\n }\n return {\n version: t.version,\n backyard: t.backyard,\n bodiesOfWater: t.bodyOfWater ?? [],\n chlorinators: t.chlorinator ?? [],\n colorLogicLights: t.colorLogicLight ?? [],\n csads: t.csad ?? [],\n filters: t.filter ?? [],\n themes: t.group ?? [],\n heaters: t.heater ?? [],\n pumps: t.pump ?? [],\n relays: t.relay ?? [],\n smartValveActuators: t.smartValveActuator ?? [],\n valveActuators: t.valveActuator ?? [],\n virtualHeaters: t.virtualHeater ?? [],\n };\n};\n\ntype RawComponent = { parameter?: ResponseParameter[] };\ntype RawSysInfo = {\n sysInfo?: { parameter?: ResponseParameter[]; component?: RawComponent[] };\n};\n\nexport const parseSysInfo = (xml: string) => {\n const raw: RawSysInfo = parseXML(xml);\n const root = raw.sysInfo;\n if (!isRecord(root)) {\n throw new OmniLogicError(\"Malformed reply: no <SysInfo> element\");\n }\n const top = parametersByName(root.parameter ?? []);\n const components = (root.component ?? []).map((c) => {\n const p = parametersByName(c.parameter ?? []);\n return {\n devName: String(p.devName ?? \"\"),\n type: String(p.type ?? \"\"),\n hua: String(p.hua ?? \"\"),\n version: String(p.version ?? \"\"),\n nodeId: Number(p.nodeId),\n systemId: Number(p.systemId),\n upgradeCapable: p.upgradeCapable === 1,\n };\n });\n return { numComponents: Number(top.numComponents), components };\n};\n","import {\n COMMANDS,\n type CommandName,\n type CommandRequestParam,\n type CommandResponseSpec,\n} from \"@/client/spec\";\nimport { SCHEDULE_EVERY_DAY } from \"@/equipment/schedules\";\nimport { OmniValidationError } from \"@/utils/errors\";\nimport {\n buildMessageXml,\n coerceParameterValue,\n parseXML,\n type ResponseMessage,\n} from \"@/utils/xml\";\n\nconst validateParam = (\n command: CommandName,\n param: CommandRequestParam,\n index: number,\n value: number | string | undefined,\n) => {\n if (param.type === \"string\") {\n if (typeof value !== \"string\") {\n throw new OmniValidationError(\n `${command}: missing or non-string parameter \"${param.name}\" (position ${index})`,\n );\n }\n if (param.values && !param.values.includes(value)) {\n throw new OmniValidationError(\n `${command}: parameter \"${param.name}\" must be one of ` +\n `${param.values.map((v) => JSON.stringify(v)).join(\", \")}, got ` +\n JSON.stringify(value),\n );\n }\n const bytes = Buffer.byteLength(value, \"utf8\");\n if (bytes > param.maxLength) {\n throw new OmniValidationError(\n `${command}: parameter \"${param.name}\" is ${bytes} bytes, ` +\n `longer than the ${param.maxLength} the controller keeps`,\n );\n }\n return value;\n }\n\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new OmniValidationError(\n `${command}: missing or non-numeric parameter \"${param.name}\" (position ${index})`,\n );\n }\n if (param.type !== \"float\") {\n if (!Number.isInteger(value)) {\n throw new OmniValidationError(\n `${command}: parameter \"${param.name}\" must be an integer, got ${value}`,\n );\n }\n // a byte is unsigned, an int a signed 32-bit\n const [min, max] =\n param.type === \"byte\" ? [0, 255] : [-2147483648, 2147483647];\n if (value < min || value > max) {\n throw new OmniValidationError(\n `${command}: parameter \"${param.name}\" must be between ${min} and ${max}, got ${value}`,\n );\n }\n }\n return value;\n};\n\nexport const buildCommandXml = (\n name: CommandName,\n params: Record<string, number | string>,\n) => {\n const request = COMMANDS[name].request;\n const known = new Set(request.map((p) => p.name));\n const xml = buildMessageXml(\n name,\n request.map((p, index) => ({\n name: p.name,\n dataType: p.type,\n value: String(validateParam(name, p, index, params[p.name])),\n })),\n );\n return {\n xml,\n unknown: Object.keys(params).filter((k) => !known.has(k)),\n };\n};\n\n// matched in order, not by name\nexport const parseCommandResponse = (\n responseSpec: CommandResponseSpec,\n xml: string,\n) => {\n const parsed: ResponseMessage = parseXML(xml);\n const parameters = parsed.response?.parameters?.parameter ?? [];\n if (parameters.length !== responseSpec.parameters.length) {\n return {\n ok: false,\n actual: parameters.length,\n expected: responseSpec.parameters.length,\n };\n }\n\n const out: Record<string, number | boolean | string> = {};\n responseSpec.parameters.forEach((p, index) => {\n out[p.name] = coerceParameterValue(p.dataType, parameters[index]?._ ?? \"\");\n });\n return { ok: true, params: out };\n};\n\nexport type TimerOptions = {\n isCountdownTimer?: boolean;\n startTimeHours?: number;\n startTimeMinutes?: number;\n endTimeHours?: number;\n endTimeMinutes?: number;\n daysActive?: number;\n recurring?: boolean;\n};\n\nexport const timerParams = (t: TimerOptions = {}) => ({\n // spelled the firmware's way\n isCountDownTimer: Number(t.isCountdownTimer ?? false),\n startTimeHours: t.startTimeHours ?? 0,\n startTimeMinutes: t.startTimeMinutes ?? 0,\n endTimeHours: t.endTimeHours ?? 0,\n endTimeMinutes: t.endTimeMinutes ?? 0,\n daysActive: t.daysActive ?? 0,\n recurring: Number(t.recurring ?? false),\n});\n\nexport const countdownParams = (minutes: number) =>\n timerParams({\n isCountdownTimer: true,\n endTimeHours: Math.floor(minutes / 60),\n endTimeMinutes: minutes % 60,\n daysActive: SCHEDULE_EVERY_DAY,\n });\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { PUMP_STATE, PUMP_WHY_ON } from \"@/constants/labels\";\nimport { Device } from \"@/equipment/device\";\nimport { timerParams } from \"@/utils/command\";\n\ntype PumpConfig = {\n systemId: number;\n name: string;\n type: string;\n function?: string;\n};\n\nexport class Pump extends Device {\n #type: string;\n #function: string | undefined;\n\n constructor(omni: OmniLogic, poolId: number, config: PumpConfig) {\n super(omni, poolId, config.systemId, config.name);\n this.#type = config.type;\n this.#function = config.function;\n }\n\n // the speeds it can run, e.g. PMP_VARIABLE_SPEED_PUMP\n get type() {\n return this.#type;\n }\n\n // what it drives, absent on the filter pump\n get function() {\n return this.#function;\n }\n\n get #rows() {\n const t = this.omni.telemetry;\n return [...t.pumps, ...t.filters];\n }\n\n get state() {\n return this.telemetry(this.#rows);\n }\n\n get reported() {\n return this.reportedIn(this.#rows);\n }\n\n get states() {\n return PUMP_STATE;\n }\n\n get reasons() {\n return PUMP_WHY_ON;\n }\n\n get countdownReason() {\n return 9;\n }\n\n get #reading() {\n const row = this.state;\n return \"pumpState\" in row\n ? { speed: row.pumpSpeed, position: row.pumpState, whyOn: row.whyOn }\n : {\n speed: row.filterSpeed,\n position: row.filterState,\n whyOn: row.whyFilterIsOn,\n };\n }\n\n get speed() {\n return this.reported ? this.#reading.speed : 0;\n }\n\n get isOn() {\n return this.reported && this.#reading.position !== 0;\n }\n\n get isRunning() {\n return this.speed > 0;\n }\n\n get lastSpeed() {\n return (\n this.#rows.find((r) => r.systemId === this.equipmentId)?.lastSpeed ?? 0\n );\n }\n\n get status() {\n const position = this.reported ? this.#reading.position : 0;\n return this.states[position] ?? \"Unknown\";\n }\n\n get whyOn() {\n const code = this.reported ? this.#reading.whyOn : 0;\n return this.reasons[code] ?? \"Unknown\";\n }\n\n get onCountdown() {\n return this.reported && this.#reading.whyOn === this.countdownReason;\n }\n\n // set the pump speed, 0 for off\n setSpeed(value: number) {\n return this.omni.command(\"SetUIEquipmentCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n isOn: value,\n ...timerParams(),\n });\n }\n}\n","import type { OmniLogic, ReadOptions } from \"@/client/omnilogic\";\nimport {\n FILTER_STATE,\n FILTER_VALVE_POSITION,\n FILTER_WHY_ON,\n} from \"@/constants/labels\";\nimport { Pump } from \"@/equipment/pump\";\nimport type { Filter as FilterConfig } from \"@/types/config\";\nimport { bcdWatts, displayRevision, driveRevision, word } from \"@/utils/decode\";\n\nconst ascii = (bytes: number[]) =>\n String.fromCharCode(...bytes).replace(/[\\0 ]+$/, \"\");\n\nexport type FilterDiagnostics = {\n // watts, or the BCD word with { raw: true }\n power: number;\n errorStatus: number;\n // as the panel shows it, or the six bytes as text with { raw: true }\n displayRevision: string;\n driveRevision: string;\n};\n\n// the pump that drives the filter\nexport class Filter extends Pump {\n constructor(omni: OmniLogic, poolId: number, config: FilterConfig) {\n super(omni, poolId, {\n systemId: config.systemId,\n name: config.name,\n type: config.filterType,\n });\n }\n\n get #config() {\n return this.configured(this.bodyConfig?.filter);\n }\n\n get states() {\n return FILTER_STATE;\n }\n\n get reasons() {\n return FILTER_WHY_ON;\n }\n\n get countdownReason() {\n return 10;\n }\n\n get state() {\n return this.telemetry(this.omni.telemetry.filters);\n }\n\n // which way the valves are set, e.g. \"Pool Only\", \"Spillover\"\n get valvePosition() {\n const position = this.reported ? this.state.valvePosition : -1;\n return FILTER_VALVE_POSITION[position] ?? \"Unknown\";\n }\n\n // the speed the pump reports back, lagging the speed it was told\n get reportedSpeed() {\n return this.reported ? this.state.reportedFilterSpeed : 0;\n }\n\n get isPriming() {\n const state = this.reported ? this.state.filterState : 0;\n return state === 2 || state === 10; // Priming or Force Priming\n }\n\n // watts\n get power() {\n return this.reported ? this.state.power : 0;\n }\n\n async diagnostics(options: ReadOptions = {}): Promise<FilterDiagnostics> {\n const r = await this.omni.command(\"GetUIFilterDiagnosticInfo\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n });\n const display = [\n r.displayFwRevisionB1,\n r.displayFwRevisionB2,\n r.displayFwRevisionB3,\n r.displayFwRevisionB4,\n r.displayFwRevisionB5,\n r.displayFwRevisionB6,\n ];\n const drive = [\n r.driveFwRevisionB1,\n r.driveFwRevisionB2,\n r.driveFwRevisionB3,\n r.driveFwRevisionB4,\n r.driveFwRevisionB5,\n r.driveFwRevisionB6,\n ];\n const errorStatus = r.errorStatus;\n if (options.raw) {\n return {\n power: word(r.powerMsb, r.powerLsb),\n errorStatus,\n displayRevision: ascii(display),\n driveRevision: ascii(drive),\n };\n }\n return {\n power: bcdWatts(r.powerMsb, r.powerLsb),\n errorStatus,\n displayRevision: displayRevision(display),\n driveRevision: driveRevision(drive),\n };\n }\n\n get minSpeed() {\n return this.#config.minPumpSpeed;\n }\n\n setMinSpeed(value: number) {\n return this.omni.command(\"SetFilterLowSpeed\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: value,\n });\n }\n\n get maxSpeed() {\n return this.#config.maxPumpSpeed;\n }\n\n setMaxSpeed(value: number) {\n return this.omni.command(\"SetFilterHighSpeed\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: value,\n });\n }\n\n // the speed the Low preset runs\n get lowSpeed() {\n return this.#config.vspLowPumpSpeed;\n }\n\n // the speed the Medium preset runs\n get mediumSpeed() {\n return this.#config.vspMediumPumpSpeed;\n }\n\n // the speed the High preset runs\n get highSpeed() {\n return this.#config.vspHighPumpSpeed;\n }\n\n get primingDuration() {\n return this.#config.primingDuration;\n }\n\n setPrimingDuration(seconds: number) {\n return this.omni.command(\"SetPrimingDuration\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: seconds,\n });\n }\n\n get cooldownDuration() {\n return this.#config.cooldownDuration;\n }\n\n setCooldownDuration(seconds: number) {\n return this.omni.command(\"SetCooldownDuration\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: seconds,\n });\n }\n\n get sharedFilterTimeout() {\n return this.#config.sharedFilterTimeout;\n }\n\n setSharedFilterTimeout(seconds: number) {\n return this.omni.command(\"SetSharedFilterTimeout\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: seconds,\n });\n }\n\n get freezeProtectOverrideInterval() {\n return this.#config.freezeProtectOverrideInterval;\n }\n\n setFreezeProtectOverrideInterval(seconds: number) {\n return this.omni.command(\"SetUIFreezeProtectOverrideInterval\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: seconds,\n });\n }\n\n get freezeProtect() {\n return this.#config.freezeProtectEnable;\n }\n\n setFreezeProtect(on: boolean) {\n return this.omni.command(\"SetFreezeProtect\", {\n poolId: this.poolId,\n data: Number(on),\n });\n }\n\n get freezeProtectTemp() {\n return this.#config.freezeProtectTemp;\n }\n\n setFreezeProtectTemp(degrees: number) {\n return this.omni.command(\"SetFreezeProtectTemp\", {\n poolId: this.poolId,\n data: degrees,\n });\n }\n\n get freezeProtectSpeed() {\n return this.#config.freezeProtectSpeed;\n }\n\n setFreezeProtectSpeed(value: number) {\n return this.omni.command(\"SetFreezeProtectSpeed\", {\n poolId: this.poolId,\n data: value,\n });\n }\n\n get offDuringValveChange() {\n return this.#config.valveChangeOffEnable;\n }\n\n setOffDuringValveChange(on: boolean) {\n return this.omni.command(\"SetFilterOffValveChg\", {\n poolId: this.poolId,\n data: Number(on),\n });\n }\n\n get flowMonitor() {\n return this.#config.noWaterFlowTimeoutEnable;\n }\n\n setFlowMonitor(on: boolean) {\n return this.omni.command(\"SetFlowMonitor\", {\n poolId: this.poolId,\n data: Number(on),\n });\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { HEATER_PRIORITY, HEATER_STATE } from \"@/constants/labels\";\nimport { HEATER_TEMP_UNAVAILABLE } from \"@/constants/sentinels\";\nimport { Device } from \"@/equipment/device\";\nimport type { HeaterEquipment } from \"@/types/config\";\nimport { OmniValidationError } from \"@/utils/errors\";\n\n// the priority that puts a solar loop ahead of every other source\nconst SOLAR_FIRST = 254;\n\n// one heat source under a body's thermostat\nexport class HeaterAppliance extends Device {\n constructor(omni: OmniLogic, poolId: number, config: HeaterEquipment) {\n super(omni, poolId, config.systemId, config.name);\n }\n\n get #config() {\n return this.configured(\n this.bodyConfig?.heater?.operations\n .flatMap((o) => o.heaterEquipment ?? [])\n .find((e) => e.systemId === this.equipmentId),\n );\n }\n\n // HTR_GAS, HTR_SOLAR, HTR_HEAT_PUMP…\n get type() {\n return this.#config.heaterType;\n }\n\n // the other body's record for the same unit, -1 when it is not shared\n get sharedWith() {\n return this.#config.sharedEquipmentSystemId;\n }\n\n get state() {\n return this.telemetry(this.omni.telemetry.heaters);\n }\n\n get #reported() {\n return this.reportedIn(this.omni.telemetry.heaters);\n }\n\n get #runningState() {\n this.requireRunning();\n return this.state;\n }\n\n get status() {\n return this.#reported\n ? (HEATER_STATE[this.state.heaterState] ?? \"Unknown\")\n : \"Off\";\n }\n\n get isOn() {\n return this.#reported && this.state.heaterState === 1;\n }\n\n get temp() {\n if (!this.#reported) {\n return undefined;\n }\n const temp = this.state.temp;\n return temp === HEATER_TEMP_UNAVAILABLE ? undefined : temp;\n }\n\n get supportsCooling() {\n return this.#config.supportsCooling;\n }\n\n // the slowest the filter pump may run while this one heats\n get lowSpeed() {\n return this.#config.minSpeedForOperation;\n }\n\n setLowSpeed(value: number) {\n return this.omni.command(\"SetHeaterLowSpeed\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: value,\n });\n }\n\n // whether the filter pump may run slow while this one heats\n get allowLowSpeed() {\n return this.#config.allowLowSpeedOperation;\n }\n\n setAllowLowSpeed(on: boolean) {\n return this.omni.command(\"SetHeaterAllowedLowSpeed\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n get enabled() {\n return this.#runningState.enable !== 0;\n }\n\n setEnabled(on: boolean) {\n return this.omni.command(\"SetHeaterEnable\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n // its rank against the body's other heat sources\n get priority() {\n return HEATER_PRIORITY[this.#runningState.priority] ?? \"Unknown\";\n }\n\n setPriority(rank: number) {\n if (HEATER_PRIORITY[rank] === undefined) {\n throw new OmniValidationError(\n `Heater priority ${rank} is not one of ${Object.keys(HEATER_PRIORITY).join(\", \")}`,\n );\n }\n if (rank === SOLAR_FIRST && this.type !== \"HTR_SOLAR\") {\n throw new OmniValidationError(\n `Only a solar loop takes priority ${SOLAR_FIRST}; \"${this.name}\" is ${this.type}`,\n );\n }\n return this.omni.command(\"SetUIHeaterPriorityCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: rank,\n });\n }\n\n // hours this source keeps priority, 0 shares it, 24 keeps it while it can run\n get maintainFor() {\n return this.#runningState.maintainFor;\n }\n}\n","import { HEATER_MODE } from \"@/constants/labels\";\nimport { Device } from \"@/equipment/device\";\nimport { HeaterAppliance } from \"@/equipment/heaterAppliance\";\nimport { OmniLogicError, OmniValidationError } from \"@/utils/errors\";\n\n// Heat, Cool and Auto\nconst VALID_MODES = [0, 1, 2];\n\n// the body's thermostat\nexport class Heater extends Device {\n get state() {\n return this.telemetry(this.omni.telemetry.virtualHeaters);\n }\n\n get #runningState() {\n this.requireRunning();\n return this.state;\n }\n\n get #config() {\n return this.configured(this.bodyConfig?.heater);\n }\n\n // every heat source this body can call on, in the controller's order\n get appliances() {\n return this.#config.operations\n .flatMap((o) => o.heaterEquipment ?? [])\n .map((e) => new HeaterAppliance(this.omni, this.poolId, e));\n }\n\n // what the first heat source is doing\n get applianceState() {\n return this.appliances[0]?.status ?? \"Off\";\n }\n\n get setPoint() {\n return this.#runningState.currentSetPoint;\n }\n\n // every controller reports one, fitted with solar or not\n get solarSetPoint() {\n return this.#runningState.solarSetPoint;\n }\n\n // the lowest set point the panel accepts\n get minSetPoint() {\n return this.#config.minSettableWaterTemp;\n }\n\n // the highest set point the panel accepts\n get maxSetPoint() {\n return this.#config.maxSettableWaterTemp;\n }\n\n setSetPoint(degrees: number) {\n const { minSetPoint: min, maxSetPoint: max } = this;\n if (degrees < min || degrees > max) {\n throw new OmniValidationError(\n `Set point ${degrees} is not between ${min} and ${max}`,\n );\n }\n return this.omni.command(\"SetUIHeaterCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: degrees,\n });\n }\n\n get enabled() {\n return this.#runningState.enable !== 0;\n }\n\n setEnabled(on: boolean) {\n return this.omni.command(\"SetHeaterEnable\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n get mode() {\n return HEATER_MODE[this.#runningState.mode] ?? \"Unknown\";\n }\n\n setMode(mode: number) {\n if (!VALID_MODES.includes(mode)) {\n throw new OmniValidationError(\n `Heater mode ${mode} is not one of ${VALID_MODES.map((code) => `${code} (${HEATER_MODE[code]})`).join(\", \")}`,\n );\n }\n return this.omni.command(\"SetUIHeaterModeCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: mode,\n });\n }\n\n get silentMode() {\n return this.#runningState.silentMode !== 0;\n }\n\n setSilentMode(on: boolean) {\n return this.omni.command(\"SetHeaterSilentMode\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n get cooldown() {\n return this.#config.cooldownEnabled;\n }\n\n setCooldown(on: boolean) {\n return this.omni.command(\"SetHeaterCoolDown\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n get extend() {\n return this.#config.extendEnabled;\n }\n\n setExtend(on: boolean) {\n return this.omni.command(\"SetHeaterExtend\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: Number(on),\n });\n }\n\n async autoDifferential() {\n const r = await this.omni.command(\"GetHeaterAutoDifferential\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n });\n return r.data;\n }\n\n setAutoDifferential(degrees: number) {\n return this.omni.command(\"SetHeaterAutoDifferential\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n data: degrees,\n });\n }\n\n #first() {\n const first = this.appliances[0];\n if (first === undefined) {\n throw new OmniLogicError(`No heat source configured for \"${this.name}\"`);\n }\n return first;\n }\n\n get allowLowSpeed() {\n return this.#first().allowLowSpeed;\n }\n\n setAllowLowSpeed(on: boolean) {\n return this.#first().setAllowLowSpeed(on);\n }\n\n get lowSpeed() {\n return this.#first().lowSpeed;\n }\n\n setLowSpeed(value: number) {\n return this.#first().setLowSpeed(value);\n }\n}\n","// the Universal ColorLogic (UCL) show table: base 0–16, V2 tail 17–27\nexport const ColorLogicShow = {\n VOODOO_LOUNGE: 0,\n DEEP_BLUE_SEA: 1,\n ROYAL_BLUE: 2,\n AFTERNOON_SKY: 3,\n AQUA_GREEN: 4,\n EMERALD: 5,\n CLOUD_WHITE: 6,\n WARM_RED: 7,\n FLAMINGO: 8,\n VIVID_VIOLET: 9,\n SANGRIA: 10,\n TWILIGHT: 11,\n TRANQUILITY: 12,\n GEMSTONE: 13,\n USA: 14,\n MARDI_GRAS: 15,\n COOL_CABARET: 16,\n YELLOW: 17,\n ORANGE: 18,\n GOLD: 19,\n MINT: 20,\n TEAL: 21,\n BURNT_ORANGE: 22,\n PURE_WHITE: 23,\n CRISP_WHITE: 24,\n WARM_WHITE: 25,\n BRIGHT_YELLOW: 26,\n WATERFIRE: 27,\n} as const;\n\nexport const ColorLogicPowerState = {\n OFF: 0,\n POWERING_OFF: 1,\n RESETTING: 2,\n CHANGING_SHOW: 3,\n FIFTEEN_SECONDS_WHITE: 4,\n ACTIVE: 6,\n COOLDOWN: 7,\n} as const;\n\nexport const powerStateName = (code: number | undefined) =>\n Object.entries(ColorLogicPowerState).find(([, v]) => v === code)?.[0] ??\n `#${String(code)}`;\n\n// lit or warming up, with on its way off counting as off\nexport const isLightLit = (state: number) =>\n state === ColorLogicPowerState.CHANGING_SHOW ||\n state === ColorLogicPowerState.FIFTEEN_SECONDS_WHITE ||\n state === ColorLogicPowerState.ACTIVE;\n\ntype ShowEntry = [number, string];\n\n// ColorLogic 2.5 and ColorLogic 4.0\nconst SHOWS_25_40: ShowEntry[] = [\n [0, \"VOODOO_LOUNGE\"],\n [1, \"DEEP_BLUE_SEA\"],\n [2, \"AFTERNOON_SKY\"],\n [3, \"EMERALD\"],\n [4, \"SANGRIA\"],\n [5, \"CLOUD_WHITE\"],\n [6, \"TWILIGHT\"],\n [7, \"TRANQUILITY\"],\n [8, \"GEMSTONE\"],\n [9, \"USA\"],\n [10, \"MARDI_GRAS\"],\n [11, \"COOL_CABARET\"],\n];\n\nconst SHOWS_UCL_V2: ShowEntry[] = Object.entries(ColorLogicShow).map(\n ([name, value]) => [value, name],\n);\nconst SHOWS_UCL: ShowEntry[] = SHOWS_UCL_V2.filter(([value]) => value <= 16);\n\n// Pentair Color LED (P-COLOR)\nconst SHOWS_PENTAIR: ShowEntry[] = [\n [0, \"SAM\"],\n [1, \"PARTY\"],\n [2, \"ROMANCE\"],\n [3, \"CARIBBEAN\"],\n [4, \"AMERICAN\"],\n [5, \"CALIFORNIA_SUNSET\"],\n [6, \"ROYAL\"],\n [7, \"BLUE\"],\n [8, \"GREEN\"],\n [9, \"RED\"],\n [10, \"WHITE\"],\n [11, \"MAGENTA\"],\n];\n\n// Jandy Color LED (Z-Color)\nconst SHOWS_ZODIAC: ShowEntry[] = [\n [0, \"ALPINE_WHITE\"],\n [1, \"SKY_BLUE\"],\n [2, \"COBALT_BLUE\"],\n [3, \"CARIBBEAN_BLUE\"],\n [4, \"SPRING_GREEN\"],\n [5, \"EMERALD_GREEN\"],\n [6, \"EMERALD_ROSE\"],\n [7, \"MAGENTA\"],\n [8, \"VIOLET\"],\n [9, \"SLOW_COLOR_SPLASH\"],\n [10, \"FAST_COLOR_SPLASH\"],\n [11, \"AMERICA_THE_BEAUTIFUL\"],\n [12, \"FAT_TUESDAY\"],\n [13, \"DISCO_TECH\"],\n];\n\nexport type LightShowInfo = {\n value: number;\n name: string;\n};\n\nexport const getAvailableShows = (\n lightType: string,\n v2Active: boolean = false,\n) => {\n let entries: ShowEntry[];\n switch (lightType) {\n case \"COLOR_LOGIC_2_5\":\n case \"COLOR_LOGIC_4_0\":\n entries = SHOWS_25_40;\n break;\n case \"COLOR_LOGIC_UCL\":\n case \"COLOR_LOGIC_SAM\":\n entries = v2Active ? SHOWS_UCL_V2 : SHOWS_UCL;\n break;\n case \"CL_P_COLOR\":\n entries = SHOWS_PENTAIR;\n break;\n case \"CL_Z_COLOR\":\n entries = SHOWS_ZODIAC;\n break;\n default:\n entries = SHOWS_UCL;\n break;\n }\n return entries.map(([value, name]) => ({ value, name }));\n};\n","type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"off\";\n\ntype EmittedLevel = Exclude<LogLevel, \"off\">;\n\ntype LogFields = Record<string, unknown>;\n\ntype Logger = Record<\n EmittedLevel,\n (message: string, fields?: LogFields) => void\n>;\n\nconst LOG_RANK: Record<LogLevel, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n off: 100,\n};\n\nconst DEFAULT_LEVEL: LogLevel = \"warn\";\n\nconst isLogLevel = (value: unknown): value is LogLevel =>\n typeof value === \"string\" && Object.hasOwn(LOG_RANK, value);\n\nconst currentLevel = () => {\n const level = process.env.LOG_LEVEL;\n return isLogLevel(level) ? level : DEFAULT_LEVEL;\n};\n\nexport const createLogger = (namespace: string): Logger => {\n const emit = (level: EmittedLevel, message: string, fields?: LogFields) => {\n if (LOG_RANK[level] < LOG_RANK[currentLevel()]) {\n return;\n }\n\n const errors: Error[] = [];\n let tail = \"\";\n for (const [key, value] of Object.entries(fields ?? {})) {\n if (value instanceof Error) {\n errors.push(value);\n } else {\n tail += ` ${key}=${String(value)}`;\n }\n }\n console.error(\n `${level.padEnd(5)} [${namespace}] ${message}${tail}`,\n ...errors,\n );\n };\n\n return {\n trace: (message, fields) => emit(\"trace\", message, fields),\n debug: (message, fields) => emit(\"debug\", message, fields),\n info: (message, fields) => emit(\"info\", message, fields),\n warn: (message, fields) => emit(\"warn\", message, fields),\n error: (message, fields) => emit(\"error\", message, fields),\n };\n};\n","import { setTimeout } from \"node:timers/promises\";\n\nimport type { CommandOptions } from \"@/client/omnilogic\";\nimport { LIGHT_BRIGHTNESS, LIGHT_SPEED } from \"@/constants/labels\";\nimport {\n ColorLogicPowerState,\n getAvailableShows,\n isLightLit,\n powerStateName,\n} from \"@/constants/lightShows\";\nimport { Device } from \"@/equipment/device\";\nimport { timerParams } from \"@/utils/command\";\nimport {\n OmniLogicError,\n OmniTimeoutError,\n OmniValidationError,\n ReadingUnavailableError,\n} from \"@/utils/errors\";\nimport { findBySystemId, stringOf } from \"@/utils/helpers\";\nimport { createLogger } from \"@/utils/logger\";\n\nconst equipmentLog = createLogger(\"equipment\");\n\nexport type LightWriteOptions = Pick<\n CommandOptions,\n \"attempts\" | \"force\" | \"pollMs\" | \"timeoutMs\"\n> & {\n // \"1/16x\" to \"16x\", default the current speed\n speed?: string;\n // 20 to 100 in steps of 20, default the current brightness\n brightness?: number;\n // default true, false throws on a light mid-transition instead of waiting\n wait?: boolean;\n};\n\nconst encodeShow = (show: number, speed: string, brightness: number) => {\n const speedCode = Object.entries(LIGHT_SPEED).find(\n ([, label]) => label === speed,\n )?.[0];\n if (speedCode === undefined) {\n throw new OmniValidationError(\n `light speed \"${speed}\" is not one of ${Object.values(LIGHT_SPEED).join(\", \")}`,\n );\n }\n const brightnessCode = Object.entries(LIGHT_BRIGHTNESS).find(\n ([, percent]) => percent === brightness,\n )?.[0];\n if (brightnessCode === undefined) {\n throw new OmniValidationError(\n `light brightness ${brightness} is not one of ${Object.values(LIGHT_BRIGHTNESS).join(\", \")}`,\n );\n }\n return {\n data: show,\n field19: Number(speedCode),\n field1a: Number(brightnessCode),\n field1b: 0,\n };\n};\n\n// the wait between telemetry reads\nconst DEFAULT_POLL_MS = 4000;\n// a show change registers within this after the send\nconst DEFAULT_VERIFY_MS = 30000;\n// a light reaches OFF or ACTIVE within this\nconst SETTLE_MS = 60000;\n\nconst verifyOptions = (\n options: LightWriteOptions,\n verify: () => boolean,\n failure: string,\n) => ({\n verify,\n timeoutMs: options.timeoutMs ?? DEFAULT_VERIFY_MS,\n pollMs: options.pollMs ?? DEFAULT_POLL_MS,\n attempts: options.attempts,\n force: options.force,\n failure,\n});\n\nexport class Light extends Device {\n // undefined when telemetry has no row for this light\n get state() {\n return this.omni.telemetry.colorLogicLights.find(\n (l) => l.systemId === this.equipmentId,\n );\n }\n\n get #reported() {\n return this.running ? this.state : undefined;\n }\n\n get #config() {\n const light = findBySystemId(this.omni.config, this.equipmentId);\n return {\n type: stringOf(light?.type) ?? \"\",\n v2Active: light?.v2Active === true,\n };\n }\n\n get omniDirect() {\n return this.#config.v2Active;\n }\n\n get shows() {\n const { type, v2Active } = this.#config;\n return getAvailableShows(type, v2Active);\n }\n\n #readOr<T>(read: () => T | undefined, fallback: T) {\n try {\n const value = read();\n return value === undefined || value === \"Unknown\" ? fallback : value;\n } catch (error) {\n if (error instanceof ReadingUnavailableError) {\n return fallback;\n }\n throw error;\n }\n }\n\n get powerState() {\n const row = this.#reported;\n return row === undefined ? \"OFF\" : powerStateName(row.lightState);\n }\n\n get show() {\n this.requireRunning();\n const current = this.state?.currentShow;\n return this.shows.find((s) => s.value === current)?.name ?? \"Unknown\";\n }\n\n get speed() {\n this.requireRunning();\n const row = this.state;\n return row === undefined\n ? \"Unknown\"\n : (LIGHT_SPEED[row.speed] ?? \"Unknown\");\n }\n\n get brightness() {\n this.requireRunning();\n const row = this.state;\n return row === undefined ? undefined : LIGHT_BRIGHTNESS[row.brightness];\n }\n\n get isOn() {\n const row = this.#reported;\n return row !== undefined && isLightLit(row.lightState);\n }\n\n #requireOmniDirect(options: { speed?: string; brightness?: number }) {\n if (\n (options.speed !== undefined || options.brightness !== undefined) &&\n !this.omniDirect\n ) {\n throw new OmniValidationError(\n `\"${this.name}\" is not in OmniDirect mode, so it does not support speed or brightness`,\n );\n }\n }\n\n showParams(\n show: number,\n options: { speed?: string; brightness?: number } = {},\n ) {\n this.#requireOmniDirect(options);\n if (!this.omniDirect) {\n return { data: show, field19: 0, field1a: 0, field1b: 0 };\n }\n return encodeShow(\n show,\n options.speed ?? this.#readOr(() => this.speed, \"1x\"),\n options.brightness ?? this.#readOr(() => this.brightness, 100),\n );\n }\n\n async setShow(show: number, options: LightWriteOptions = {}) {\n this.#requireOmniDirect(options);\n await this.#waitUntilStable(`show ${show}`, options);\n if (!options.force && !this.shows.some((s) => s.value === show)) {\n throw new OmniValidationError(\n `\"${this.name}\" has no show ${show}; its shows are 0 to ${Math.max(...this.shows.map((s) => s.value))}`,\n );\n }\n await this.omni.command(\n \"SetStandAloneLightShow\",\n {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n ...this.showParams(show, options),\n ...timerParams(),\n },\n verifyOptions(\n options,\n () =>\n this.state?.currentShow === show &&\n (options.speed === undefined ||\n this.#readOr(() => this.speed, \"\") === options.speed) &&\n (options.brightness === undefined ||\n this.#readOr(() => this.brightness, -1) === options.brightness),\n `Unable to set \"${this.name}\" to show ${show}`,\n ),\n );\n }\n\n on(options: LightWriteOptions = {}) {\n return this.#setPower(true, options);\n }\n\n off(options: LightWriteOptions = {}) {\n return this.#setPower(false, options);\n }\n\n async #setPower(on: boolean, options: LightWriteOptions) {\n await this.#waitUntilStable(on ? \"power on\" : \"power off\", options);\n await this.omni.command(\n \"SetUIEquipmentCmd\",\n {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n isOn: Number(on),\n ...timerParams(),\n },\n verifyOptions(\n options,\n // any move away from the old state counts\n () => {\n const row = this.state;\n return (\n row !== undefined &&\n row.lightState !==\n (on ? ColorLogicPowerState.OFF : ColorLogicPowerState.ACTIVE)\n );\n },\n `Unable to turn \"${this.name}\" ${on ? \"on\" : \"off\"}`,\n ),\n );\n }\n\n async #waitUntilStable(action: string, options: LightWriteOptions) {\n const { wait = true, pollMs = DEFAULT_POLL_MS } = options;\n await this.omni.refresh({ refetch: true, force: options.force });\n if (this.state === undefined) {\n if (options.force) {\n return;\n }\n throw new OmniLogicError(\n `The controller reports no telemetry for \"${this.name}\"; pass { force: true } to send anyway`,\n );\n }\n if (this.#isStable()) {\n equipmentLog.trace(\"light is stable\", {\n light: this.name,\n state: powerStateName(this.state?.lightState),\n });\n return;\n }\n if (!wait) {\n throw new OmniValidationError(\n `\"${this.name}\" is transitioning ` +\n `(${powerStateName(this.state?.lightState)}); ${action} would be silently ignored`,\n );\n }\n equipmentLog.debug(\"light is transitioning; waiting for a stable state\", {\n light: this.name,\n state: powerStateName(this.state?.lightState),\n action,\n pollMs,\n settleTimeoutMs: SETTLE_MS,\n });\n const started = Date.now();\n const deadline = started + SETTLE_MS;\n while (Date.now() < deadline) {\n await setTimeout(pollMs);\n await this.omni\n .refresh({ refetch: true, force: options.force })\n .catch((error: unknown) => {\n equipmentLog.trace(\"refresh failed while waiting for the light\", {\n light: this.name,\n error,\n });\n });\n if (this.#isStable()) {\n equipmentLog.debug(\"light settled\", {\n light: this.name,\n state: powerStateName(this.state?.lightState),\n ms: Date.now() - started,\n });\n return;\n }\n equipmentLog.trace(\"light still transitioning\", {\n light: this.name,\n state: powerStateName(this.state?.lightState),\n ms: Date.now() - started,\n });\n }\n throw new OmniTimeoutError(\n `Timed out waiting for \"${this.name}\" to settle`,\n );\n }\n\n #isStable() {\n const s = this.state?.lightState;\n return s === ColorLogicPowerState.OFF || s === ColorLogicPowerState.ACTIVE;\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { RELAY_STATE, RELAY_WHY_ON } from \"@/constants/labels\";\nimport { Device } from \"@/equipment/device\";\nimport type { Relay as RelayConfig } from \"@/types/config\";\nimport { countdownParams, timerParams } from \"@/utils/command\";\n\nexport class Relay extends Device {\n #type: string;\n #function: string;\n\n constructor(omni: OmniLogic, poolId: number, config: RelayConfig) {\n super(omni, poolId, config.systemId, config.name);\n this.#type = config.type;\n this.#function = config.function;\n }\n\n get type() {\n return this.#type;\n }\n\n get function() {\n return this.#function;\n }\n\n // the filter pump speed set when this feature turns on, held until the next schedule\n get valveDefaultSpeed() {\n return this.bodyConfig?.relays.find((r) => r.systemId === this.equipmentId)\n ?.valveDefaultSpeed;\n }\n\n get #rows() {\n const t = this.omni.telemetry;\n return [...t.relays, ...t.valveActuators, ...t.smartValveActuators];\n }\n\n get state() {\n return this.telemetry(this.#rows);\n }\n\n get #reported() {\n return this.reportedIn(this.#rows);\n }\n\n get #position() {\n const row = this.state;\n return \"relayState\" in row ? row.relayState : row.valveActuatorState;\n }\n\n get status() {\n return this.#reported ? (RELAY_STATE[this.#position] ?? \"Unknown\") : \"Off\";\n }\n\n get isOn() {\n return this.#reported && this.#position !== 0;\n }\n\n // where a smart valve actuator is driving to, and undefined for the rest\n get smartValveTarget() {\n return this.omni.telemetry.smartValveActuators.find(\n (r) => r.systemId === this.equipmentId,\n )?.smartValveTarget;\n }\n\n get whyOn() {\n return this.#reported\n ? (RELAY_WHY_ON[this.state.whyOn] ?? \"Unknown\")\n : \"No Message\";\n }\n\n get onCountdown() {\n return this.#reported && this.state.whyOn === 6; // Countdown Timer\n }\n\n #setState(on: boolean) {\n return this.omni.command(\"SetUIEquipmentCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n isOn: Number(on),\n ...timerParams(),\n });\n }\n\n on() {\n return this.#setState(true);\n }\n\n off() {\n return this.#setState(false);\n }\n\n async remainingCountdownTime() {\n const r = await this.omni.command(\"GetRemainingCountdownTime\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n });\n return r.hour * 60 + r.minute;\n }\n\n setCountdownTime(minutes: number) {\n return this.omni.command(\"SetUIEquipmentCmd\", {\n poolId: this.poolId,\n equipmentId: this.equipmentId,\n isOn: 1,\n ...countdownParams(minutes),\n });\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { isRunning } from \"@/constants/labels\";\nimport { WATER_TEMP_UNAVAILABLE } from \"@/constants/sentinels\";\nimport { Chlorinator } from \"@/equipment/chlorinator\";\nimport { CSAD } from \"@/equipment/csad\";\nimport { Filter } from \"@/equipment/filter\";\nimport { Heater } from \"@/equipment/heater\";\nimport { Light } from \"@/equipment/light\";\nimport { Pump } from \"@/equipment/pump\";\nimport { Relay } from \"@/equipment/relay\";\nimport type { BodyOfWater as BodyOfWaterConfig } from \"@/types/config\";\nimport { OmniLogicError } from \"@/utils/errors\";\nimport { hasSystemId } from \"@/utils/inventory\";\n\nexport class BodyOfWater {\n #systemId: number;\n #name: string;\n #type: string;\n #filter?: Filter;\n #pumps: Pump[];\n #heater?: Heater;\n #chlorinator?: Chlorinator;\n #csad?: CSAD;\n #lights: Light[];\n #relays: Relay[];\n #omni: OmniLogic;\n\n get systemId() {\n return this.#systemId;\n }\n\n get name() {\n return this.#name;\n }\n\n get type() {\n return this.#type;\n }\n\n get #config() {\n const found = this.#omni.config.backyard.bodiesOfWater.find(\n (b) => b.systemId === this.systemId,\n );\n if (found === undefined) {\n throw new OmniLogicError(`No configuration for \"${this.name}\"`);\n }\n return found;\n }\n\n get spilloverEnabled() {\n return this.#config.supportsSpillover;\n }\n\n get filter() {\n return this.#filter;\n }\n\n // every pump on the body, the filter pump first when there is one\n get pumps() {\n return [...this.#pumps];\n }\n\n get heater() {\n return this.#heater;\n }\n\n get chlorinator() {\n return this.#chlorinator;\n }\n\n get csad() {\n return this.#csad;\n }\n\n get lights() {\n return [...this.#lights];\n }\n\n get relays() {\n return [...this.#relays];\n }\n\n constructor(omni: OmniLogic, config: BodyOfWaterConfig) {\n const poolId = config.systemId;\n this.#omni = omni;\n this.#systemId = poolId;\n this.#name = config.name;\n this.#type = config.type;\n\n this.#filter = hasSystemId(config.filter)\n ? new Filter(omni, poolId, config.filter)\n : undefined;\n this.#pumps = [\n ...(this.#filter === undefined ? [] : [this.#filter]),\n ...config.pumps.map((p) => new Pump(omni, poolId, p)),\n ];\n this.#heater = hasSystemId(config.heater)\n ? new Heater(\n omni,\n poolId,\n config.heater.systemId,\n `${config.name} Heater`,\n )\n : undefined;\n this.#chlorinator = hasSystemId(config.chlorinator)\n ? new Chlorinator(\n omni,\n poolId,\n config.chlorinator.systemId,\n config.chlorinator.name,\n )\n : undefined;\n this.#csad = hasSystemId(config.csad)\n ? new CSAD(omni, poolId, config.csad)\n : undefined;\n this.#lights = config.colorLogicLights.map(\n (l) => new Light(omni, poolId, l.systemId, l.name),\n );\n this.#relays = config.relays.map((r) => new Relay(omni, poolId, r));\n }\n\n get state() {\n const row = this.#omni.telemetry.bodiesOfWater.find(\n (b) => b.systemId === this.systemId,\n );\n if (row === undefined) {\n throw new OmniLogicError(`No telemetry for \"${this.name}\"`);\n }\n return row;\n }\n\n get #reportedFilter() {\n const filter = this.filter;\n return filter !== undefined &&\n this.#omni.telemetry.filters.some(\n (r) => r.systemId === filter.equipmentId,\n )\n ? filter\n : undefined;\n }\n\n get waterTemp() {\n if (!isRunning(this.#omni.telemetry.backyard.state)) {\n return undefined;\n }\n const temp = this.state.waterTemp;\n return temp === WATER_TEMP_UNAVAILABLE ? undefined : temp;\n }\n\n get spilloverOn() {\n const filter = this.#reportedFilter;\n return (\n filter !== undefined && filter.running && filter.state.valvePosition === 3 // Spillover\n );\n }\n\n get spilloverOnCountdown() {\n const filter = this.#reportedFilter;\n return (\n filter !== undefined &&\n filter.running &&\n filter.state.whyFilterIsOn === 17 // Spillover Countdown Timer\n );\n }\n\n setSpilloverEnabled(on: boolean) {\n return this.#omni.command(\"SetSpaSpilloverEnable\", {\n poolId: this.systemId,\n data: Number(on),\n });\n }\n}\n","import type { OmniLogic, WriteOptions } from \"@/client/omnilogic\";\nimport { OmniValidationError } from \"@/utils/errors\";\nimport { matches } from \"@/utils/helpers\";\n\n// the data a theme favorite carries in place of a show\nexport const THEME_FAVORITE_DATA = 268435455;\n\nexport type FavoriteCreate = {\n equipmentId: number;\n // the show number for a light, 0 for anything else\n data: number;\n};\n\nexport class Favorites {\n #omni: OmniLogic;\n\n constructor(omni: OmniLogic) {\n this.#omni = omni;\n }\n\n list() {\n return this.#omni.config.favorites;\n }\n\n get(indexId: number) {\n return this.list().find((f) => f.indexId === indexId);\n }\n\n async create(spec: FavoriteCreate, options: WriteOptions = {}) {\n const record = { equipmentIdOrThemeId: spec.equipmentId, data: spec.data };\n const before = new Set(this.list().map((f) => f.systemId));\n const created = () =>\n this.list().find((f) => !before.has(f.systemId) && matches(f, record));\n await this.#omni.command(\n \"CreateUIFavoriteCmd\",\n { equipmentId: spec.equipmentId, data: spec.data },\n {\n verify: () => created() !== undefined,\n attempts: options.attempts,\n failure: `Unable to create favorite for equipment ${spec.equipmentId}`,\n },\n );\n return created()!;\n }\n\n createForTheme(themeId: number, options: WriteOptions = {}) {\n return this.create(\n { equipmentId: themeId, data: THEME_FAVORITE_DATA },\n options,\n );\n }\n\n async remove(indexId: number, options: WriteOptions = {}) {\n const favorite = this.get(indexId);\n if (favorite === undefined) {\n throw new OmniValidationError(\n `No favorite at index ${indexId} in the cached config`,\n );\n }\n // a favorite is identified by its system id, an index is a display slot\n const removed = favorite.systemId;\n await this.#omni.command(\n \"DeleteUIFavoriteCmd\",\n { data: indexId },\n {\n verify: () => !this.list().some((f) => f.systemId === removed),\n attempts: options.attempts,\n failure: `Unable to delete favorite ${indexId}`,\n },\n );\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport type { UnitSystem } from \"@/types/config\";\nimport { OmniValidationError } from \"@/utils/errors\";\n\nexport type SpeedFormat = \"RPM\" | \"Percent\";\nexport type ChlorinatorDisplay = \"Salt\" | \"Minerals\";\n\nexport class Panel {\n #omni: OmniLogic;\n\n constructor(omni: OmniLogic) {\n this.#omni = omni;\n }\n\n get omni() {\n return this.#omni;\n }\n\n get #system() {\n return this.omni.config.system;\n }\n\n async beeper() {\n const r = await this.omni.command(\"GetBeeper\");\n return r.enabled;\n }\n\n setBeeper(on: boolean) {\n return this.omni.command(\"SetBeeper\", { data: Number(on) });\n }\n\n async backLight() {\n const r = await this.omni.command(\"GetBackLight\");\n return r.state;\n }\n\n setBackLight(on: boolean) {\n return this.omni.command(\"SetBackLight\", { data: Number(on) });\n }\n\n async backLightBrightness() {\n const r = await this.omni.command(\"GetBackLightBrightness\");\n return r.brightness;\n }\n\n setBackLightBrightness(percent: number) {\n return this.omni.command(\"SetBackLightBrightness\", { data: percent });\n }\n\n async backLightTimeout() {\n const r = await this.omni.command(\"GetBackLightTimeout\");\n return r.timeout;\n }\n\n setBackLightTimeout(seconds: number) {\n return this.omni.command(\"SetBackLightTimeout\", { data: seconds });\n }\n\n get vspSpeedFormat(): SpeedFormat {\n return this.#system.mspVspSpeedFormat === \"RPM\" ? \"RPM\" : \"Percent\";\n }\n\n setVspSpeedFormat(format: SpeedFormat) {\n return this.omni.command(\"SetVSPSpeedFormat\", {\n data: format === \"RPM\" ? 1 : 0,\n });\n }\n\n get chlorinatorDisplay(): ChlorinatorDisplay {\n return this.#system.mspChlorDisplay === \"Salt\" ? \"Salt\" : \"Minerals\";\n }\n\n setChlorinatorDisplay(display: ChlorinatorDisplay) {\n return this.omni.command(\"SetCHLORDisplay\", {\n data: display === \"Salt\" ? 1 : 0,\n });\n }\n\n // the controller words it \"12 Hour Format\"\n get timeFormat() {\n return parseInt(this.#system.mspTimeFormat, 10);\n }\n\n setTimeFormat(hours: number) {\n if (hours !== 12 && hours !== 24) {\n throw new OmniValidationError(`Time format ${hours} is not 12 or 24`);\n }\n return this.omni.command(\"SetTimeFormat\", { data: hours });\n }\n\n async units() {\n const r = await this.omni.command(\"GetUnits\");\n return r.unitFormat ? \"Metric\" : \"Standard\";\n }\n\n setUnits(units: UnitSystem) {\n return this.omni.command(\"SetUnits\", {\n data: units === \"Metric\" ? 1 : 0,\n });\n }\n\n async coordinates() {\n const r = await this.omni.command(\"GetCoordinates\");\n return {\n latitude: r.latitude,\n longitude: r.longitude,\n };\n }\n\n setCoordinates(latitude: number, longitude: number) {\n return this.omni.command(\"SetCoordinates\", { latitude, longitude });\n }\n}\n","import type { OmniLogic, WriteOptions } from \"@/client/omnilogic\";\nimport type { ScheduleCreate } from \"@/equipment/schedules\";\nimport { countdownParams, timerParams } from \"@/utils/command\";\nimport { OmniValidationError } from \"@/utils/errors\";\n\nexport class Themes {\n #omni: OmniLogic;\n\n constructor(omni: OmniLogic) {\n this.#omni = omni;\n }\n\n list() {\n return this.#omni.config.themes;\n }\n\n // any body's id will do\n get #groupFields() {\n const [body] = this.#omni.config.backyard.bodiesOfWater;\n if (body === undefined) {\n throw new OmniValidationError(\"No body of water in the cached config\");\n }\n return { daysActive: 0, recurring: 0, poolId: body.systemId };\n }\n\n get activeIds() {\n return this.#omni.telemetry.themes\n .filter((g) => g.groupState !== 0)\n .map((g) => g.systemId);\n }\n\n get(themeId: number) {\n return this.list().find((g) => g.systemId === themeId);\n }\n\n async create(name: string, options: WriteOptions = {}) {\n const before = new Set(this.list().map((g) => g.systemId));\n const created = () =>\n this.list().find((g) => !before.has(g.systemId) && g.name === name);\n await this.#omni.command(\n \"SaveNewGroupCmd\",\n { name, ...this.#groupFields },\n {\n verify: () => created() !== undefined,\n attempts: options.attempts,\n failure: `Unable to create theme \"${name}\"`,\n },\n );\n return created()!;\n }\n\n async rename(themeId: number, name: string, options: WriteOptions = {}) {\n if (this.list().some((g) => g.systemId !== themeId && g.name === name)) {\n throw new OmniValidationError(`A theme named \"${name}\" already exists`);\n }\n await this.#omni.command(\n \"SetGroupCmd\",\n { equipmentId: themeId, name, ...this.#groupFields },\n {\n verify: () => this.get(themeId)?.name === name,\n attempts: options.attempts,\n failure: `Unable to rename theme ${themeId} to \"${name}\"`,\n },\n );\n }\n\n async run(\n themeId: number,\n on = true,\n { minutes }: { minutes?: number } = {},\n ) {\n await this.#omni.command(\"RunGroupCmd\", {\n equipmentId: themeId,\n data: on ? 1 : 0,\n ...(on && minutes !== undefined\n ? countdownParams(minutes)\n : timerParams()),\n });\n }\n\n schedule(\n themeId: number,\n window: Omit<ScheduleCreate, \"equipmentId\" | \"data\" | \"type\">,\n ) {\n return this.#omni.backyard.schedules.create({\n ...window,\n equipmentId: themeId,\n data: 1,\n type: \"theme\",\n });\n }\n\n async remove(themeId: number, options: WriteOptions = {}) {\n if (this.get(themeId) === undefined) {\n throw new OmniValidationError(`No theme ${themeId} in the cached config`);\n }\n await this.#omni.command(\n \"DeleteGroupCmd\",\n { equipmentId: themeId },\n {\n verify: () => this.get(themeId) === undefined,\n attempts: options.attempts,\n failure: `Unable to delete theme ${themeId}`,\n },\n );\n }\n}\n","import type { OmniLogic } from \"@/client/omnilogic\";\nimport { isRunning, SYSTEM_STATE } from \"@/constants/labels\";\nimport { AIR_TEMP_UNAVAILABLE } from \"@/constants/sentinels\";\nimport { BodyOfWater } from \"@/equipment/bodyOfWater\";\nimport { Favorites } from \"@/equipment/favorites\";\nimport { Light } from \"@/equipment/light\";\nimport { Panel } from \"@/equipment/panel\";\nimport { Relay } from \"@/equipment/relay\";\nimport { Schedules } from \"@/equipment/schedules\";\nimport { Themes } from \"@/equipment/themes\";\nimport { OmniLogicError } from \"@/utils/errors\";\n\nexport class Backyard {\n #omni: OmniLogic;\n\n constructor(omni: OmniLogic) {\n this.#omni = omni;\n }\n\n get schedules() {\n return new Schedules(this.#omni);\n }\n\n get favorites() {\n return new Favorites(this.#omni);\n }\n\n get themes() {\n return new Themes(this.#omni);\n }\n\n get panel() {\n return new Panel(this.#omni);\n }\n\n get state() {\n return this.#omni.telemetry.backyard;\n }\n\n get running() {\n return isRunning(this.state.state);\n }\n\n get systemState() {\n return SYSTEM_STATE[this.state.state] ?? \"Unknown\";\n }\n\n get airTemp() {\n const temp = this.state.airTemp;\n return !this.running || temp === AIR_TEMP_UNAVAILABLE ? undefined : temp;\n }\n\n get bodies() {\n return this.#omni.config.backyard.bodiesOfWater.map(\n (raw) => new BodyOfWater(this.#omni, raw),\n );\n }\n\n get lights() {\n const backyard = this.#omni.config.backyard;\n return backyard.colorLogicLights.map(\n (l) => new Light(this.#omni, backyard.systemId, l.systemId, l.name),\n );\n }\n\n get relays() {\n const backyard = this.#omni.config.backyard;\n return backyard.relays.map(\n (r) => new Relay(this.#omni, backyard.systemId, r),\n );\n }\n\n body(nameOrId: string | number) {\n return this.bodies.find((b) =>\n typeof nameOrId === \"number\"\n ? b.systemId === nameOrId\n : b.name.toLowerCase() === nameOrId.toLowerCase(),\n );\n }\n\n get pool() {\n return this.#ofType(\"BOW_POOL\");\n }\n\n get spa() {\n return this.#ofType(\"BOW_SPA\");\n }\n\n #ofType(type: string) {\n const matches = this.bodies.filter((b) => b.type === type);\n if (matches.length > 1) {\n throw new OmniLogicError(\n `This system has more than one body of water of type ${type}; use body(nameOrId) or bodies`,\n );\n }\n return matches[0];\n }\n}\n","import type { CommandOpcode, SWITCH_OPCODE } from \"@/client/spec\";\n\n// acknowledgment of a controller message, sent with that message's id\nexport const OUTBOUND_ACK = 0;\n\nexport const INBOUND_FRAME = {\n ack: 1002,\n // an unsolicited telemetry push, always compressed\n telemetryUpdate: 1004,\n // header of a split payload, declaring how many blocks follow\n leadMessage: 1998,\n // one block of a split payload\n blockMessage: 1999,\n} as const;\n\nexport type SendableOpcode =\n | CommandOpcode\n | (typeof SWITCH_OPCODE)[keyof typeof SWITCH_OPCODE]\n | typeof OUTBOUND_ACK;\n\nexport const isAck = (opCode: number) =>\n opCode === OUTBOUND_ACK || opCode === INBOUND_FRAME.ack;\n\nexport class OmniLogicMessage {\n id: number;\n opCode: number;\n payload: Buffer;\n // 0=request with body, 1=bare request, 2=panel, 3=peer controller\n clientType: number;\n version: string;\n timestamp: number = Math.floor(Date.now() / 1000);\n compressed: boolean = false;\n\n constructor(\n messageId: number,\n opCode: number,\n payload: string | null = null,\n version: string = \"1.19\",\n ) {\n this.id = messageId;\n this.opCode = opCode;\n this.clientType = payload !== null ? 0 : 1;\n this.payload = Buffer.from(\n payload !== null ? `${payload}\\x00` : \"\",\n \"utf-8\",\n );\n this.version = version;\n }\n\n toBytes() {\n const header = Buffer.alloc(24);\n header.writeUInt32BE(this.id, 0);\n header.writeBigUInt64BE(BigInt(this.timestamp), 4);\n header.write(this.version, 12, \"ascii\");\n header.writeUInt32BE(this.opCode, 16);\n header.writeUInt8(this.clientType, 20);\n header.writeUInt8(this.compressed ? 1 : 0, 22);\n return Buffer.concat([header, this.payload]);\n }\n\n toString() {\n const head =\n `ID: ${this.id}, Type: ${this.opCode}, Compressed: ${this.compressed}, ` +\n `Client: ${this.clientType}, Version: ${this.version}, Timestamp: ${this.timestamp}`;\n // a block or compressed payload is not text\n if (this.opCode === INBOUND_FRAME.blockMessage || this.compressed) {\n return head;\n }\n return `${head}, Body: ${this.payload.subarray(0, -1).toString(\"utf-8\")}`;\n }\n\n static fromBytes(data: Buffer) {\n if (data.length < 24) {\n throw new Error(\"Invalid message: too short\");\n }\n const header = data.subarray(0, 24);\n const version = header\n .subarray(12, 16)\n .toString(\"ascii\")\n .replace(/\\0/g, \"\");\n const message = new OmniLogicMessage(\n header.readUInt32BE(0),\n header.readUInt32BE(16),\n null,\n version,\n );\n message.timestamp = Number(header.readBigUInt64BE(4));\n message.clientType = header.readUInt8(20);\n message.compressed =\n header.readUInt8(22) === 1 ||\n message.opCode === INBOUND_FRAME.telemetryUpdate;\n message.payload = data.subarray(24);\n return message;\n }\n}\n","import type { OmniLogicMessage } from \"@/transport/message\";\nimport { OmniTimeoutError } from \"@/utils/errors\";\nimport { createLogger } from \"@/utils/logger\";\n\nconst protocolLog = createLogger(\"protocol\");\n\ntype PendingResolver = {\n resolve: (value: OmniLogicMessage) => void;\n reject: (reason: Error) => void;\n};\n\nexport class MessageQueue {\n #pendingResolvers: PendingResolver[] = [];\n #queue: OmniLogicMessage[] = [];\n // the error that ended the socket\n #failure: Error | undefined;\n\n add(message: OmniLogicMessage) {\n const next = this.#pendingResolvers.shift();\n if (next) {\n next.resolve(message);\n } else {\n this.#queue.push(message);\n }\n }\n\n next(timeoutMs: number, timeoutMessage: string): Promise<OmniLogicMessage> {\n if (this.#failure !== undefined) {\n return Promise.reject(this.#failure);\n }\n const message = this.#queue.shift();\n if (message !== undefined) {\n return Promise.resolve(message);\n }\n return new Promise((resolve, reject) => {\n const pending: PendingResolver = {\n resolve: (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n reject: (reason) => {\n clearTimeout(timer);\n reject(reason);\n },\n };\n const timer = setTimeout(() => {\n this.#pendingResolvers = this.#pendingResolvers.filter(\n (p) => p !== pending,\n );\n reject(new OmniTimeoutError(timeoutMessage));\n }, timeoutMs);\n this.#pendingResolvers.push(pending);\n });\n }\n\n reset(failure?: Error) {\n this.#failure = failure ?? this.#failure;\n if (this.#pendingResolvers.length > 0 || this.#queue.length > 0) {\n protocolLog.trace(\"queue reset\", {\n waiters: this.#pendingResolvers.length,\n buffered: this.#queue.length,\n });\n }\n for (const pending of this.#pendingResolvers) {\n pending.reject(\n failure ?? new OmniTimeoutError(\"The operation was closed\"),\n );\n }\n this.#pendingResolvers = [];\n this.#queue = [];\n }\n}\n","import { createSocket, type Socket } from \"node:dgram\";\nimport { setTimeout } from \"node:timers/promises\";\nimport { inflateSync } from \"node:zlib\";\n\nimport { SWITCH_OPCODE } from \"@/client/spec\";\nimport {\n INBOUND_FRAME,\n isAck,\n OmniLogicMessage,\n OUTBOUND_ACK,\n type SendableOpcode,\n} from \"@/transport/message\";\nimport { MessageQueue } from \"@/transport/queue\";\nimport { OmniLogicError, OmniTimeoutError } from \"@/utils/errors\";\nimport { defined, isRecord } from \"@/utils/helpers\";\nimport { createLogger } from \"@/utils/logger\";\nimport {\n buildMessageXml,\n parametersByName,\n parseXML,\n type ResponseMessage,\n} from \"@/utils/xml\";\n\nconst protocolLog = createLogger(\"protocol\");\n\n// how many blocks follow and how many bytes of them are payload\nconst parseLeadMessage = (payload: Buffer) => {\n const xml = payload.subarray(0, -1).toString(\"utf-8\");\n const parsed: ResponseMessage = parseXML(xml);\n if (!isRecord(parsed.response) || !isRecord(parsed.response.parameters)) {\n throw new OmniLogicError(`Malformed reply header: ${JSON.stringify(xml)}`);\n }\n const params = parametersByName(parsed.response.parameters.parameter);\n const count = params.msgBlockCount;\n if (typeof count !== \"number\") {\n throw new OmniLogicError(\n `Malformed reply header parameters: ${JSON.stringify(params)}`,\n );\n }\n const size = params.msgSize;\n return {\n blockCount: count,\n msgSize: typeof size === \"number\" && size > 0 ? size : undefined,\n };\n};\n\ntype Connection = {\n socket: Socket;\n queue: MessageQueue;\n timings: Timings;\n};\n\nexport type Timings = {\n // per attempt, before retransmitting\n ackTimeoutMs: number;\n // for the reply, after the send is acknowledged\n nextMessageTimeoutMs: number;\n // after one operation ends and before the next starts, 0 for no gap\n minSendGapMs: number;\n // after a settling command, the pause once the controller answers again\n settleGraceMs: number;\n};\n\nexport const DEFAULT_TIMINGS: Timings = {\n ackTimeoutMs: 5000,\n // the controller retransmits five times at 2.1 s\n nextMessageTimeoutMs: 2.1 * 5 * 1000,\n minSendGapMs: 500,\n settleGraceMs: 2000,\n};\n\nexport type OperationOptions = {\n timings?: Partial<Timings>;\n // the controller goes quiet after this send\n settle?: boolean;\n // how many times to send when the controller acknowledges but never replies, default 1\n attempts?: number;\n // the opcode the reply carries when it arrives in one frame, any other frame is skipped\n reply?: number;\n};\n\nconst ACK_ATTEMPTS = 5;\n\nconst newId = () => Math.floor(Math.random() * 0xffffffff);\n\n// the end of the last queued operation\nlet queueTail = Promise.resolve(0);\n\nexport class OmniLogicProtocol {\n #host: string;\n #port: number;\n #timings: Timings;\n\n constructor(host: string, port: number, timings: Partial<Timings> = {}) {\n this.#host = host;\n this.#port = port;\n this.#timings = { ...DEFAULT_TIMINGS, ...defined(timings) };\n }\n\n get #key() {\n return `${this.#host}:${this.#port}`;\n }\n\n async #waitForTurn(timings: Timings, previous: Promise<number>) {\n const started = Date.now();\n const ended = await previous;\n protocolLog.trace(\"previous operation ended\", {\n key: this.#key,\n waitedMs: Date.now() - started,\n });\n // capped at the gap\n const wait = Math.min(\n timings.minSendGapMs,\n ended + timings.minSendGapMs - Date.now(),\n );\n if (wait > 0) {\n protocolLog.debug(\"throttling\", { key: this.#key, waitMs: wait });\n await setTimeout(wait);\n }\n }\n\n async #settle(timings: Timings) {\n protocolLog.debug(\"settling\", { key: this.#key });\n const started = Date.now();\n let conn: Connection;\n try {\n conn = await this.#open(timings);\n } catch (error) {\n protocolLog.warn(\"could not open a socket to settle; releasing\", {\n key: this.#key,\n error,\n });\n return;\n }\n try {\n await this.#send(conn, SWITCH_OPCODE.GetTelemetry, null);\n await this.#processResponse(conn, INBOUND_FRAME.telemetryUpdate);\n protocolLog.trace(\"controller answered the settle probe\", {\n key: this.#key,\n ms: Date.now() - started,\n });\n } catch (error) {\n protocolLog.warn(\"controller did not answer while settling; releasing\", {\n key: this.#key,\n error,\n });\n } finally {\n this.#close(conn);\n }\n if (timings.settleGraceMs > 0) {\n protocolLog.trace(\"settle grace\", {\n key: this.#key,\n ms: timings.settleGraceMs,\n });\n await setTimeout(timings.settleGraceMs);\n }\n protocolLog.debug(\"settled; releasing queued operations\", {\n key: this.#key,\n ms: Date.now() - started,\n });\n }\n\n async #withConnection<T>(\n options: OperationOptions,\n fn: (conn: Connection) => Promise<T>,\n ) {\n const timings = { ...this.#timings, ...defined(options.timings ?? {}) };\n const previous = queueTail;\n const { promise: ended, resolve: end } = Promise.withResolvers<number>();\n queueTail = ended;\n try {\n await this.#waitForTurn(timings, previous);\n const started = Date.now();\n const conn = await this.#open(timings);\n try {\n const result = await fn(conn);\n protocolLog.trace(\"operation complete\", {\n key: this.#key,\n ms: Date.now() - started,\n });\n return result;\n } finally {\n this.#close(conn);\n }\n } finally {\n if (options.settle) {\n void this.#settle(timings).finally(() => end(Date.now()));\n } else {\n end(Date.now());\n }\n }\n }\n\n #close(conn: Connection) {\n conn.queue.reset();\n try {\n conn.socket.close();\n } catch {\n // already closed\n }\n protocolLog.trace(\"socket closed\");\n }\n\n #open(timings: Timings): Promise<Connection> {\n return new Promise((resolve, reject) => {\n const socket = createSocket(\"udp4\");\n const queue = new MessageQueue();\n const conn: Connection = { socket, queue, timings };\n let connected = false;\n\n socket.on(\"error\", (err) => {\n protocolLog.debug(\"socket error\", { err });\n if (connected) {\n queue.reset(err);\n } else {\n socket.close();\n reject(err);\n }\n });\n\n socket.on(\"message\", (data: Buffer) => {\n try {\n const message = OmniLogicMessage.fromBytes(data);\n protocolLog.trace(\"received message\", {\n message: message.toString(),\n });\n queue.add(message);\n } catch (error) {\n protocolLog.warn(\"dropped a malformed datagram\", {\n bytes: data.length,\n error,\n });\n }\n });\n\n socket.on(\"connect\", () => {\n connected = true;\n protocolLog.debug(\"socket open\");\n resolve(conn);\n });\n\n protocolLog.debug(\"opening socket\", {\n host: this.#host,\n port: this.#port,\n });\n try {\n socket.connect(this.#port, this.#host);\n } catch (err) {\n socket.close();\n reject(err);\n }\n });\n }\n\n async sendMessage(\n opCode: SendableOpcode,\n payload: string | null,\n options: OperationOptions = {},\n ) {\n return this.#withConnection(options, (conn) =>\n this.#send(conn, opCode, payload),\n );\n }\n\n async sendAndReceive(\n opCode: SendableOpcode,\n payload: string | null,\n options: OperationOptions = {},\n ) {\n const attempts = Math.max(1, options.attempts ?? 1);\n return this.#withConnection(options, async (conn) => {\n for (let attempt = 1; ; attempt++) {\n const message = await this.#send(conn, opCode, payload);\n protocolLog.debug(\"waiting for response\", { id: message.id });\n try {\n const response = await this.#processResponse(conn, options.reply);\n protocolLog.debug(\"received response\", {\n id: message.id,\n opCode,\n length: response.length,\n });\n return response;\n } catch (error) {\n if (!(error instanceof OmniTimeoutError) || attempt >= attempts) {\n throw error;\n }\n protocolLog.warn(\"acknowledged but no reply, sending again\", {\n id: message.id,\n opCode,\n attempt,\n of: attempts,\n });\n }\n }\n });\n }\n\n async #nextReply(conn: Connection, reply: number | undefined) {\n protocolLog.debug(\"waiting for the reply\", { reply });\n for (;;) {\n const message = await conn.queue.next(\n conn.timings.nextMessageTimeoutMs,\n \"No reply from the controller\",\n );\n if (isAck(message.opCode)) {\n protocolLog.trace(\"ACK received, skipping\", { id: message.id });\n continue;\n }\n // a long reply arrives as a lead message whatever its opcode\n if (\n reply !== undefined &&\n message.opCode !== reply &&\n message.opCode !== INBOUND_FRAME.leadMessage\n ) {\n protocolLog.trace(\"message of another kind, skipping\", {\n id: message.id,\n opCode: message.opCode,\n reply,\n });\n await this.#sendAck(conn, message.id);\n continue;\n }\n protocolLog.debug(\"reply received\", { id: message.id });\n return message;\n }\n }\n\n async #waitForAck(conn: Connection, ackId: number) {\n protocolLog.debug(\"waiting for ACK\", { id: ackId });\n const message = await conn.queue.next(\n conn.timings.ackTimeoutMs,\n `No acknowledgment from the controller (message ${ackId})`,\n );\n if (message.id !== ackId) {\n protocolLog.trace(\"reply arrived before the ACK; putting it back\", {\n id: message.id,\n expected: ackId,\n opCode: message.opCode,\n });\n conn.queue.add(message);\n }\n }\n\n async #sendAck(conn: Connection, messageId: number) {\n const message = buildMessageXml(\"Ack\");\n protocolLog.debug(\"sending ACK\", { id: messageId });\n await this.#send(conn, OUTBOUND_ACK, message, messageId);\n }\n\n async #send(\n conn: Connection,\n opCode: SendableOpcode,\n payload: string | null,\n messageId?: number,\n ) {\n let message = new OmniLogicMessage(messageId ?? newId(), opCode, payload);\n protocolLog.debug(\"sending message\", { message: message.toString() });\n\n for (let attempt = 0; attempt < ACK_ATTEMPTS; attempt++) {\n // the controller takes a retransmission as a new request\n if (attempt > 0 && messageId === undefined) {\n message = new OmniLogicMessage(newId(), opCode, payload);\n }\n const bytes = message.toBytes();\n conn.socket.send(bytes, (err) => {\n if (err) {\n protocolLog.warn(\"send failed\", { id: message.id, err: err.message });\n conn.queue.reset(err);\n }\n });\n protocolLog.trace(\"sent\", {\n id: message.id,\n opCode,\n attempt: attempt + 1,\n bytes: bytes.length,\n });\n if (isAck(message.opCode)) {\n break;\n }\n\n try {\n await this.#waitForAck(conn, message.id);\n protocolLog.debug(\"ACK received\", { id: message.id });\n break;\n } catch (error) {\n if (\n !(error instanceof OmniTimeoutError) ||\n attempt === ACK_ATTEMPTS - 1\n ) {\n throw error;\n }\n protocolLog.warn(\"ACK not received, retrying\", {\n id: message.id,\n attempt: attempt + 1,\n });\n }\n }\n\n return message;\n }\n\n async #processResponse(conn: Connection, reply?: number) {\n const message = await this.#nextReply(conn, reply);\n await this.#sendAck(conn, message.id);\n\n let payload: Buffer;\n if (message.opCode === INBOUND_FRAME.leadMessage) {\n const { blockCount, msgSize } = parseLeadMessage(message.payload);\n protocolLog.trace(\"received lead message\", { blockCount });\n if (blockCount === 0) {\n protocolLog.trace(\n \"empty response: the lead message announced no blocks\",\n );\n return \"\";\n }\n\n const blocks: Map<number, Buffer> = new Map();\n while (blocks.size < blockCount) {\n const block = await conn.queue.next(\n conn.timings.nextMessageTimeoutMs,\n \"The controller stopped partway through its reply\",\n );\n // a resend means the controller missed the ack\n if (\n block.id === message.id ||\n (block.opCode === INBOUND_FRAME.blockMessage && blocks.has(block.id))\n ) {\n protocolLog.trace(\"duplicate message, acknowledging again\", {\n id: block.id,\n });\n await this.#sendAck(conn, block.id);\n continue;\n }\n if (block.opCode !== INBOUND_FRAME.blockMessage) {\n protocolLog.trace(\"message of another kind, skipping\", {\n id: block.id,\n opCode: block.opCode,\n });\n await this.#sendAck(conn, block.id);\n continue;\n }\n await this.#sendAck(conn, block.id);\n // a block's first 8 bytes are a header\n blocks.set(block.id, block.payload.subarray(8));\n protocolLog.trace(\"block received\", {\n id: block.id,\n received: blocks.size,\n of: blockCount,\n bytes: block.payload.length - 8,\n });\n }\n payload = Buffer.concat(\n Array.from(blocks.entries())\n .toSorted((a, b) => a[0] - b[0])\n .map(([, data]) => data),\n );\n if (msgSize !== undefined && msgSize < payload.length) {\n protocolLog.trace(\"trimming padding past the announced size\", {\n from: payload.length,\n to: msgSize,\n });\n payload = payload.subarray(0, msgSize);\n }\n protocolLog.trace(\"blocks reassembled\", {\n blocks: blockCount,\n bytes: payload.length,\n });\n } else {\n payload = message.payload;\n }\n\n if (message.compressed && payload.length > 0) {\n try {\n const compressedBytes = payload.length;\n payload = inflateSync(payload);\n protocolLog.trace(\"decompressed\", {\n from: compressedBytes,\n to: payload.length,\n });\n } catch (error: unknown) {\n protocolLog.debug(\"decompression failed\", {\n opCode: message.opCode,\n error,\n });\n throw new OmniLogicError(\"Could not decompress the reply\", {\n cause: error,\n });\n }\n }\n\n return payload.toString(\"utf-8\").replace(/\\0$/, \"\");\n }\n}\n","import { setTimeout } from \"node:timers/promises\";\n\nimport {\n COMMANDS,\n type CommandName,\n type CommandParams,\n type CommandResult,\n SWITCH_OPCODE,\n} from \"@/client/spec\";\nimport { isRunning } from \"@/constants/labels\";\nimport { Backyard } from \"@/equipment/backyard\";\nimport {\n DEFAULT_TIMINGS,\n OmniLogicProtocol,\n type Timings,\n} from \"@/transport/protocol\";\nimport type { MSPConfig } from \"@/types/config\";\nimport type { SysInfo } from \"@/types/sysinfo\";\nimport type { Telemetry } from \"@/types/telemetry\";\nimport { buildCommandXml, parseCommandResponse } from \"@/utils/command\";\nimport {\n CommandFailedError,\n EquipmentNotInstalledError,\n FirmwareTooOldError,\n OmniLogicError,\n OmniValidationError,\n SystemStateError,\n ReadingUnavailableError,\n} from \"@/utils/errors\";\nimport { defined, findBySystemId, numberOf, stringOf } from \"@/utils/helpers\";\nimport {\n INVENTORY_PATHS,\n discover,\n presenceAt,\n systemIdAt,\n type Inventory,\n type InventoryPath,\n type Presence,\n} from \"@/utils/inventory\";\nimport { createLogger } from \"@/utils/logger\";\nimport {\n buildMessageXml,\n parseConfig,\n parseSysInfo,\n parseTelemetry,\n} from \"@/utils/xml\";\n\nconst DEFAULT_CACHE_TTL_SECONDS = 30;\nconst DEFAULT_READ_ATTEMPTS = 3;\n\nexport const MIN_MSP_VERSION = \"R0502000\";\n\nconst MSP_VERSION_SHAPE = /^R\\d{7}$/;\n\nexport const DEFAULT_PORT = 10444;\n\nexport type OmniLogicOptions = {\n host: string;\n port?: number;\n // seconds\n cacheTTL?: number;\n // ignored when protocol is supplied\n timings?: Partial<Timings>;\n // how many times a read is sent when the controller acknowledges it but never replies, default 3\n readAttempts?: number;\n // for testing purposes only\n protocol?: OmniLogicProtocol;\n // a cached config to start from, refetched when the checksum moves\n config?: MSPConfig;\n};\n\nexport type CommandOptions = {\n // send even where the SDK would refuse\n force?: boolean;\n timings?: Partial<Timings>;\n // whether the command took\n verify?: () => boolean;\n // default 0: one check\n timeoutMs?: number;\n // default 4000\n pollMs?: number;\n // sends of a write until verify passes, or of a read until the controller replies, default 1 and the session's readAttempts\n attempts?: number;\n // default \"<name> failed\"\n failure?: string;\n // the reply as sent, unparsed\n raw?: boolean;\n};\n\nexport type WriteOptions = Pick<CommandOptions, \"attempts\">;\n\nexport type ReadOptions<R extends boolean = boolean> = { raw?: R };\ntype Fetched<R extends boolean, T> = Promise<R extends true ? string : T>;\n\n// the opcode each fetch answers with\nconst FETCH_REPLY: Record<keyof typeof SWITCH_OPCODE, number> = {\n RequestConfiguration: 1003,\n GetTelemetry: 1004,\n GetSysInfo: 1411,\n};\n\nconst omnilogicLog = createLogger(\"omnilogic\");\nconst commandLog = createLogger(\"command\");\n\nconst ACTUATES_VALVE: Set<CommandName> = new Set([\n \"SetUIPoolSpaSpilloverCmd\",\n \"SetUISpilloverCmd\",\n \"SetUIValveCmd\",\n \"SetUISmartValveCmd\",\n \"SetUISmartValveTargetCmd\",\n]);\n\nconst isInventoryPath = (value: string): value is InventoryPath =>\n INVENTORY_PATHS.some((path) => path === value);\n\n// a check that reads while the controller is off has not passed yet\nconst verified = (verify: () => boolean) => {\n try {\n return verify();\n } catch (error) {\n if (error instanceof ReadingUnavailableError) {\n return false;\n }\n throw error;\n }\n};\n\nexport class OmniLogic {\n #protocol: OmniLogicProtocol;\n #backyard = new Backyard(this);\n #mspConfig: MSPConfig | null = null;\n #telemetry: Telemetry | null = null;\n #configChecksum: number = 0;\n #telemetryLastUpdated: number = 0;\n #cacheTTL: number;\n #timings: Timings;\n #readAttempts: number;\n #inventory: Inventory | null = null;\n\n #telemetryDirty: boolean = true;\n // resolves when the first refresh has finished\n #firstRefresh: Promise<void> | null = null;\n #refreshStarted: number = 0;\n #telemetryCachedFrom: number = 0;\n #writes: number = 0;\n\n constructor(options: OmniLogicOptions) {\n const {\n host,\n port = DEFAULT_PORT,\n cacheTTL = DEFAULT_CACHE_TTL_SECONDS,\n timings = {},\n readAttempts = DEFAULT_READ_ATTEMPTS,\n protocol,\n config,\n } = options;\n this.#cacheTTL = cacheTTL;\n this.#readAttempts = readAttempts;\n this.#timings = { ...DEFAULT_TIMINGS, ...defined(timings) };\n this.#protocol =\n protocol ?? new OmniLogicProtocol(host, port, this.#timings);\n if (config !== undefined) {\n this.#adopt(config);\n this.#configChecksum = config.checksum;\n }\n }\n\n get timings() {\n return this.#timings;\n }\n\n get backyard() {\n return this.#backyard;\n }\n\n get configChecksum() {\n return this.#configChecksum;\n }\n\n get mspVersion() {\n return this.#telemetry?.backyard.mspVersion;\n }\n\n // whether the cached telemetry may be out of date\n get telemetryDirty() {\n return this.#telemetryDirty;\n }\n\n get config() {\n if (this.#mspConfig === null) {\n throw new OmniLogicError(\"No config cached; call refresh() first\");\n }\n return this.#mspConfig;\n }\n\n get telemetry() {\n if (this.#telemetry === null) {\n throw new OmniLogicError(\"No telemetry cached; call refresh() first\");\n }\n return this.#telemetry;\n }\n\n get inventory() {\n if (this.#inventory === null) {\n throw new OmniLogicError(\"No config cached; call refresh() first\");\n }\n return this.#inventory;\n }\n\n #adopt(config: MSPConfig) {\n this.#mspConfig = config;\n const inventory = discover(config);\n this.#inventory = inventory;\n const listed = new Set(inventory.bodies.map((b) => b.systemId));\n for (const bow of config.backyard.bodiesOfWater) {\n if (!listed.has(bow.systemId)) {\n omnilogicLog.debug(\"body without an id left out of the inventory\", {\n name: bow.name,\n });\n }\n }\n const unknown: string[] = [];\n for (const body of inventory.bodies) {\n const presences: Record<string, Presence> = {};\n for (const path of INVENTORY_PATHS) {\n const presence = presenceAt(body, path);\n presences[path] = presence;\n if (presence === \"unknown\") {\n unknown.push(`${body.systemId}:${path}`);\n }\n }\n omnilogicLog.trace(\"body inventory\", {\n poolId: body.systemId,\n ...presences,\n });\n }\n omnilogicLog.debug(\"inventory discovered\", {\n bodies: inventory.bodies.length,\n unknown: unknown.length === 0 ? \"none\" : unknown.join(\",\"),\n });\n }\n\n /**\n * Send a command to the controller\n */\n command<N extends CommandName>(\n name: N,\n params: CommandParams<N> | undefined,\n options: CommandOptions & { raw: true },\n ): Promise<string | undefined>;\n command<N extends CommandName>(\n name: N,\n ...rest: CommandParams<N> extends Record<string, never>\n ? [params?: CommandParams<N>, options?: CommandOptions]\n : [params: CommandParams<N>, options?: CommandOptions]\n ): Promise<CommandResult<N>>;\n command<N extends CommandName>(\n name: N,\n params: CommandParams<N>,\n options?: CommandOptions,\n ): Promise<CommandResult<N>>;\n command<N extends CommandName>(\n name: CommandName extends N ? N : never,\n params: Record<string, number | string> | undefined,\n options: CommandOptions & { raw: true },\n ): Promise<string | undefined>;\n command<N extends CommandName>(\n name: CommandName extends N ? N : never,\n params?: Record<string, number | string>,\n options?: CommandOptions,\n ): Promise<unknown>;\n async command(\n name: CommandName,\n params: Record<string, number | string> = {},\n options: CommandOptions = {},\n ): Promise<unknown> {\n if (options.force) {\n omnilogicLog.trace(\"checks skipped (forced)\", { command: name });\n } else {\n if (this.#telemetry === null) {\n omnilogicLog.debug(\"no config or telemetry cached, refreshing first\", {\n command: name,\n });\n this.#firstRefresh ??= this.refresh().finally(() => {\n this.#firstRefresh = null;\n });\n await this.#firstRefresh;\n }\n this.#gate(name, params);\n }\n this.#warnValveWhilePumping(name, params);\n const send = async () => {\n if (!options.force) {\n this.#refuseOutsideNormalOperation(name);\n }\n const result = await this.#send(name, params, options);\n if (COMMANDS[name].read !== true) {\n this.#writes++;\n this.#telemetryDirty = true;\n omnilogicLog.trace(\"telemetry marked dirty\", { command: name });\n }\n return result;\n };\n\n const { verify } = options;\n if (verify === undefined) {\n return send();\n }\n const attempts = Math.max(1, options.attempts ?? 1);\n const timeoutMs = options.timeoutMs ?? 0;\n const pollMs = options.pollMs ?? 4000;\n omnilogicLog.trace(\"verifying\", {\n command: name,\n attempts,\n timeoutMs,\n pollMs,\n });\n let sendError: unknown;\n for (let attempt = 1; attempt <= attempts; attempt++) {\n sendError = undefined;\n const result = await send().catch((error: unknown) => {\n if (\n error instanceof OmniValidationError ||\n error instanceof SystemStateError\n ) {\n throw error;\n }\n omnilogicLog.warn(\"send failed; checking whether it took\", {\n command: name,\n attempt,\n error,\n });\n sendError = error;\n return undefined;\n });\n const deadline = Date.now() + timeoutMs;\n for (let check = 1; ; check++) {\n try {\n await this.refresh({ refetch: true, force: options.force });\n } catch (error) {\n omnilogicLog.warn(\"refresh failed, so the command is unverified\", {\n command: name,\n attempt,\n check,\n error,\n });\n throw new CommandFailedError({\n message: options.failure ?? `${name} failed`,\n command: name,\n attempts: attempt,\n cause: error,\n });\n }\n if (verified(verify)) {\n omnilogicLog.trace(\"verified\", { command: name, attempt, check });\n // a read with no reply has nothing to return\n if (sendError !== undefined && COMMANDS[name].response) {\n throw sendError;\n }\n return result;\n }\n if (Date.now() >= deadline) {\n omnilogicLog.trace(\"not verified within the timeout\", {\n command: name,\n attempt,\n check,\n });\n break;\n }\n omnilogicLog.trace(\"not verified yet, polling\", {\n command: name,\n attempt,\n check,\n pollMs,\n });\n await setTimeout(pollMs);\n }\n }\n throw new CommandFailedError({\n message: options.failure ?? `${name} failed`,\n command: name,\n attempts,\n cause: sendError,\n });\n }\n\n async #send(\n name: CommandName,\n params: Record<string, number | string>,\n options: CommandOptions,\n ) {\n const spec = COMMANDS[name];\n if (spec.caveat !== undefined) {\n const { effect, alternative } = spec.caveat;\n commandLog.warn(\n `${name} ${effect}`,\n alternative === undefined ? undefined : { alternative },\n );\n }\n commandLog.debug(name, { opcode: spec.opcode, ...params });\n\n const { xml, unknown } = buildCommandXml(name, params);\n for (const key of unknown) {\n commandLog.warn(\"ignoring unknown parameter (not in spec)\", {\n name,\n key,\n });\n }\n commandLog.trace(\"payload\", {\n name,\n bytes: Buffer.byteLength(xml, \"utf8\"),\n xml,\n });\n\n const started = Date.now();\n const operation = {\n timings: options.timings,\n settle: spec.settle,\n attempts:\n spec.read === true ? (options.attempts ?? this.#readAttempts) : 1,\n reply: spec.response?.opcode,\n };\n try {\n if (spec.response) {\n const responseXml = await this.#protocol.sendAndReceive(\n spec.opcode,\n xml,\n operation,\n );\n commandLog.trace(\"response\", {\n name,\n ms: Date.now() - started,\n xml: responseXml,\n });\n\n const parsed = parseCommandResponse(spec.response, responseXml);\n if (!parsed.ok) {\n throw new OmniLogicError(\n parsed.actual === 0\n ? `${name} answered nothing`\n : `${name} answered with ${parsed.actual} parameters, not the ${parsed.expected} of ${spec.response.name}`,\n );\n }\n\n if (options.raw) {\n return responseXml === \"\" ? undefined : responseXml;\n }\n\n commandLog.debug(\"parsed response\", { name, ...parsed.params });\n return parsed.params;\n }\n\n const message = await this.#protocol.sendMessage(\n spec.opcode,\n xml,\n operation,\n );\n commandLog.debug(\"sent\", {\n name,\n id: message.id,\n ms: Date.now() - started,\n });\n return undefined;\n } catch (error) {\n commandLog.debug(\"failed\", { name, opcode: spec.opcode, error });\n throw error;\n }\n }\n\n async #fetch(name: keyof typeof SWITCH_OPCODE) {\n omnilogicLog.debug(name);\n const started = Date.now();\n const xml = await this.#protocol.sendAndReceive(\n SWITCH_OPCODE[name],\n buildMessageXml(name),\n { attempts: this.#readAttempts, reply: FETCH_REPLY[name] },\n );\n omnilogicLog.debug(\"fetched\", {\n name,\n ms: Date.now() - started,\n bytes: Buffer.byteLength(xml, \"utf8\"),\n });\n return xml;\n }\n\n fetchConfig<R extends boolean = false>(\n options?: ReadOptions<R>,\n ): Fetched<R, MSPConfig>;\n async fetchConfig(options: ReadOptions = {}) {\n const xmlResponse = await this.#fetch(\"RequestConfiguration\");\n if (options.raw) {\n return xmlResponse;\n }\n const config = parseConfig(xmlResponse);\n omnilogicLog.trace(\"config parsed\", {\n checksum: config.checksum,\n bodies: config.backyard.bodiesOfWater.length,\n schedules: config.schedules.length,\n favorites: config.favorites.length,\n themes: config.themes.length,\n });\n return config;\n }\n\n fetchTelemetry<R extends boolean = false>(\n options?: ReadOptions<R>,\n ): Fetched<R, Telemetry>;\n async fetchTelemetry(options: ReadOptions = {}) {\n const xmlResponse = await this.#fetch(\"GetTelemetry\");\n if (options.raw) {\n return xmlResponse;\n }\n const telemetry = parseTelemetry(xmlResponse);\n omnilogicLog.trace(\"telemetry parsed\", {\n version: telemetry.version,\n checksum: telemetry.backyard.configChksum,\n bodies: telemetry.bodiesOfWater.length,\n });\n return telemetry;\n }\n\n fetchSysInfo<R extends boolean = false>(\n options?: ReadOptions<R>,\n ): Fetched<R, SysInfo>;\n async fetchSysInfo(options: ReadOptions = {}) {\n const xmlResponse = await this.#fetch(\"GetSysInfo\");\n if (options.raw) {\n return xmlResponse;\n }\n const info = parseSysInfo(xmlResponse);\n omnilogicLog.trace(\"sysinfo parsed\", {\n components: info.components.length,\n });\n return info;\n }\n\n // a command that moves a valve, or a relay command aimed at a valve actuator\n #movesAValve(name: CommandName, params: Record<string, unknown>) {\n if (ACTUATES_VALVE.has(name)) {\n return true;\n }\n if (name !== \"SetUIEquipmentCmd\" && name !== \"SetUIRelayCmd\") {\n return false;\n }\n const equipmentId = numberOf(params.equipmentId);\n const type = stringOf(\n equipmentId === undefined\n ? undefined\n : findBySystemId(this.#mspConfig, equipmentId)?.type,\n );\n return type === \"RLY_VALVE_ACTUATOR\" || type === \"RLY_SMART_VALVE_ACTUATOR\";\n }\n\n #warnValveWhilePumping(name: CommandName, params: Record<string, unknown>) {\n if (!this.#movesAValve(name, params)) {\n return;\n }\n const poolId = numberOf(params.poolId);\n if (poolId === undefined) {\n return;\n }\n let pumpOn = false;\n try {\n pumpOn = this.backyard.body(poolId)?.filter?.isOn ?? false;\n } catch {\n omnilogicLog.trace(\"no telemetry to check the pump against\", {\n command: name,\n poolId,\n });\n }\n if (!pumpOn) {\n return;\n }\n omnilogicLog.warn(\n \"valve command sent while the filter pump looks to be running, which can deadhead it\",\n { command: name, poolId },\n );\n }\n\n #refuseUnsupportedFirmware(telemetry: Telemetry) {\n const version = telemetry.backyard.mspVersion;\n if (version === undefined || !MSP_VERSION_SHAPE.test(version)) {\n omnilogicLog.debug(\"firmware version unrecognized, not checked\", {\n version,\n });\n return;\n }\n // string order is version order\n if (version < MIN_MSP_VERSION) {\n throw new FirmwareTooOldError({ version, minimum: MIN_MSP_VERSION });\n }\n omnilogicLog.trace(\"firmware supported\", { version });\n }\n\n #refuseOutsideNormalOperation(name: CommandName) {\n const { state } = this.telemetry.backyard;\n if (COMMANDS[name].read !== true && !isRunning(state)) {\n throw new SystemStateError({ command: name, backyardState: state });\n }\n }\n\n #gate(name: CommandName, params: Record<string, unknown>) {\n const inventory = this.inventory;\n\n const { requires = [], target } = COMMANDS[name];\n if (requires.length === 0 && target === undefined) {\n return;\n }\n omnilogicLog.trace(\"gate\", { command: name, requires, target });\n\n if (inventory.bodies.length === 0) {\n omnilogicLog.debug(\"no bodies discovered; sending anyway\", {\n command: name,\n });\n return;\n }\n\n const poolId = numberOf(params.poolId);\n if (poolId === undefined) {\n omnilogicLog.trace(\"no poolId to gate on; sending\", { command: name });\n return;\n }\n\n const body = inventory.bodies.find((b) => b.systemId === poolId);\n if (body === undefined) {\n throw new EquipmentNotInstalledError({\n command: name,\n requirement: \"body\",\n poolId,\n inventory,\n });\n }\n\n const refuse = (requirement: string, hint?: string) => {\n throw new EquipmentNotInstalledError({\n command: name,\n requirement,\n poolId,\n hint,\n inventory,\n });\n };\n\n for (const path of requires) {\n const presence = presenceAt(body, path);\n if (presence === \"absent\") {\n refuse(path);\n }\n if (presence === \"unknown\") {\n omnilogicLog.debug(\"inventory unknown; sending anyway\", {\n command: name,\n path,\n poolId,\n });\n }\n }\n\n // refuses the parent's id where the part's is wanted\n if (target === undefined || !target.includes(\".\")) {\n return;\n }\n const dot = target.indexOf(\".\");\n const ownerPath = target.slice(0, dot);\n if (!isInventoryPath(ownerPath)) {\n return;\n }\n const wanted = systemIdAt(body, target);\n const owner = systemIdAt(body, ownerPath);\n if (\n wanted !== undefined &&\n owner !== undefined &&\n params.equipmentId === owner &&\n owner !== wanted\n ) {\n refuse(\n target,\n `it takes the ${target.slice(dot + 1)} id (${wanted}), not the ${ownerPath}'s (${owner})`,\n );\n }\n }\n\n /**\n * Fetch and cache the latest telemetry and config\n */\n async refresh(\n options: {\n // refetch when a write marked the cached telemetry stale, default true\n ifDirty?: boolean;\n // seconds the cached telemetry may be old, 0 reads every time, default the session's cache TTL\n ifOlderThan?: number;\n // fetch even when the cached config and telemetry are fresh\n refetch?: boolean;\n // fetch even from a controller the SDK would refuse\n force?: boolean;\n } = {},\n ) {\n const {\n ifDirty = true,\n ifOlderThan = this.#cacheTTL,\n refetch = false,\n force = false,\n } = options;\n\n const now = Date.now() / 1000;\n const age = now - this.#telemetryLastUpdated;\n const isStale = age >= ifOlderThan;\n const dirty = ifDirty && this.#telemetryDirty;\n const shouldUpdate = refetch || dirty || isStale;\n\n if (!shouldUpdate) {\n omnilogicLog.trace(\"refresh skipped (not dirty, not stale)\", {\n ageSeconds: Math.round(age),\n ttlSeconds: ifOlderThan,\n });\n return;\n }\n\n omnilogicLog.debug(\"refresh starting\", {\n refetch,\n dirty,\n stale: isStale,\n ageSeconds: Math.round(age),\n });\n const started = Date.now();\n const seq = ++this.#refreshStarted;\n const writes = this.#writes;\n const telemetry = await this.fetchTelemetry();\n if (!force) {\n this.#refuseUnsupportedFirmware(telemetry);\n }\n const newChecksum = telemetry.backyard.configChksum;\n omnilogicLog.trace(\"telemetry fetched\", {\n ms: Date.now() - started,\n checksum: newChecksum,\n });\n\n if (\n refetch ||\n this.#mspConfig === null ||\n newChecksum !== this.#configChecksum\n ) {\n omnilogicLog.debug(\"fetching config\", {\n reason: refetch\n ? \"refetching\"\n : this.#mspConfig === null\n ? \"none cached\"\n : \"checksum changed\",\n checksum: newChecksum,\n previous: this.#configChecksum,\n });\n const configStarted = Date.now();\n const config = await this.fetchConfig();\n this.#configChecksum = newChecksum;\n omnilogicLog.trace(\"config fetched\", { ms: Date.now() - configStarted });\n this.#adopt(config);\n } else {\n omnilogicLog.trace(\"config checksum unchanged, skipping fetch\", {\n checksum: newChecksum,\n });\n }\n if (this.#telemetryCachedFrom > seq) {\n omnilogicLog.trace(\"telemetry superseded by a later refresh\", {\n ms: Date.now() - started,\n });\n return;\n }\n this.#telemetry = telemetry;\n this.#telemetryCachedFrom = seq;\n this.#telemetryLastUpdated = now;\n this.#telemetryDirty = this.#writes !== writes;\n }\n}\n"],"mappings":"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CjE,GAAG;CACH,GAAG;CACH,GAAG;AACL;AAEA,MAAa,qBAA6C;CACxD,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,KAAK;AACP;AASA,MAAa,qBAAoC;CAC/C;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ,EACN,GAAG,oBACL;CACF;CACA;EACE,OAAO;EACP,QAAQ,EACN,GAAG,mBACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ,EACN,GAAG,uBACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ,EACN,GAAG,aACL;CACF;AACF;AAEA,MAAa,qBAAoC;CAC/C;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;CACA;EACE,OAAO;EACP,QAAQ;GACN,GAAG;GACH,GAAG;EACL;CACF;AACF;AAEA,MAAa,cAAsC;CACjD,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;AACL;AAEA,MAAa,eAAuC;CAClD,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,IAAI;AACN;AAEA,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"}