{"openapi":"3.1.0","info":{"title":"Juicy Battery Fleet API","version":"1.0.0"},"paths":{"/v1/health":{"get":{"tags":["Health"],"summary":"Health Check","description":"Basic health check.","operationId":"health_check_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/v1/health/live":{"get":{"tags":["Health"],"summary":"Liveness Check","description":"Kubernetes liveness probe.","operationId":"liveness_check_v1_health_live_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/v1/health/ready":{"get":{"tags":["Health"],"summary":"Readiness Check","description":"Kubernetes readiness probe - checks database connectivity.","operationId":"readiness_check_v1_health_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadinessResponse"}}}}}}},"/v1/auth/me":{"get":{"tags":["Authentication"],"summary":"Get Me","description":"Get the current authenticated user.","operationId":"get_me_v1_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/auth/google/token":{"post":{"tags":["Authentication"],"summary":"Google Token Exchange","description":"Exchange a Google ID token for API access/refresh tokens.\n\nCalled by the web frontend (NextAuth) after Google OAuth sign-in.\nVerifies the ID token with Google, then creates/updates the user\nand returns API JWTs.","operationId":"google_token_exchange_v1_auth_google_token_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleTokenRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/google/login":{"get":{"tags":["Authentication"],"summary":"Google Login","description":"Initiate Google OAuth2 login.","operationId":"google_login_v1_auth_google_login_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/auth/google/callback":{"get":{"tags":["Authentication"],"summary":"Google Callback","description":"Handle Google OAuth2 callback.","operationId":"google_callback_v1_auth_google_callback_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}}}}},"/v1/auth/microsoft/login":{"get":{"tags":["Authentication"],"summary":"Microsoft Login","description":"Initiate Microsoft OAuth2 login.","operationId":"microsoft_login_v1_auth_microsoft_login_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/auth/microsoft/callback":{"get":{"tags":["Authentication"],"summary":"Microsoft Callback","description":"Handle Microsoft OAuth2 callback.","operationId":"microsoft_callback_v1_auth_microsoft_callback_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}}}}},"/v1/auth/refresh":{"post":{"tags":["Authentication"],"summary":"Refresh Token","description":"Refresh an access token.","operationId":"refresh_token_v1_auth_refresh_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/auth/battery/register":{"post":{"tags":["Authentication"],"summary":"Register Battery","description":"Register a new battery and get an API key.\n\nNote: In production, this should require admin authentication.\nThe API key is only shown once - save it securely.\n\nIf the battery already exists, a new API key is generated (for development convenience).\nUses upsert (ON CONFLICT) to handle concurrent registrations safely.","operationId":"register_battery_v1_auth_battery_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryRegister"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryRegistrationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries":{"get":{"tags":["Batteries"],"summary":"List Batteries","description":"List batteries (slim view). For full detail incl. metadata, address,\nhardware limits and target SOC, GET /v1/batteries/{id}.","operationId":"list_batteries_v1_batteries_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_BatteryListItem_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}":{"get":{"tags":["Batteries"],"summary":"Get Battery","description":"Get a battery by ID.","operationId":"get_battery_v1_batteries__battery_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Batteries"],"summary":"Update Battery","description":"Update a battery. Accessible by Admin, Operator, and Installer roles.","operationId":"update_battery_v1_batteries__battery_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Batteries"],"summary":"Delete Battery","description":"Delete (decommission) a battery.","operationId":"delete_battery_v1_batteries__battery_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/status":{"get":{"tags":["Batteries"],"summary":"Get Battery Status","description":"Get quick status for a battery.","operationId":"get_battery_status_v1_batteries__battery_id__status_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/tariff":{"put":{"tags":["Batteries"],"summary":"Assign Battery Tariff","description":"Assign or unassign a tariff to a battery.","operationId":"assign_battery_tariff_v1_batteries__battery_id__tariff_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryTariffAssign"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/counterfactual-tariff":{"put":{"tags":["Batteries"],"summary":"Assign Battery Counterfactual Tariff","description":"Set or clear the counterfactual tariff used as the savings comparison baseline.","operationId":"assign_battery_counterfactual_tariff_v1_batteries__battery_id__counterfactual_tariff_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryCounterfactualTariffAssign"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/control":{"get":{"tags":["Batteries"],"summary":"Get Battery Control","description":"Get battery control mode and settings.\n\nThis endpoint is used by agents to fetch the current control mode.\nNo authentication required for agent access.","operationId":"get_battery_control_v1_batteries__battery_id__control_get","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryControlResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Batteries"],"summary":"Set Battery Control","description":"Set battery control mode.\n\nControl modes:\n- auto: Controller decides based on tariff/time\n- force_charge: Charge at specified power for duration, then revert\n- force_discharge: Discharge at specified power for duration, then revert\n- manual_idle: Force idle indefinitely\n- manual_self_use: Force self-use indefinitely","operationId":"set_battery_control_v1_batteries__battery_id__control_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryControlSet"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryControlResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/tariff-schedule":{"get":{"tags":["Batteries"],"summary":"Get Tariff Schedule","description":"Get tariff schedule for battery AUTO mode decisions.\n\nThis endpoint is used by agents to fetch tariff timing info.\nNo authentication required for agent access.","operationId":"get_tariff_schedule_v1_batteries__battery_id__tariff_schedule_get","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffScheduleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/control/revert":{"post":{"tags":["Batteries"],"summary":"Revert Battery Control","description":"Revert battery control mode after force mode expires.\n\nThis endpoint is called by agents when they detect force mode has expired.\nNo authentication required for agent access.","operationId":"revert_battery_control_v1_batteries__battery_id__control_revert_post","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryControlResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/agent-settings":{"get":{"tags":["Batteries"],"summary":"Get Agent Settings","description":"Get agent settings for a battery. Admin only.","operationId":"get_agent_settings_v1_batteries__battery_id__agent_settings_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Batteries"],"summary":"Update Agent Settings","description":"Update agent settings for a battery. Admin only.\n\nValidates each setting, stores only non-default values in metadata,\ncreates an audit log entry, and notifies the agent via WebSocket.","operationId":"update_agent_settings_v1_batteries__battery_id__agent_settings_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSettingsUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/setup":{"put":{"tags":["Commissioning"],"summary":"Setup Battery","description":"Set minimum required details for commissioning.\n\nSets inverter type and location. Notifies agent of config change.","operationId":"setup_battery_v1_batteries__battery_id__setup_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommissioningSetup"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/commission/test":{"post":{"tags":["Commissioning"],"summary":"Run Commissioning Test","description":"Start a single commissioning test step in the background.\n\nReturns immediately. Poll battery metadata for progress.","operationId":"run_commissioning_test_v1_batteries__battery_id__commission_test_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommissioningTestRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Run Commissioning Test V1 Batteries  Battery Id  Commission Test Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/commission/test-all":{"post":{"tags":["Commissioning"],"summary":"Run All Commissioning Tests","description":"Start all commissioning tests as a background task.\n\nReturns immediately. Poll battery metadata for progress:\nbattery.metadata.commissioning_test_run.status = running|completed|failed|error","operationId":"run_all_commissioning_tests_v1_batteries__battery_id__commission_test_all_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Run All Commissioning Tests V1 Batteries  Battery Id  Commission Test All Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/commission":{"post":{"tags":["Commissioning"],"summary":"Commission Battery","description":"Mark battery as commissioned (add to fleet).\n\nValidates that minimum required fields are set, then marks\nthe battery as commissioned and resets control mode to auto.","operationId":"commission_battery_v1_batteries__battery_id__commission_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/decommission":{"post":{"tags":["Commissioning"],"summary":"Decommission Battery","description":"Decommission a battery (remove from fleet, back to setup state).\n\nResets commissioned status so the battery can be re-tested and\nre-commissioned. Does not delete the battery or its telemetry.","operationId":"decommission_battery_v1_batteries__battery_id__decommission_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatteryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/logs/stream":{"get":{"tags":["Logs"],"summary":"Stream Agent Logs","description":"Stream agent logs via Server-Sent Events.\n\nSends a request_logs command to the agent, then relays log lines\nback to the client as SSE events.","operationId":"stream_agent_logs_v1_batteries__battery_id__logs_stream_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}},{"name":"level","in":"query","required":false,"schema":{"type":"string","pattern":"^(DEBUG|INFO|WARNING|ERROR)$","default":"INFO","title":"Level"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/logs/download":{"get":{"tags":["Logs"],"summary":"Download Agent Logs","description":"Download the agent's full log ring buffer as a text file.","operationId":"download_agent_logs_v1_batteries__battery_id__logs_download_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/logs/snapshot":{"post":{"tags":["Logs"],"summary":"Store Log Snapshot","description":"Store agent log snapshot for offline viewing.\n\nCalled by the agent periodically to persist recent logs\nso they're available even when the agent is disconnected.","operationId":"store_log_snapshot_v1_batteries__battery_id__logs_snapshot_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Snapshot"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Store Log Snapshot V1 Batteries  Battery Id  Logs Snapshot Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/logs/offline":{"get":{"tags":["Logs"],"summary":"Get Offline Logs","description":"Return the most recent agent log snapshot for this battery.\n\nThe agent posts a rolling buffer of ~500 lines to /logs/snapshot. Those\nlines used to be bundled into battery.metadata; now they live behind this\nendpoint so the default battery detail response stays small.","operationId":"get_offline_logs_v1_batteries__battery_id__logs_offline_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Offline Logs V1 Batteries  Battery Id  Logs Offline Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batteries/{battery_id}/logs":{"get":{"tags":["Logs"],"summary":"Get Offline Logs","description":"Return the most recent agent log snapshot for this battery.\n\nThe agent posts a rolling buffer of ~500 lines to /logs/snapshot. Those\nlines used to be bundled into battery.metadata; now they live behind this\nendpoint so the default battery detail response stays small.","operationId":"get_offline_logs_v1_batteries__battery_id__logs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Offline Logs V1 Batteries  Battery Id  Logs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups":{"get":{"tags":["Groups"],"summary":"List Groups","description":"List all groups with pagination.","operationId":"list_groups_v1_groups_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"group_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Group Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_GroupResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Groups"],"summary":"Create Group","description":"Create a new group.","operationId":"create_group_v1_groups_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/{group_id}":{"get":{"tags":["Groups"],"summary":"Get Group","description":"Get a group by ID.","operationId":"get_group_v1_groups__group_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Groups"],"summary":"Update Group","description":"Update a group.","operationId":"update_group_v1_groups__group_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Groups"],"summary":"Delete Group","description":"Delete a group.","operationId":"delete_group_v1_groups__group_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Group Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/groups/{group_id}/batteries":{"post":{"tags":["Groups"],"summary":"Add Batteries To Group","description":"Add batteries to a group.","operationId":"add_batteries_to_group_v1_groups__group_id__batteries_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupBatteriesRequest"}}}},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Groups"],"summary":"Remove Batteries From Group","description":"Remove batteries from a group.","operationId":"remove_batteries_from_group_v1_groups__group_id__batteries_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupBatteriesRequest"}}}},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Groups"],"summary":"Get Group Batteries","description":"Get all batteries in a group.","operationId":"get_group_batteries_v1_groups__group_id__batteries_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{},"title":"Response Get Group Batteries V1 Groups  Group Id  Batteries Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tariffs":{"get":{"tags":["Tariffs"],"summary":"List Tariffs","description":"List tariffs with pagination and filtering.","operationId":"list_tariffs_v1_tariffs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"tariff_type","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/TariffType"},{"type":"null"}],"title":"Tariff Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_TariffResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Tariffs"],"summary":"Create Tariff","description":"Create a custom tariff.","operationId":"create_tariff_v1_tariffs_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tariffs/{tariff_id}":{"get":{"tags":["Tariffs"],"summary":"Get Tariff","description":"Get a tariff by ID.","operationId":"get_tariff_v1_tariffs__tariff_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tariff_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tariff Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Tariffs"],"summary":"Update Tariff","description":"Update a tariff.","operationId":"update_tariff_v1_tariffs__tariff_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tariff_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tariff Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Tariffs"],"summary":"Delete Tariff","description":"Delete a tariff.","operationId":"delete_tariff_v1_tariffs__tariff_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"tariff_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Tariff Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/commands":{"get":{"tags":["Commands"],"summary":"List Commands","description":"List commands with pagination and filtering.","operationId":"list_commands_v1_commands_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"target_type","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/TargetType"},{"type":"null"}],"title":"Target Type"}},{"name":"target_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Target Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/CommandStatus"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_CommandResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Commands"],"summary":"Create Command","description":"Send a command to a battery or group.","operationId":"create_command_v1_commands_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/commands/{command_id}":{"get":{"tags":["Commands"],"summary":"Get Command","description":"Get a command by ID.","operationId":"get_command_v1_commands__command_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"command_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Command Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/commands/{command_id}/cancel":{"post":{"tags":["Commands"],"summary":"Cancel Command","description":"Cancel a pending command.","operationId":"cancel_command_v1_commands__command_id__cancel_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"command_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Command Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/commands/{command_id}/status":{"put":{"tags":["Commands"],"summary":"Update Command Status","description":"Update command status (used by agents to acknowledge commands).\n\nThis endpoint does not require authentication as it's called by\nbattery agents which use API keys for telemetry but need to\nacknowledge commands.","operationId":"update_command_status_v1_commands__command_id__status_put","parameters":[{"name":"command_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Command Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandStatusUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/commands/{command_id}/results":{"get":{"tags":["Commands"],"summary":"Get Command Results","description":"Get results for a command (for group commands).","operationId":"get_command_results_v1_commands__command_id__results_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"command_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Command Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommandResultResponse"},"title":"Response Get Command Results V1 Commands  Command Id  Results Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schedules/base/battery/{battery_id}":{"get":{"tags":["Schedules"],"summary":"Get Battery Base Mode","description":"Get the base mode for a battery.","operationId":"get_battery_base_mode_v1_schedules_base_battery__battery_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/BaseModeResponse"},{"type":"null"}],"title":"Response Get Battery Base Mode V1 Schedules Base Battery  Battery Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Schedules"],"summary":"Set Battery Base Mode","description":"Set the base mode for a battery.","operationId":"set_battery_base_mode_v1_schedules_base_battery__battery_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BaseModeUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BaseModeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schedules/base/group/{group_id}":{"get":{"tags":["Schedules"],"summary":"Get Group Base Mode","description":"Get the base mode for a group.","operationId":"get_group_base_mode_v1_schedules_base_group__group_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/BaseModeResponse"},{"type":"null"}],"title":"Response Get Group Base Mode V1 Schedules Base Group  Group Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Schedules"],"summary":"Set Group Base Mode","description":"Set the base mode for a group.","operationId":"set_group_base_mode_v1_schedules_base_group__group_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Group Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BaseModeUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BaseModeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schedules/recurring":{"get":{"tags":["Schedules"],"summary":"List Recurring Schedules","description":"List recurring schedules.","operationId":"list_recurring_schedules_v1_schedules_recurring_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"}},{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Group Id"}},{"name":"enabled_only","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Enabled Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RecurringScheduleResponse"},"title":"Response List Recurring Schedules V1 Schedules Recurring Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Schedules"],"summary":"Create Recurring Schedule","description":"Create a recurring schedule.","operationId":"create_recurring_schedule_v1_schedules_recurring_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecurringScheduleCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecurringScheduleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schedules/recurring/{schedule_id}":{"get":{"tags":["Schedules"],"summary":"Get Recurring Schedule","description":"Get a recurring schedule by ID.","operationId":"get_recurring_schedule_v1_schedules_recurring__schedule_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Schedule Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecurringScheduleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Schedules"],"summary":"Update Recurring Schedule","description":"Update a recurring schedule.","operationId":"update_recurring_schedule_v1_schedules_recurring__schedule_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Schedule Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecurringScheduleUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecurringScheduleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Schedules"],"summary":"Delete Recurring Schedule","description":"Delete a recurring schedule.","operationId":"delete_recurring_schedule_v1_schedules_recurring__schedule_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Schedule Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schedules/events":{"get":{"tags":["Schedules"],"summary":"List One Off Events","description":"List one-off events.","operationId":"list_one_off_events_v1_schedules_events_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"}},{"name":"group_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Group Id"}},{"name":"include_expired","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Expired"}},{"name":"include_cancelled","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Cancelled"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OneOffEventResponse"},"title":"Response List One Off Events V1 Schedules Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Schedules"],"summary":"Create One Off Event","description":"Create a one-off event (highest priority override).","operationId":"create_one_off_event_v1_schedules_events_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OneOffEventCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OneOffEventResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schedules/events/{event_id}":{"get":{"tags":["Schedules"],"summary":"Get One Off Event","description":"Get a one-off event by ID.","operationId":"get_one_off_event_v1_schedules_events__event_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OneOffEventResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Schedules"],"summary":"Cancel One Off Event","description":"Cancel a one-off event.","operationId":"cancel_one_off_event_v1_schedules_events__event_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Event Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schedules/battery/{battery_id}/active":{"get":{"tags":["Schedules"],"summary":"Get Battery Active Schedule","description":"Get the currently active schedule for a battery.","operationId":"get_battery_active_schedule_v1_schedules_battery__battery_id__active_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ActiveScheduleResponse"},{"type":"null"}],"title":"Response Get Battery Active Schedule V1 Schedules Battery  Battery Id  Active Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schedules/group/{group_id}/active":{"get":{"tags":["Schedules"],"summary":"Get Group Active Schedule","description":"Get the currently active schedule for a group.","operationId":"get_group_active_schedule_v1_schedules_group__group_id__active_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Group Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ActiveScheduleResponse"},{"type":"null"}],"title":"Response Get Group Active Schedule V1 Schedules Group  Group Id  Active Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schedules/battery/{battery_id}/timeline":{"get":{"tags":["Schedules"],"summary":"Get Battery Schedule Timeline","description":"Get the schedule timeline for a battery for the next N hours.","operationId":"get_battery_schedule_timeline_v1_schedules_battery__battery_id__timeline_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleTimelineEntry"},"title":"Response Get Battery Schedule Timeline V1 Schedules Battery  Battery Id  Timeline Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/schedules/group/{group_id}/timeline":{"get":{"tags":["Schedules"],"summary":"Get Group Schedule Timeline","description":"Get the schedule timeline for a group for the next N hours.","operationId":"get_group_schedule_timeline_v1_schedules_group__group_id__timeline_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"group_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Group Id"}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":168,"minimum":1,"default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleTimelineEntry"},"title":"Response Get Group Schedule Timeline V1 Schedules Group  Group Id  Timeline Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/telemetry/batch":{"post":{"tags":["Telemetry"],"summary":"Ingest Telemetry Batch","description":"Ingest a batch of telemetry readings from a battery.\n\nThis endpoint is called by battery agents to upload telemetry data.\nThe authenticated battery can only submit telemetry for itself.","operationId":"ingest_telemetry_batch_v1_telemetry_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelemetryBatch"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Ingest Telemetry Batch V1 Telemetry Batch Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/telemetry/query":{"get":{"tags":["Telemetry"],"summary":"Query Telemetry","description":"Query telemetry data with time-based aggregation.\n\nNote: This is a simplified implementation. In production, you would use\nTimescaleDB's time_bucket function for efficient aggregation.","operationId":"query_telemetry_v1_telemetry_query_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"query","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}},{"name":"start_time","in":"query","required":true,"schema":{"type":"string","format":"date-time","title":"Start Time"}},{"name":"end_time","in":"query","required":true,"schema":{"type":"string","format":"date-time","title":"End Time"}},{"name":"interval","in":"query","required":true,"schema":{"type":"string","title":"Interval"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelemetryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/telemetry/agent-audit":{"post":{"tags":["Telemetry"],"summary":"Report Agent Audit","description":"Report an audit event from an agent (e.g. meter offline/recovered).","operationId":"report_agent_audit_v1_telemetry_agent_audit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentAuditEvent"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Report Agent Audit V1 Telemetry Agent Audit Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/audit":{"get":{"tags":["Audit"],"summary":"List Audit Entries","description":"List audit entries with filtering.","operationId":"list_audit_entries_v1_audit_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}},{"name":"severity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/AuditSeverity"},{"type":"null"}],"title":"Severity"}},{"name":"min_severity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/AuditSeverity"},{"type":"null"}],"description":"Show entries at or above this severity. `warning` returns warning+error; `error` returns error only. Overrides `severity` if both are set.","title":"Min Severity"},"description":"Show entries at or above this severity. `warning` returns warning+error; `error` returns error only. Overrides `severity` if both are set."},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/AuditCategory"},{"type":"null"}],"title":"Category"}},{"name":"battery_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"}},{"name":"message_code","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Code"}},{"name":"actor_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Actor Type"}},{"name":"actor_email","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Actor Email"}},{"name":"start_time","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Start Time"}},{"name":"end_time","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"End Time"}},{"name":"unacknowledged_only","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Unacknowledged Only"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AuditEntryResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/audit/summary":{"get":{"tags":["Audit"],"summary":"Get Summary","description":"Get audit summary for alert badge.","operationId":"get_summary_v1_audit_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditSummaryResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/audit/acknowledge":{"post":{"tags":["Audit"],"summary":"Acknowledge Entries","description":"Acknowledge audit entries.","operationId":"acknowledge_entries_v1_audit_acknowledge_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditAcknowledgeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Acknowledge Entries V1 Audit Acknowledge Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/audit/slack-settings":{"get":{"tags":["Audit"],"summary":"Get Slack Settings","description":"Current Slack alert configuration for the audit page toggles.","operationId":"get_slack_settings_v1_audit_slack_settings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SlackSettingsResponse"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["Audit"],"summary":"Update Slack Settings","description":"Flip the per-severity Slack toggles. Applies immediately (cache is\ninvalidated on write; the next audit event picks up the new value).","operationId":"update_slack_settings_v1_audit_slack_settings_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SlackSettingsUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SlackSettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/audit/slack-test":{"post":{"tags":["Audit"],"summary":"Slack Test","description":"Send a one-shot test message to the configured Slack webhook.\n\nBypasses the per-severity toggles — the whole point is validating that\nthe webhook works. Returns the HTTP status from Slack.","operationId":"slack_test_v1_audit_slack_test_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Slack Test V1 Audit Slack Test Post"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/reports/{battery_id}/tariff-periods":{"get":{"tags":["Reports"],"summary":"Get Tariff Periods","description":"Get tariff periods for a battery, ordered by most recent first.","operationId":"get_tariff_periods_v1_reports__battery_id__tariff_periods_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TariffPeriodResponse"},"title":"Response Get Tariff Periods V1 Reports  Battery Id  Tariff Periods Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reports/{battery_id}/tariff-periods/{period_id}":{"put":{"tags":["Reports"],"summary":"Update Tariff Period","description":"Update a tariff period's start/end dates (restricted to midnight boundaries).","operationId":"update_tariff_period_v1_reports__battery_id__tariff_periods__period_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}},{"name":"period_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Period Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffPeriodUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffPeriodResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Reports"],"summary":"Delete Tariff Period","description":"Delete a tariff period.","operationId":"delete_tariff_period_v1_reports__battery_id__tariff_periods__period_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}},{"name":"period_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Period Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reports/{battery_id}/energy-report":{"get":{"tags":["Reports"],"summary":"Get Energy Report","description":"Get per-minute-of-day energy report for a tariff period.","operationId":"get_energy_report_v1_reports__battery_id__energy_report_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}},{"name":"period_id","in":"query","required":true,"schema":{"type":"string","format":"uuid","title":"Period Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnergyReportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/reports/fleet-summary":{"get":{"tags":["Reports"],"summary":"Get Fleet Summary","description":"Get fleet-wide energy savings summary from active tariff periods.","operationId":"get_fleet_summary_v1_reports_fleet_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetReportResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/reports/rte":{"get":{"tags":["Reports"],"summary":"Get Rte Report","description":"Fleet RTE report from meter cumulative-counter deltas.\n\nFor each battery, finds the first telemetry row whose meter readings\nwere recorded within 2 hours of each daily anchor (snapshot_time on\neach day from start_date through end_date+1). The first and last\nfound readings give the period delta; missing interior anchors flag\na row as `partial`.","operationId":"get_rte_report_v1_reports_rte_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"start_date","in":"query","required":true,"schema":{"type":"string","format":"date","description":"First day to include (inclusive)","title":"Start Date"},"description":"First day to include (inclusive)"},{"name":"end_date","in":"query","required":true,"schema":{"type":"string","format":"date","description":"Last day to include (inclusive)","title":"End Date"},"description":"Last day to include (inclusive)"},{"name":"snapshot_time","in":"query","required":false,"schema":{"type":"string","format":"time","description":"Local time of day used as the snapshot anchor (default 05:00).","default":"05:00:00","title":"Snapshot Time"},"description":"Local time of day used as the snapshot anchor (default 05:00)."},{"name":"tz","in":"query","required":false,"schema":{"type":"string","description":"IANA timezone in which snapshot_time is interpreted.","default":"Europe/London","title":"Tz"},"description":"IANA timezone in which snapshot_time is interpreted."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RteReportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users":{"get":{"tags":["Users"],"summary":"List Users","description":"List all users (admin only).","operationId":"list_users_v1_users_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserResponse"},"title":"Response List Users V1 Users Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Users"],"summary":"Create User","description":"Create a new user (admin only).\n\nThe user will be created with a placeholder oauth_sub. The real value\nis filled on their first OAuth login.","operationId":"create_user_v1_users_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/{user_id}":{"put":{"tags":["Users"],"summary":"Update User","description":"Update a user's role or active status (admin only).","operationId":"update_user_v1_users__user_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Users"],"summary":"Delete User","description":"Soft-delete a user by deactivating them (admin only).","operationId":"delete_user_v1_users__user_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers":{"get":{"tags":["Fleet Providers"],"summary":"List Fleet Providers","description":"List available fleet providers.","operationId":"list_fleet_providers_v1_fleet_providers_get","parameters":[{"name":"include_local","in":"query","required":false,"schema":{"type":"boolean","description":"Include the 'local' provider","default":false,"title":"Include Local"},"description":"Include the 'local' provider"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FleetProviderResponse"},"title":"Response List Fleet Providers V1 Fleet Providers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/{slug}":{"patch":{"tags":["Fleet Providers"],"summary":"Update Fleet Provider","description":"Update a fleet provider's config (admin only).","operationId":"update_fleet_provider_v1_fleet_providers__slug__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Data"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FleetProviderResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/batteries/{battery_id}/provider":{"get":{"tags":["Fleet Providers"],"summary":"Get Battery Provider","description":"Get the current provider assignment for a battery.","operationId":"get_battery_provider_v1_fleet_providers_batteries__battery_id__provider_get","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ProviderAssignmentResponse"},{"type":"null"}],"title":"Response Get Battery Provider V1 Fleet Providers Batteries  Battery Id  Provider Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Fleet Providers"],"summary":"Assign Battery Provider","description":"Assign a fleet provider to a battery.","operationId":"assign_battery_provider_v1_fleet_providers_batteries__battery_id__provider_put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignProviderRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderAssignmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Fleet Providers"],"summary":"Remove Battery Provider","description":"Remove provider assignment, revert to local control.","operationId":"remove_battery_provider_v1_fleet_providers_batteries__battery_id__provider_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/{slug}/check-asset-id/{asset_id}":{"get":{"tags":["Fleet Providers"],"summary":"Check Asset Id","description":"Check if an external_asset_id is available for a provider and suggest the next one.","operationId":"check_asset_id_v1_fleet_providers__slug__check_asset_id__asset_id__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Check Asset Id V1 Fleet Providers  Slug  Check Asset Id  Asset Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/batteries/{battery_id}/provider/status":{"post":{"tags":["Fleet Providers"],"summary":"Update Provider Status","description":"Agent reports provider connection state.","operationId":"update_provider_status_v1_fleet_providers_batteries__battery_id__provider_status_post","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderStatusUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Provider Status V1 Fleet Providers Batteries  Battery Id  Provider Status Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/batteries/{battery_id}/provider/events":{"post":{"tags":["Fleet Providers"],"summary":"Create Provider Events","description":"Agent reports provider events.","operationId":"create_provider_events_v1_fleet_providers_batteries__battery_id__provider_events_post","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProviderEventCreate"},"title":"Events"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Provider Events V1 Fleet Providers Batteries  Battery Id  Provider Events Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/{slug}/summary":{"get":{"tags":["Fleet Providers"],"summary":"Get Provider Summary","description":"Get aggregate stats for a provider dashboard.","operationId":"get_provider_summary_v1_fleet_providers__slug__summary_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderSummaryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/{slug}/devices":{"get":{"tags":["Fleet Providers"],"summary":"Get Provider Devices","description":"List devices assigned to a provider with their status.","operationId":"get_provider_devices_v1_fleet_providers__slug__devices_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ProviderDeviceResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/{slug}/events":{"get":{"tags":["Fleet Providers"],"summary":"Get Provider Events","description":"Get event log for a provider.","operationId":"get_provider_events_v1_fleet_providers__slug__events_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Page Size"}},{"name":"event_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by event type (comma-separated for multiple)","title":"Event Type"},"description":"Filter by event type (comma-separated for multiple)"},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":720,"minimum":1,"description":"Lookback hours (default 7 days)","default":168,"title":"Hours"},"description":"Lookback hours (default 7 days)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ProviderEventResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/batteries/{battery_id}/provider/provision":{"post":{"tags":["Fleet Providers"],"summary":"Provision Battery Provider","description":"Provision the battery with its assigned external provider via gRPC.\n\nLooks up the battery + active assignment, calls\n`ProvisioningService.provisionNewAsset` on the provider's endpoint, stores\nthe returned asset_id, and marks the assignment as provisioned.","operationId":"provision_battery_provider_v1_fleet_providers_batteries__battery_id__provider_provision_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Re-provision even if already provisioned","default":false,"title":"Force"},"description":"Re-provision even if already provisioned"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderAssignmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/fake-centrica/send-control":{"post":{"tags":["Fleet Providers"],"summary":"Fake Centrica Send Control","description":"Push a control message to agents connected to the fake Centrica server.\n\nBody:\n    asset_id (int): The external_asset_id of the battery (e.g. 1)\n    control_type (str): \"flex_planning\" | \"sensor_setpoints\" | \"clear\"\n    payload (dict): Proto fields as camelCase JSON — use {} for \"clear\"\n\nExamples:\n    Flex self-consumption for the next 2h:\n      {\"asset_id\": 1, \"control_type\": \"flex_planning\", \"payload\": {\n        \"flexBlocks\": [{\"startTime\": 1234567890000, \"endTime\": 1234575090000,\n          \"flexStrategy\": {\"behindTheMeterStrategy\": {\"selfConsumptionMode\": {}}}}]}}\n\n    Charge at 3kW for 30 minutes:\n      {\"asset_id\": 1, \"control_type\": \"sensor_setpoints\", \"payload\": {\n        \"setpoints\": [{\"sensorId\": 8879365, \"setpoint\": 3000,\n          \"startTime\": 1234567890000, \"endTime\": 1234569690000}]}}\n\n    Clear all controls:\n      {\"asset_id\": 1, \"control_type\": \"clear\", \"payload\": {}}","operationId":"fake_centrica_send_control_v1_fleet_providers_fake_centrica_send_control_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Fake Centrica Send Control V1 Fleet Providers Fake Centrica Send Control Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/fleet-providers/fake-centrica/measurements/{asset_id}":{"get":{"tags":["Fleet Providers"],"summary":"Fake Centrica Measurements","description":"Return recent measurements received from an asset by the fake Centrica server.","operationId":"fake_centrica_measurements_v1_fleet_providers_fake_centrica_measurements__asset_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"integer","title":"Asset Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Fake Centrica Measurements V1 Fleet Providers Fake Centrica Measurements  Asset Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/fake-centrica/controls":{"get":{"tags":["Fleet Providers"],"summary":"Fake Centrica Controls","description":"Return control history from the fake Centrica server, with block status.","operationId":"fake_centrica_controls_v1_fleet_providers_fake_centrica_controls_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"asset_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Asset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{},"title":"Response Fake Centrica Controls V1 Fleet Providers Fake Centrica Controls Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/fleet-providers/fake-centrica/connected":{"get":{"tags":["Fleet Providers"],"summary":"Fake Centrica Connected","description":"Return open stream count and assets with recent measurements.","operationId":"fake_centrica_connected_v1_fleet_providers_fake_centrica_connected_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Fake Centrica Connected V1 Fleet Providers Fake Centrica Connected Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/api-tokens":{"get":{"tags":["API Tokens"],"summary":"List Api Tokens","description":"List all API tokens (admin only). Secrets are never returned.","operationId":"list_api_tokens_v1_api_tokens_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ApiTokenResponse"},"type":"array","title":"Response List Api Tokens V1 Api Tokens Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["API Tokens"],"summary":"Create Api Token","description":"Create a new API token. The plaintext token is returned exactly once.","operationId":"create_api_token_v1_api_tokens_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiTokenCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiTokenWithSecret"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/api-tokens/{token_id}":{"delete":{"tags":["API Tokens"],"summary":"Revoke Api Token","description":"Revoke an API token. Subsequent requests with it will be rejected.","operationId":"revoke_api_token_v1_api_tokens__token_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"token_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Token Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/optimiser/batteries":{"get":{"tags":["Optimiser"],"summary":"List My Batteries","description":"List batteries assigned to the calling partner.\n\nKeyset-paginated on `(serial_number, id)`. Follow `next_cursor` until\nit is `null`. `modified_since` filters to batteries whose row has\nchanged since the given ISO timestamp — partners syncing incrementally\nshould pass their last successful sync time.","operationId":"list_my_batteries_v1_optimiser_batteries_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"modified_since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Modified Since"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPage_PartnerBatteryResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/optimiser/batteries/{battery_id}":{"get":{"tags":["Optimiser"],"summary":"Get My Battery","operationId":"get_my_battery_v1_optimiser_batteries__battery_id__get","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerBatteryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/optimiser/batteries/{battery_id}/telemetry":{"get":{"tags":["Optimiser"],"summary":"Get My Battery Telemetry","description":"Recent raw telemetry rows for the partner's battery.","operationId":"get_my_battery_telemetry_v1_optimiser_batteries__battery_id__telemetry_get","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get My Battery Telemetry V1 Optimiser Batteries  Battery Id  Telemetry Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/optimiser/batteries/{battery_id}/flex-plan":{"get":{"tags":["Optimiser"],"summary":"Get My Battery Flex Plan","operationId":"get_my_battery_flex_plan_v1_optimiser_batteries__battery_id__flex_plan_get","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlexPlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Optimiser"],"summary":"Submit My Battery Flex Plan","operationId":"submit_my_battery_flex_plan_v1_optimiser_batteries__battery_id__flex_plan_post","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlexPlanSubmit"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlexPlanSubmitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Optimiser"],"summary":"Clear My Battery Flex Plan","operationId":"clear_my_battery_flex_plan_v1_optimiser_batteries__battery_id__flex_plan_delete","parameters":[{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/optimiser/partners":{"get":{"tags":["Optimiser Admin"],"summary":"List Partners","operationId":"list_partners_v1_admin_optimiser_partners_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/OptimiserPartnerResponse"},"type":"array","title":"Response List Partners V1 Admin Optimiser Partners Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Optimiser Admin"],"summary":"Create Partner","operationId":"create_partner_v1_admin_optimiser_partners_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimiserPartnerCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimiserPartnerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/admin/optimiser/partners/{partner_id}":{"patch":{"tags":["Optimiser Admin"],"summary":"Update Partner","operationId":"update_partner_v1_admin_optimiser_partners__partner_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimiserPartnerUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimiserPartnerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/optimiser/partners/{partner_id}/certificates":{"get":{"tags":["Optimiser Admin"],"summary":"List Partner Certificates","operationId":"list_partner_certificates_v1_admin_optimiser_partners__partner_id__certificates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OptimiserCertificateResponse"},"title":"Response List Partner Certificates V1 Admin Optimiser Partners  Partner Id  Certificates Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Optimiser Admin"],"summary":"Issue Partner Certificate","operationId":"issue_partner_certificate_v1_admin_optimiser_partners__partner_id__certificates_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimiserCertificateSignRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimiserCertificateIssued"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/optimiser/partners/{partner_id}/certificates/{cert_id}":{"delete":{"tags":["Optimiser Admin"],"summary":"Revoke Partner Certificate","operationId":"revoke_partner_certificate_v1_admin_optimiser_partners__partner_id__certificates__cert_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}},{"name":"cert_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Cert Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/optimiser/partners/{partner_id}/batteries":{"get":{"tags":["Optimiser Admin"],"summary":"List Partner Batteries","operationId":"list_partner_batteries_v1_admin_optimiser_partners__partner_id__batteries_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OptimiserAssignmentResponse"},"title":"Response List Partner Batteries V1 Admin Optimiser Partners  Partner Id  Batteries Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Optimiser Admin"],"summary":"Assign Batteries","operationId":"assign_batteries_v1_admin_optimiser_partners__partner_id__batteries_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimiserAssignmentCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OptimiserAssignmentResponse"},"title":"Response Assign Batteries V1 Admin Optimiser Partners  Partner Id  Batteries Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/optimiser/partners/{partner_id}/batteries/{battery_id}":{"delete":{"tags":["Optimiser Admin"],"summary":"Unassign Partner Battery","operationId":"unassign_partner_battery_v1_admin_optimiser_partners__partner_id__batteries__battery_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}},{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/optimiser/unassign-batteries":{"post":{"tags":["Optimiser Admin"],"summary":"Bulk Unassign Batteries","description":"Partner-agnostic bulk unassign — for each battery_id, find its active\noptimiser assignment (if any) and clear it. Idempotent: batteries that\naren't currently assigned are silently skipped.","operationId":"bulk_unassign_batteries_v1_admin_optimiser_unassign_batteries_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnassignBatteriesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Bulk Unassign Batteries V1 Admin Optimiser Unassign Batteries Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/admin/optimiser/partners/{partner_id}/batteries-as-partner":{"get":{"tags":["Optimiser Admin"],"summary":"Admin List Batteries As Partner","description":"Admin-bypass mirror of `GET /v1/optimiser/batteries` — same query\nparameters, same code path, same response shape. Exists so the partner\nE2E suite can verify cursor pagination without provisioning mTLS certs.","operationId":"admin_list_batteries_as_partner_v1_admin_optimiser_partners__partner_id__batteries_as_partner_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor"}},{"name":"modified_since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Modified Since"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPage_PartnerBatteryResponse_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/optimiser/partners/{partner_id}/batteries/{battery_id}/flex-plan":{"get":{"tags":["Optimiser Admin"],"summary":"Admin Get Partner Flex Plan","operationId":"admin_get_partner_flex_plan_v1_admin_optimiser_partners__partner_id__batteries__battery_id__flex_plan_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}},{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlexPlanResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Optimiser Admin"],"summary":"Admin Submit Partner Flex Plan","operationId":"admin_submit_partner_flex_plan_v1_admin_optimiser_partners__partner_id__batteries__battery_id__flex_plan_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}},{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlexPlanSubmit"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlexPlanSubmitResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Optimiser Admin"],"summary":"Admin Clear Partner Flex Plan","operationId":"admin_clear_partner_flex_plan_v1_admin_optimiser_partners__partner_id__batteries__battery_id__flex_plan_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Id"}},{"name":"battery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Battery Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/admin/optimiser/activity":{"get":{"tags":["Optimiser Admin"],"summary":"List Optimiser Activity","description":"Recent partner-API plan submissions across all partners.\n\nReturns the most-recently-submitted plans (one row per battery) joined\nto the partner and battery. Used by the Partner API provider page to\nshow a live activity feed.\n\nNOTE: Each battery has at most one row in `optimiser_flex_plans`\n(snapshot semantics — submits update the row in place and bump the\nrevision). So this is \"current plan per battery, ordered by recency\",\nnot \"every historical submission\". A separate audit table would be\nneeded for full history; out of scope here.","operationId":"list_optimiser_activity_v1_admin_optimiser_activity_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptimiserActivityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agent/optimiser/plan":{"get":{"tags":["Agent"],"summary":"Get My Plan","description":"Return active + future flex blocks for the calling battery.","operationId":"get_my_plan_v1_agent_optimiser_plan_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentFlexPlanResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/agent/hardware-specs":{"patch":{"tags":["Agent"],"summary":"Update Hardware Specs","description":"Update hardware specs for the calling battery.\n\nCalled by the agent after protocol reload discovers new capacity/power\nratings from the inverter, and on startup to report agent_version.\n/auth/battery/register also accepts the hardware fields on upsert but\nrotates the api_key as a side effect; this is the no-rotation update path.","operationId":"update_hardware_specs_v1_agent_hardware_specs_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HardwareSpecsUpdate"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}}},"components":{"schemas":{"ActiveScheduleResponse":{"properties":{"battery_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"},"group_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Group Id"},"active_layer":{"type":"integer","title":"Active Layer","description":"1=base, 2=recurring, 3=one-off"},"source_id":{"type":"string","format":"uuid","title":"Source Id"},"source_type":{"type":"string","title":"Source Type"},"mode":{"$ref":"#/components/schemas/OperatingMode"},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters"},"active_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Active Until","description":"When this schedule ends (None for base mode)"}},"type":"object","required":["battery_id","group_id","active_layer","source_id","source_type","mode","parameters"],"title":"ActiveScheduleResponse","description":"The currently active schedule for a target."},"AgentAuditEvent":{"properties":{"severity":{"type":"string","title":"Severity","default":"warning"},"category":{"type":"string","title":"Category","default":"status_change"},"message":{"type":"string","title":"Message"},"message_code":{"type":"string","title":"Message Code"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["message","message_code"],"title":"AgentAuditEvent","description":"Audit event reported by an agent."},"AgentFlexBlock":{"properties":{"start_time_ms":{"type":"integer","title":"Start Time Ms"},"end_time_ms":{"type":"integer","title":"End Time Ms"},"strategy":{"$ref":"#/components/schemas/FlexBlockStrategy"},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters"}},"type":"object","required":["start_time_ms","end_time_ms","strategy","parameters"],"title":"AgentFlexBlock","description":"Block shape returned to the agent (matches FlexBlockResponse)."},"AgentFlexPlanResponse":{"properties":{"revision":{"type":"integer","title":"Revision"},"submitted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Submitted At"},"blocks":{"items":{"$ref":"#/components/schemas/AgentFlexBlock"},"type":"array","title":"Blocks"}},"type":"object","required":["revision","submitted_at","blocks"],"title":"AgentFlexPlanResponse"},"AgentSettingsResponse":{"properties":{"current":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"number"},{"type":"boolean"},{"type":"string"}]},"type":"object","title":"Current"},"defaults":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"number"},{"type":"boolean"},{"type":"string"}]},"type":"object","title":"Defaults"},"validation":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Validation"},"categories":{"additionalProperties":{"items":{"type":"string"},"type":"array"},"type":"object","title":"Categories"},"restart_required":{"items":{"type":"string"},"type":"array","title":"Restart Required"}},"type":"object","required":["current","defaults","validation","categories","restart_required"],"title":"AgentSettingsResponse","description":"Full agent settings with current values, defaults, and validation metadata."},"AgentSettingsUpdate":{"properties":{"settings":{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"number"},{"type":"boolean"},{"type":"string"}]},"type":"object","title":"Settings"}},"type":"object","required":["settings"],"title":"AgentSettingsUpdate","description":"Partial update to agent settings. Only include keys being changed."},"ApiTokenCreate":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"scope":{"$ref":"#/components/schemas/ApiTokenScope"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["name","scope"],"title":"ApiTokenCreate","description":"Request body for creating a new API token."},"ApiTokenResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"token_prefix":{"type":"string","title":"Token Prefix"},"scope":{"$ref":"#/components/schemas/ApiTokenScope"},"created_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By User Id"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","token_prefix","scope","created_by_user_id","expires_at","revoked_at","last_used_at","created_at"],"title":"ApiTokenResponse","description":"Public view of an API token (no secret)."},"ApiTokenScope":{"type":"string","enum":["read","write","admin"],"title":"ApiTokenScope","description":"Scope a personal API token grants its bearer."},"ApiTokenWithSecret":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"token_prefix":{"type":"string","title":"Token Prefix"},"scope":{"$ref":"#/components/schemas/ApiTokenScope"},"created_by_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By User Id"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"token":{"type":"string","title":"Token"}},"type":"object","required":["id","name","token_prefix","scope","created_by_user_id","expires_at","revoked_at","last_used_at","created_at","token"],"title":"ApiTokenWithSecret","description":"One-time response on creation; includes the plaintext token."},"AssignProviderRequest":{"properties":{"provider_slug":{"type":"string","maxLength":50,"minLength":1,"title":"Provider Slug"},"external_asset_id":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"External Asset Id"},"credentials":{"additionalProperties":true,"type":"object","title":"Credentials"},"config_overrides":{"additionalProperties":true,"type":"object","title":"Config Overrides"}},"type":"object","required":["provider_slug"],"title":"AssignProviderRequest","description":"Request to assign a provider to a battery."},"AuditAcknowledgeRequest":{"properties":{"entry_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array"},{"type":"null"}],"title":"Entry Ids"},"before_timestamp":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Before Timestamp"}},"type":"object","title":"AuditAcknowledgeRequest","description":"Request to acknowledge audit entries."},"AuditCategory":{"type":"string","enum":["housekeeping","status_change","telemetry","system","command","commissioning"],"title":"AuditCategory","description":"Audit entry categories."},"AuditEntryResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"severity":{"$ref":"#/components/schemas/AuditSeverity"},"category":{"$ref":"#/components/schemas/AuditCategory"},"message":{"type":"string","title":"Message"},"message_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Code"},"actor_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Actor Type"},"actor_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Actor Email"},"battery_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"},"battery_serial":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Battery Serial"},"battery_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Battery Display Name"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"acknowledged":{"type":"boolean","title":"Acknowledged"},"acknowledged_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Acknowledged At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","timestamp","severity","category","message","acknowledged","created_at"],"title":"AuditEntryResponse","description":"Audit entry response schema."},"AuditSeverity":{"type":"string","enum":["info","warning","error"],"title":"AuditSeverity","description":"Audit entry severity levels."},"AuditSummaryResponse":{"properties":{"total_unacknowledged":{"type":"integer","title":"Total Unacknowledged"},"info_count":{"type":"integer","title":"Info Count"},"warning_count":{"type":"integer","title":"Warning Count"},"error_count":{"type":"integer","title":"Error Count"},"recent_warnings":{"type":"integer","title":"Recent Warnings"},"recent_errors":{"type":"integer","title":"Recent Errors"}},"type":"object","required":["total_unacknowledged","info_count","warning_count","error_count","recent_warnings","recent_errors"],"title":"AuditSummaryResponse","description":"Summary of audit entries for alert badge."},"BaseModeResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"battery_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"},"group_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Group Id"},"mode":{"$ref":"#/components/schemas/OperatingMode"},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","battery_id","group_id","mode","parameters","created_at","updated_at"],"title":"BaseModeResponse","description":"Schema for base mode response."},"BaseModeUpdate":{"properties":{"mode":{"$ref":"#/components/schemas/OperatingMode"},"parameters":{"$ref":"#/components/schemas/ScheduleParameters"}},"type":"object","required":["mode"],"title":"BaseModeUpdate","description":"Schema for setting the base mode."},"BatteryControlResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"serial_number":{"type":"string","title":"Serial Number"},"inverter_type":{"type":"string","title":"Inverter Type"},"control_mode":{"type":"string","title":"Control Mode"},"control_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Control Power Kw"},"control_duration_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Control Duration Seconds"},"control_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Control Expires At"},"control_previous_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Control Previous Mode"},"control_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Control Updated At"},"target_soc":{"type":"number","title":"Target Soc"},"has_tariff":{"type":"boolean","title":"Has Tariff"},"tariff_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tariff Name"},"auto_provider_slug":{"type":"string","title":"Auto Provider Slug","default":"local"},"provider_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Type"},"provider_endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Endpoint"},"provider_config":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Provider Config"},"provider_credentials":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Provider Credentials"},"external_asset_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Asset Id"}},"type":"object","required":["id","serial_number","inverter_type","control_mode","control_power_kw","control_duration_seconds","control_expires_at","control_previous_mode","control_updated_at","target_soc","has_tariff","tariff_name"],"title":"BatteryControlResponse","description":"Response showing battery control state."},"BatteryControlSet":{"properties":{"control_mode":{"$ref":"#/components/schemas/ControlMode"},"power_kw":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Power Kw","description":"Power for force charge/discharge"},"duration_seconds":{"anyOf":[{"type":"integer","maximum":86400.0,"exclusiveMinimum":0.0},{"type":"null"}],"title":"Duration Seconds","description":"Duration in seconds (max 24 hours)"}},"type":"object","required":["control_mode"],"title":"BatteryControlSet","description":"Schema for setting battery control mode."},"BatteryCounterfactualTariffAssign":{"properties":{"counterfactual_tariff_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Counterfactual Tariff Id","description":"Tariff ID to use as savings comparison baseline, or null to fall back to the assigned tariff"}},"type":"object","title":"BatteryCounterfactualTariffAssign","description":"Schema for assigning a counterfactual tariff to a battery."},"BatteryListItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"serial_number":{"type":"string","title":"Serial Number"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"manufacturer":{"type":"string","title":"Manufacturer"},"model":{"type":"string","title":"Model"},"inverter_type":{"$ref":"#/components/schemas/InverterType"},"agent_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Version"},"host_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Host Name"},"capacity_kwh":{"type":"number","title":"Capacity Kwh"},"max_power_kw":{"type":"number","title":"Max Power Kw"},"current_soc":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Soc"},"current_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Power Kw"},"status":{"$ref":"#/components/schemas/BatteryStatus"},"condition":{"type":"string","title":"Condition","default":"ok"},"last_seen":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Seen"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"country":{"type":"string","title":"Country"},"timezone":{"type":"string","title":"Timezone"},"group_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Group Ids"},"tariff_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Tariff Id"},"tariff_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tariff Name"},"control_mode":{"type":"string","title":"Control Mode","default":"auto"},"control_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Control Power Kw"},"control_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Control Expires At"},"control_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Control Updated At"},"auto_provider_slug":{"type":"string","title":"Auto Provider Slug","default":"local"},"commissioned":{"type":"boolean","title":"Commissioned","default":true}},"type":"object","required":["id","serial_number","manufacturer","model","inverter_type","capacity_kwh","max_power_kw","current_soc","current_power_kw","status","last_seen","city","country","timezone"],"title":"BatteryListItem","description":"Slim battery response for list endpoints.\n\nDrops heavy/uncommon fields: metadata, address/postal/lat/lon, firmware,\nmin/max SOC limits, target SOC, grid_connection_id, transient control\ndetail (duration_seconds, previous_mode), commissioning timestamps, and\ncreated_at/updated_at. Use `GET /v1/batteries/{id}` for the full record."},"BatteryRegister":{"properties":{"serial_number":{"type":"string","maxLength":100,"minLength":1,"title":"Serial Number"},"manufacturer":{"type":"string","maxLength":100,"minLength":1,"title":"Manufacturer"},"model":{"type":"string","maxLength":100,"minLength":1,"title":"Model"},"inverter_type":{"$ref":"#/components/schemas/InverterType"},"capacity_kwh":{"type":"number","minimum":0.0,"title":"Capacity Kwh"},"max_power_kw":{"type":"number","minimum":0.0,"title":"Max Power Kw"},"min_soc_percent":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Min Soc Percent","default":10.0},"max_soc_percent":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Max Soc Percent","default":100.0},"location":{"$ref":"#/components/schemas/LocationSchema"},"firmware_version":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Firmware Version"},"host_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Host Name","description":"Pi hostname"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["serial_number","manufacturer","model","inverter_type","capacity_kwh","max_power_kw","location"],"title":"BatteryRegister","description":"Schema for registering a new battery (from the battery itself)."},"BatteryRegistrationResponse":{"properties":{"battery":{"$ref":"#/components/schemas/BatteryResponse"},"api_key":{"type":"string","title":"Api Key","description":"API key - save this, it won't be shown again"}},"type":"object","required":["battery","api_key"],"title":"BatteryRegistrationResponse","description":"Response after battery registration, includes the API key (only shown once)."},"BatteryResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"serial_number":{"type":"string","title":"Serial Number"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"api_key_prefix":{"type":"string","title":"Api Key Prefix"},"manufacturer":{"type":"string","title":"Manufacturer"},"model":{"type":"string","title":"Model"},"inverter_type":{"$ref":"#/components/schemas/InverterType"},"firmware_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Firmware Version"},"agent_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Version"},"host_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Host Name"},"capacity_kwh":{"type":"number","title":"Capacity Kwh"},"max_power_kw":{"type":"number","title":"Max Power Kw"},"min_soc_percent":{"type":"number","title":"Min Soc Percent"},"max_soc_percent":{"type":"number","title":"Max Soc Percent"},"current_soc":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Soc"},"current_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Power Kw"},"status":{"$ref":"#/components/schemas/BatteryStatus"},"condition":{"type":"string","title":"Condition","default":"ok"},"last_seen":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Seen"},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"country":{"type":"string","title":"Country"},"postal_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Postal Code"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude"},"timezone":{"type":"string","title":"Timezone"},"grid_connection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grid Connection Id"},"group_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Group Ids"},"tariff_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Tariff Id"},"tariff_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tariff Name"},"counterfactual_tariff_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Counterfactual Tariff Id"},"counterfactual_tariff_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Counterfactual Tariff Name"},"control_mode":{"type":"string","title":"Control Mode","default":"auto"},"control_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Control Power Kw"},"control_duration_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Control Duration Seconds"},"control_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Control Expires At"},"control_previous_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Control Previous Mode"},"control_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Control Updated At"},"target_soc":{"type":"number","title":"Target Soc","default":100.0},"auto_provider_slug":{"type":"string","title":"Auto Provider Slug","default":"local"},"commissioned":{"type":"boolean","title":"Commissioned","default":true},"commissioned_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Commissioned At"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","serial_number","api_key_prefix","manufacturer","model","inverter_type","firmware_version","capacity_kwh","max_power_kw","min_soc_percent","max_soc_percent","current_soc","current_power_kw","status","last_seen","address","city","state","country","postal_code","latitude","longitude","timezone","metadata","created_at","updated_at"],"title":"BatteryResponse","description":"Schema for battery response."},"BatteryStatus":{"type":"string","enum":["online","offline","charging","discharging","idle","fault"],"title":"BatteryStatus","description":"Battery operating status."},"BatteryStatusResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"serial_number":{"type":"string","title":"Serial Number"},"status":{"$ref":"#/components/schemas/BatteryStatus"},"current_soc":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Soc"},"current_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Power Kw"},"last_seen":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Seen"}},"type":"object","required":["id","serial_number","status","current_soc","current_power_kw","last_seen"],"title":"BatteryStatusResponse","description":"Quick status response for a battery."},"BatteryTariffAssign":{"properties":{"tariff_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Tariff Id","description":"Tariff ID to assign, or null to unassign"}},"type":"object","title":"BatteryTariffAssign","description":"Schema for assigning a tariff to a battery."},"BatteryUpdate":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Display Name"},"manufacturer":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Manufacturer"},"model":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Model"},"inverter_type":{"anyOf":[{"$ref":"#/components/schemas/InverterType"},{"type":"null"}]},"min_soc_percent":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Min Soc Percent"},"max_soc_percent":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Max Soc Percent"},"firmware_version":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Firmware Version"},"location":{"anyOf":[{"$ref":"#/components/schemas/LocationSchema"},{"type":"null"}]},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","title":"BatteryUpdate","description":"Schema for updating a battery."},"CommandCreate":{"properties":{"target_type":{"$ref":"#/components/schemas/TargetType"},"target_id":{"type":"string","format":"uuid","title":"Target Id"},"command_type":{"$ref":"#/components/schemas/CommandType"},"parameters":{"$ref":"#/components/schemas/CommandParameters"}},"type":"object","required":["target_type","target_id","command_type"],"title":"CommandCreate","description":"Schema for creating a command."},"CommandParameters":{"properties":{"power_kw":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Power Kw","description":"Power in kW"},"duration_minutes":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Duration Minutes","description":"Duration in minutes"},"target_soc":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Target Soc","description":"Target state of charge (%)"}},"type":"object","title":"CommandParameters","description":"Parameters for a command."},"CommandResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"target_type":{"$ref":"#/components/schemas/TargetType"},"target_id":{"type":"string","format":"uuid","title":"Target Id"},"command_type":{"$ref":"#/components/schemas/CommandType"},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters"},"status":{"$ref":"#/components/schemas/CommandStatus"},"dispatched_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Dispatched At"},"executed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Executed At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"expanded_battery_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Expanded Battery Ids"},"created_by_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","target_type","target_id","command_type","parameters","status","dispatched_at","executed_at","completed_at","error_message","expanded_battery_ids","created_by_id","created_at","updated_at"],"title":"CommandResponse","description":"Schema for command response."},"CommandResultResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"command_id":{"type":"string","format":"uuid","title":"Command Id"},"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"status":{"$ref":"#/components/schemas/CommandStatus"},"executed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Executed At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"},"response_data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Response Data"}},"type":"object","required":["id","command_id","battery_id","status","executed_at","completed_at","error_message","response_data"],"title":"CommandResultResponse","description":"Schema for command result per battery."},"CommandStatus":{"type":"string","enum":["pending","dispatched","executing","completed","failed","cancelled"],"title":"CommandStatus","description":"Command execution status."},"CommandStatusUpdate":{"properties":{"status":{"$ref":"#/components/schemas/CommandStatus"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"}},"type":"object","required":["status"],"title":"CommandStatusUpdate","description":"Schema for updating command status (used by agents)."},"CommandType":{"type":"string","enum":["discharge","charge","self_use","idle"],"title":"CommandType","description":"Type of command to execute."},"CommissioningSetup":{"properties":{"inverter_type":{"$ref":"#/components/schemas/InverterType"},"location":{"$ref":"#/components/schemas/LocationSchema"}},"type":"object","required":["inverter_type","location"],"title":"CommissioningSetup","description":"Minimum required details for commissioning a battery."},"CommissioningTestRequest":{"properties":{"step":{"$ref":"#/components/schemas/CommissioningTestStep"},"power_kw":{"type":"number","maximum":5.0,"exclusiveMinimum":0.0,"title":"Power Kw","default":1.0},"duration_seconds":{"type":"integer","maximum":120.0,"exclusiveMinimum":0.0,"title":"Duration Seconds","default":60}},"type":"object","required":["step"],"title":"CommissioningTestRequest","description":"Request to run a single commissioning test step."},"CommissioningTestStep":{"type":"string","enum":["charge","discharge","self_use","idle"],"title":"CommissioningTestStep","description":"Steps in the commissioning test sequence."},"ControlMode":{"type":"string","enum":["auto","force_charge","force_discharge","manual_idle","manual_self_use"],"title":"ControlMode","description":"Battery control mode - how the operating mode is decided."},"CursorPage_PartnerBatteryResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/PartnerBatteryResponse"},"type":"array","title":"Data"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"has_more":{"type":"boolean","title":"Has More","default":false}},"type":"object","required":["data"],"title":"CursorPage[PartnerBatteryResponse]"},"EnergyReportResponse":{"properties":{"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"period":{"$ref":"#/components/schemas/TariffPeriodResponse"},"summary":{"$ref":"#/components/schemas/EnergyReportSummary"},"data":{"items":{"$ref":"#/components/schemas/MinuteOfDayPoint"},"type":"array","title":"Data"},"counterfactual_tariff_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Counterfactual Tariff Name"},"counterfactual_tariff_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Counterfactual Tariff Type"},"counterfactual_flat_price_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Counterfactual Flat Price P"},"counterfactual_off_peak_price_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Counterfactual Off Peak Price P"},"counterfactual_peak_price_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Counterfactual Peak Price P"}},"type":"object","required":["battery_id","period","summary","data"],"title":"EnergyReportResponse","description":"Full energy report for a tariff period."},"EnergyReportSummary":{"properties":{"period_days":{"type":"integer","title":"Period Days"},"total_import_kwh":{"type":"number","title":"Total Import Kwh"},"off_peak_import_kwh":{"type":"number","title":"Off Peak Import Kwh"},"peak_import_kwh":{"type":"number","title":"Peak Import Kwh"},"off_peak_cost_p":{"type":"number","title":"Off Peak Cost P"},"peak_cost_p":{"type":"number","title":"Peak Cost P"},"total_cost_p":{"type":"number","title":"Total Cost P"},"estimated_no_battery_cost_p":{"type":"number","title":"Estimated No Battery Cost P"},"estimated_savings_p":{"type":"number","title":"Estimated Savings P"},"battery_charge_kwh":{"type":"number","title":"Battery Charge Kwh"},"battery_discharge_kwh":{"type":"number","title":"Battery Discharge Kwh"},"total_solar_kwh":{"type":"number","title":"Total Solar Kwh"},"total_household_kwh":{"type":"number","title":"Total Household Kwh"},"total_export_kwh":{"type":"number","title":"Total Export Kwh"},"solar_self_consumption_pct":{"type":"number","title":"Solar Self Consumption Pct"}},"type":"object","required":["period_days","total_import_kwh","off_peak_import_kwh","peak_import_kwh","off_peak_cost_p","peak_cost_p","total_cost_p","estimated_no_battery_cost_p","estimated_savings_p","battery_charge_kwh","battery_discharge_kwh","total_solar_kwh","total_household_kwh","total_export_kwh","solar_self_consumption_pct"],"title":"EnergyReportSummary","description":"Summary statistics for an energy report period."},"FleetBatterySummary":{"properties":{"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"serial_number":{"type":"string","title":"Serial Number"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"tariff_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tariff Name"},"period_days":{"type":"integer","title":"Period Days"},"total_import_kwh":{"type":"number","title":"Total Import Kwh"},"estimated_savings_p":{"type":"number","title":"Estimated Savings P"},"battery_charge_kwh":{"type":"number","title":"Battery Charge Kwh"},"battery_discharge_kwh":{"type":"number","title":"Battery Discharge Kwh"}},"type":"object","required":["battery_id","serial_number","display_name","tariff_name","period_days","total_import_kwh","estimated_savings_p","battery_charge_kwh","battery_discharge_kwh"],"title":"FleetBatterySummary","description":"Per-battery summary within the fleet report."},"FleetProviderResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"display_name":{"type":"string","title":"Display Name"},"provider_type":{"type":"string","title":"Provider Type"},"endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endpoint"},"auth_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Auth Type"},"config":{"additionalProperties":true,"type":"object","title":"Config"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","slug","display_name","provider_type","endpoint","auth_type","config","is_active"],"title":"FleetProviderResponse","description":"Response schema for a fleet provider."},"FleetReportResponse":{"properties":{"total_batteries":{"type":"integer","title":"Total Batteries"},"total_savings_p":{"type":"number","title":"Total Savings P"},"total_import_kwh":{"type":"number","title":"Total Import Kwh"},"total_off_peak_import_kwh":{"type":"number","title":"Total Off Peak Import Kwh"},"total_peak_import_kwh":{"type":"number","title":"Total Peak Import Kwh"},"total_battery_charge_kwh":{"type":"number","title":"Total Battery Charge Kwh"},"total_battery_discharge_kwh":{"type":"number","title":"Total Battery Discharge Kwh"},"batteries":{"items":{"$ref":"#/components/schemas/FleetBatterySummary"},"type":"array","title":"Batteries"}},"type":"object","required":["total_batteries","total_savings_p","total_import_kwh","total_off_peak_import_kwh","total_peak_import_kwh","total_battery_charge_kwh","total_battery_discharge_kwh","batteries"],"title":"FleetReportResponse","description":"Fleet-wide energy savings summary."},"FlexBlockResponse":{"properties":{"start_time_ms":{"type":"integer","title":"Start Time Ms"},"end_time_ms":{"type":"integer","title":"End Time Ms"},"strategy":{"$ref":"#/components/schemas/FlexBlockStrategy"},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters"},"seq":{"type":"integer","title":"Seq"}},"type":"object","required":["start_time_ms","end_time_ms","strategy","parameters","seq"],"title":"FlexBlockResponse"},"FlexBlockStrategy":{"type":"string","enum":["self_consumption","fixed_power_setpoint","fixed_power_direction"],"title":"FlexBlockStrategy","description":"Strategies supported by the optimiser flex-block API in v1."},"FlexBlockSubmit":{"properties":{"start_time_ms":{"type":"integer","minimum":0.0,"title":"Start Time Ms"},"end_time_ms":{"type":"integer","minimum":0.0,"title":"End Time Ms"},"strategy":{"$ref":"#/components/schemas/FlexBlockStrategy"},"setpoint_w":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Setpoint W","description":"For fixed_power_setpoint: +charge, -discharge (asset convention)"},"direction":{"anyOf":[{"type":"string","enum":["charge","discharge"]},{"type":"null"}],"title":"Direction","description":"For fixed_power_direction: which direction to run at max power"},"max_power_w":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Max Power W","description":"For fixed_power_direction: ceiling (defaults to battery max)"}},"type":"object","required":["start_time_ms","end_time_ms","strategy"],"title":"FlexBlockSubmit","description":"One block in a submitted plan."},"FlexPlanResponse":{"properties":{"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"revision":{"type":"integer","title":"Revision"},"submitted_at":{"type":"string","format":"date-time","title":"Submitted At"},"horizon_end_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Horizon End Ms"},"blocks":{"items":{"$ref":"#/components/schemas/FlexBlockResponse"},"type":"array","title":"Blocks"}},"type":"object","required":["battery_id","revision","submitted_at","horizon_end_ms","blocks"],"title":"FlexPlanResponse"},"FlexPlanSubmit":{"properties":{"blocks":{"items":{"$ref":"#/components/schemas/FlexBlockSubmit"},"type":"array","title":"Blocks"}},"type":"object","title":"FlexPlanSubmit","description":"Full snapshot of the plan for a battery."},"FlexPlanSubmitResponse":{"properties":{"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"revision":{"type":"integer","title":"Revision"},"accepted_block_count":{"type":"integer","title":"Accepted Block Count"},"effective_at":{"type":"string","format":"date-time","title":"Effective At"}},"type":"object","required":["battery_id","revision","accepted_block_count","effective_at"],"title":"FlexPlanSubmitResponse"},"GoogleTokenRequest":{"properties":{"id_token":{"type":"string","title":"Id Token"}},"type":"object","required":["id_token"],"title":"GoogleTokenRequest","description":"Exchange a Google ID token for API JWTs."},"GroupBatteriesRequest":{"properties":{"battery_ids":{"items":{"type":"string","format":"uuid"},"type":"array","minItems":1,"title":"Battery Ids"}},"type":"object","required":["battery_ids"],"title":"GroupBatteriesRequest","description":"Request to add/remove batteries from a group."},"GroupCreate":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"group_type":{"$ref":"#/components/schemas/GroupType"},"parent_group_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Group Id"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["name","group_type"],"title":"GroupCreate","description":"Schema for creating a group."},"GroupResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"group_type":{"$ref":"#/components/schemas/GroupType"},"parent_group_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Group Id"},"battery_count":{"type":"integer","title":"Battery Count","default":0},"total_capacity_kwh":{"type":"number","title":"Total Capacity Kwh","default":0.0},"aggregate_soc":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Aggregate Soc"},"aggregate_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Aggregate Power Kw"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","description","group_type","parent_group_id","metadata","created_at","updated_at"],"title":"GroupResponse","description":"Schema for group response."},"GroupType":{"type":"string","enum":["location","customer","virtual","grid_service"],"title":"GroupType","description":"Type of battery grouping."},"GroupUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"group_type":{"anyOf":[{"$ref":"#/components/schemas/GroupType"},{"type":"null"}]},"parent_group_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Group Id"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","title":"GroupUpdate","description":"Schema for updating a group."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HardwareSpecsUpdate":{"properties":{"capacity_kwh":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Capacity Kwh"},"max_power_kw":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Max Power Kw"},"agent_version":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Agent Version"},"host_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Host Name"}},"type":"object","title":"HardwareSpecsUpdate"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status"},"version":{"type":"string","title":"Version","default":"1.0.0"}},"type":"object","required":["status"],"title":"HealthResponse","description":"Health check response."},"InverterType":{"type":"string","enum":["sunsynk_ecco","solax_x1_hybrid_g4","foxess_h1_g2","foxess_kh","simulated","none"],"title":"InverterType","description":"Supported inverter types."},"LocationSchema":{"properties":{"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"country":{"type":"string","title":"Country"},"postal_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Postal Code"},"latitude":{"anyOf":[{"type":"number","maximum":90.0,"minimum":-90.0},{"type":"null"}],"title":"Latitude"},"longitude":{"anyOf":[{"type":"number","maximum":180.0,"minimum":-180.0},{"type":"null"}],"title":"Longitude"},"timezone":{"type":"string","title":"Timezone","default":"UTC"},"grid_connection_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Grid Connection Id"}},"type":"object","required":["country"],"title":"LocationSchema","description":"Location information."},"MinuteOfDayPoint":{"properties":{"minute_of_day":{"type":"integer","title":"Minute Of Day"},"time_label":{"type":"string","title":"Time Label"},"is_off_peak":{"type":"boolean","title":"Is Off Peak"},"avg_grid_import_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Grid Import Kw"},"avg_grid_export_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Grid Export Kw"},"avg_household_load_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Household Load Kw"},"avg_household_solar_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Household Solar Kw"},"avg_battery_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Battery Power Kw"},"avg_soc_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Soc Percent"},"reading_count":{"type":"integer","title":"Reading Count"}},"type":"object","required":["minute_of_day","time_label","is_off_peak","avg_grid_import_kw","avg_grid_export_kw","avg_household_load_kw","avg_household_solar_kw","avg_battery_power_kw","avg_soc_percent","reading_count"],"title":"MinuteOfDayPoint","description":"Energy data averaged for a single minute of the day across all days in a period."},"OAuthProvider":{"type":"string","enum":["google","microsoft"],"title":"OAuthProvider","description":"OAuth2 identity provider."},"OneOffEventCreate":{"properties":{"battery_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"},"group_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Group Id"},"mode":{"$ref":"#/components/schemas/OperatingMode"},"parameters":{"$ref":"#/components/schemas/ScheduleParameters"},"start_at":{"type":"string","format":"date-time","title":"Start At","description":"When to start (UTC)"},"duration_minutes":{"type":"integer","exclusiveMinimum":0.0,"title":"Duration Minutes","description":"Duration in minutes"}},"type":"object","required":["mode","start_at","duration_minutes"],"title":"OneOffEventCreate","description":"Schema for creating a one-off event."},"OneOffEventResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"battery_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"},"group_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Group Id"},"mode":{"$ref":"#/components/schemas/OperatingMode"},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters"},"start_at":{"type":"string","format":"date-time","title":"Start At"},"duration_minutes":{"type":"integer","title":"Duration Minutes"},"end_at":{"type":"string","format":"date-time","title":"End At"},"executed":{"type":"boolean","title":"Executed"},"cancelled":{"type":"boolean","title":"Cancelled"},"is_active":{"type":"boolean","title":"Is Active"},"is_expired":{"type":"boolean","title":"Is Expired"},"created_by_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","battery_id","group_id","mode","parameters","start_at","duration_minutes","end_at","executed","cancelled","is_active","is_expired","created_by_id","created_at","updated_at"],"title":"OneOffEventResponse","description":"Schema for one-off event response."},"OperatingMode":{"type":"string","enum":["discharge","charge","self_use","idle"],"title":"OperatingMode","description":"Battery operating mode."},"OptimiserActivityResponse":{"properties":{"rows":{"items":{"$ref":"#/components/schemas/OptimiserActivityRow"},"type":"array","title":"Rows"}},"type":"object","required":["rows"],"title":"OptimiserActivityResponse"},"OptimiserActivityRow":{"properties":{"plan_id":{"type":"string","format":"uuid","title":"Plan Id"},"revision":{"type":"integer","title":"Revision"},"submitted_at":{"type":"string","format":"date-time","title":"Submitted At"},"partner_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Partner Id"},"partner_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Slug"},"partner_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Partner Display Name"},"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"battery_serial":{"type":"string","title":"Battery Serial"},"battery_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Battery Display Name"},"block_count":{"type":"integer","title":"Block Count"},"source":{"type":"string","title":"Source"},"source_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Ref"},"horizon_end_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Horizon End Ms"},"cert_fingerprint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cert Fingerprint"}},"type":"object","required":["plan_id","revision","submitted_at","partner_id","partner_slug","partner_display_name","battery_id","battery_serial","battery_display_name","block_count","source","source_ref","horizon_end_ms","cert_fingerprint"],"title":"OptimiserActivityRow"},"OptimiserAssignmentCreate":{"properties":{"battery_ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":10000,"minItems":1,"title":"Battery Ids"},"external_battery_refs":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"External Battery Refs","description":"Optional map of battery_id (str) -> partner's external ref"}},"type":"object","required":["battery_ids"],"title":"OptimiserAssignmentCreate"},"OptimiserAssignmentResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"partner_id":{"type":"string","format":"uuid","title":"Partner Id"},"external_battery_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Battery Ref"},"assigned_at":{"type":"string","format":"date-time","title":"Assigned At"},"unassigned_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Unassigned At"}},"type":"object","required":["id","battery_id","partner_id","external_battery_ref","assigned_at","unassigned_at"],"title":"OptimiserAssignmentResponse"},"OptimiserCertificateIssued":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"partner_id":{"type":"string","format":"uuid","title":"Partner Id"},"fingerprint_sha256":{"type":"string","title":"Fingerprint Sha256"},"subject_dn":{"type":"string","title":"Subject Dn"},"issuer_dn":{"type":"string","title":"Issuer Dn"},"serial_hex":{"type":"string","title":"Serial Hex"},"not_before":{"type":"string","format":"date-time","title":"Not Before"},"not_after":{"type":"string","format":"date-time","title":"Not After"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"certificate_pem":{"type":"string","title":"Certificate Pem"}},"type":"object","required":["id","partner_id","fingerprint_sha256","subject_dn","issuer_dn","serial_hex","not_before","not_after","revoked_at","last_used_at","created_at","certificate_pem"],"title":"OptimiserCertificateIssued","description":"Issuance response — includes the signed PEM so admin can hand it to partner."},"OptimiserCertificateResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"partner_id":{"type":"string","format":"uuid","title":"Partner Id"},"fingerprint_sha256":{"type":"string","title":"Fingerprint Sha256"},"subject_dn":{"type":"string","title":"Subject Dn"},"issuer_dn":{"type":"string","title":"Issuer Dn"},"serial_hex":{"type":"string","title":"Serial Hex"},"not_before":{"type":"string","format":"date-time","title":"Not Before"},"not_after":{"type":"string","format":"date-time","title":"Not After"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","partner_id","fingerprint_sha256","subject_dn","issuer_dn","serial_hex","not_before","not_after","revoked_at","last_used_at","created_at"],"title":"OptimiserCertificateResponse","description":"Certificate metadata (no private key — partner generated the key)."},"OptimiserCertificateSignRequest":{"properties":{"csr_pem":{"type":"string","title":"Csr Pem","description":"PEM-encoded PKCS#10 CSR"},"validity_days":{"type":"integer","maximum":825.0,"minimum":1.0,"title":"Validity Days","default":365}},"type":"object","required":["csr_pem"],"title":"OptimiserCertificateSignRequest","description":"Body for POST /admin/optimiser/partners/{id}/certificates."},"OptimiserPartnerCreate":{"properties":{"slug":{"type":"string","maxLength":50,"minLength":1,"pattern":"^[a-z0-9][a-z0-9_-]*$","title":"Slug"},"display_name":{"type":"string","maxLength":200,"minLength":1,"title":"Display Name"},"contact_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Contact Email"}},"type":"object","required":["slug","display_name"],"title":"OptimiserPartnerCreate"},"OptimiserPartnerResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"display_name":{"type":"string","title":"Display Name"},"contact_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contact Email"},"is_active":{"type":"boolean","title":"Is Active"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","slug","display_name","contact_email","is_active","created_at","updated_at"],"title":"OptimiserPartnerResponse"},"OptimiserPartnerUpdate":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Display Name"},"contact_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Contact Email"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"OptimiserPartnerUpdate"},"PaginatedResponse_AuditEntryResponse_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AuditEntryResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["items","total","page","page_size","total_pages"],"title":"PaginatedResponse[AuditEntryResponse]"},"PaginatedResponse_BatteryListItem_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/BatteryListItem"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["items","total","page","page_size","total_pages"],"title":"PaginatedResponse[BatteryListItem]"},"PaginatedResponse_CommandResponse_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/CommandResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["items","total","page","page_size","total_pages"],"title":"PaginatedResponse[CommandResponse]"},"PaginatedResponse_GroupResponse_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/GroupResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["items","total","page","page_size","total_pages"],"title":"PaginatedResponse[GroupResponse]"},"PaginatedResponse_ProviderDeviceResponse_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ProviderDeviceResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["items","total","page","page_size","total_pages"],"title":"PaginatedResponse[ProviderDeviceResponse]"},"PaginatedResponse_ProviderEventResponse_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ProviderEventResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["items","total","page","page_size","total_pages"],"title":"PaginatedResponse[ProviderEventResponse]"},"PaginatedResponse_TariffResponse_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/TariffResponse"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"page_size":{"type":"integer","title":"Page Size"},"total_pages":{"type":"integer","title":"Total Pages"}},"type":"object","required":["items","total","page","page_size","total_pages"],"title":"PaginatedResponse[TariffResponse]"},"PartnerBatteryResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"serial_number":{"type":"string","title":"Serial Number"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"external_battery_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Battery Ref"},"capacity_kwh":{"type":"number","title":"Capacity Kwh"},"max_power_kw":{"type":"number","title":"Max Power Kw"},"min_soc_percent":{"type":"number","title":"Min Soc Percent"},"max_soc_percent":{"type":"number","title":"Max Soc Percent"},"current_soc":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Soc"},"current_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Power Kw"},"status":{"type":"string","title":"Status"},"last_seen":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Seen"},"timezone":{"type":"string","title":"Timezone"},"control_mode":{"type":"string","title":"Control Mode"},"optimiser_steering_active":{"type":"boolean","title":"Optimiser Steering Active"}},"type":"object","required":["id","serial_number","display_name","external_battery_ref","capacity_kwh","max_power_kw","min_soc_percent","max_soc_percent","current_soc","current_power_kw","status","last_seen","timezone","control_mode","optimiser_steering_active"],"title":"PartnerBatteryResponse","description":"Minimal battery view exposed to partners."},"ProviderAssignmentResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"provider":{"$ref":"#/components/schemas/FleetProviderResponse"},"external_asset_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Asset Id"},"config_overrides":{"additionalProperties":true,"type":"object","title":"Config Overrides"},"is_active":{"type":"boolean","title":"Is Active"},"provisioned":{"type":"boolean","title":"Provisioned"},"provisioned_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Provisioned At"},"connection_status":{"type":"string","title":"Connection Status"},"steering_active":{"type":"boolean","title":"Steering Active"},"last_control_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Control At"},"last_control_detail":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Last Control Detail"},"last_connected_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Connected At"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","battery_id","provider","external_asset_id","config_overrides","is_active","provisioned","provisioned_at","connection_status","steering_active","last_control_at","last_control_detail","last_connected_at","last_error","created_at"],"title":"ProviderAssignmentResponse","description":"Response schema for a battery's provider assignment."},"ProviderDeviceResponse":{"properties":{"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"battery_serial":{"type":"string","title":"Battery Serial"},"battery_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Battery Display Name"},"external_asset_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Asset Id"},"provisioned":{"type":"boolean","title":"Provisioned"},"provisioned_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Provisioned At"},"connection_status":{"type":"string","title":"Connection Status"},"steering_active":{"type":"boolean","title":"Steering Active"},"last_control_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Control At"},"last_control_detail":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Last Control Detail"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"last_connected_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Connected At"}},"type":"object","required":["battery_id","battery_serial","battery_display_name","external_asset_id","provisioned","provisioned_at","connection_status","steering_active","last_control_at","last_control_detail","last_error","last_connected_at"],"title":"ProviderDeviceResponse","description":"Per-device status for provider dashboard."},"ProviderEventCreate":{"properties":{"event_type":{"type":"string","maxLength":50,"minLength":1,"title":"Event Type"},"detail":{"additionalProperties":true,"type":"object","title":"Detail"}},"type":"object","required":["event_type"],"title":"ProviderEventCreate","description":"Agent-reported provider event."},"ProviderEventResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"provider_id":{"type":"string","format":"uuid","title":"Provider Id"},"battery_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"},"battery_serial":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Battery Serial"},"event_type":{"type":"string","title":"Event Type"},"detail":{"additionalProperties":true,"type":"object","title":"Detail"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","provider_id","battery_id","event_type","detail","created_at"],"title":"ProviderEventResponse","description":"Response schema for a provider event."},"ProviderStatusUpdate":{"properties":{"connection_status":{"type":"string","pattern":"^(connected|disconnected)$","title":"Connection Status"},"steering_active":{"type":"boolean","title":"Steering Active","default":false},"last_control_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Control At"},"last_control_detail":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Last Control Detail"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"}},"type":"object","required":["connection_status"],"title":"ProviderStatusUpdate","description":"Agent-reported provider status update."},"ProviderSummaryResponse":{"properties":{"provider":{"$ref":"#/components/schemas/FleetProviderResponse"},"total_devices":{"type":"integer","title":"Total Devices"},"connected":{"type":"integer","title":"Connected"},"steering":{"type":"integer","title":"Steering"},"errors_24h":{"type":"integer","title":"Errors 24H"}},"type":"object","required":["provider","total_devices","connected","steering","errors_24h"],"title":"ProviderSummaryResponse","description":"Aggregate stats for a provider dashboard."},"ReadinessResponse":{"properties":{"status":{"type":"string","title":"Status"},"database":{"type":"string","title":"Database"}},"type":"object","required":["status","database"],"title":"ReadinessResponse","description":"Readiness check response."},"RecurringScheduleCreate":{"properties":{"battery_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"},"group_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Group Id"},"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"mode":{"$ref":"#/components/schemas/OperatingMode"},"parameters":{"$ref":"#/components/schemas/ScheduleParameters"},"start_time":{"type":"string","format":"time","title":"Start Time","description":"Start time (e.g., 00:00)"},"end_time":{"type":"string","format":"time","title":"End Time","description":"End time (e.g., 05:30)"},"days_of_week":{"items":{"type":"integer"},"type":"array","maxItems":7,"minItems":1,"title":"Days Of Week","description":"Days of week (0=Monday, 6=Sunday)"},"timezone":{"type":"string","title":"Timezone","default":"UTC"},"priority":{"type":"integer","minimum":0.0,"title":"Priority","description":"Higher = more important","default":0},"enabled":{"type":"boolean","title":"Enabled","default":true}},"type":"object","required":["name","mode","start_time","end_time","days_of_week"],"title":"RecurringScheduleCreate","description":"Schema for creating a recurring schedule."},"RecurringScheduleResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"battery_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Battery Id"},"group_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Group Id"},"name":{"type":"string","title":"Name"},"mode":{"$ref":"#/components/schemas/OperatingMode"},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters"},"start_time":{"type":"string","format":"time","title":"Start Time"},"end_time":{"type":"string","format":"time","title":"End Time"},"days_of_week":{"items":{"type":"integer"},"type":"array","title":"Days Of Week"},"timezone":{"type":"string","title":"Timezone"},"priority":{"type":"integer","title":"Priority"},"enabled":{"type":"boolean","title":"Enabled"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","battery_id","group_id","name","mode","parameters","start_time","end_time","days_of_week","timezone","priority","enabled","created_at","updated_at"],"title":"RecurringScheduleResponse","description":"Schema for recurring schedule response."},"RecurringScheduleUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name"},"mode":{"anyOf":[{"$ref":"#/components/schemas/OperatingMode"},{"type":"null"}]},"parameters":{"anyOf":[{"$ref":"#/components/schemas/ScheduleParameters"},{"type":"null"}]},"start_time":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Start Time"},"end_time":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"End Time"},"days_of_week":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Days Of Week"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"},"priority":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Priority"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"}},"type":"object","title":"RecurringScheduleUpdate","description":"Schema for updating a recurring schedule."},"RefreshRequest":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"RefreshRequest","description":"Refresh token request."},"RteReportResponse":{"properties":{"start_date":{"type":"string","format":"date","title":"Start Date"},"end_date":{"type":"string","format":"date","title":"End Date"},"snapshot_time":{"type":"string","format":"time","title":"Snapshot Time"},"timezone":{"type":"string","title":"Timezone"},"days_total":{"type":"integer","title":"Days Total"},"rows":{"items":{"$ref":"#/components/schemas/RteReportRow"},"type":"array","title":"Rows"}},"type":"object","required":["start_date","end_date","snapshot_time","timezone","days_total","rows"],"title":"RteReportResponse","description":"Fleet-wide round-trip-efficiency report.\n\nComputes meter import / export deltas between cumulative-counter\nreadings taken at `snapshot_time` on each day from `start_date` through\n`end_date`. When `snapshot_time` lands on a full-SOC point (e.g. 05:00\nafter off-peak charging), ΔSOC across the period is ~zero so the meter\nexport-to-import ratio approximates the round-trip efficiency."},"RteReportRow":{"properties":{"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"serial_number":{"type":"string","title":"Serial Number"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"timezone":{"type":"string","title":"Timezone"},"status":{"type":"string","title":"Status"},"import_kwh":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Import Kwh"},"export_kwh":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Export Kwh"},"export_import_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Export Import Pct"},"days_with_data":{"type":"integer","title":"Days With Data"},"days_total":{"type":"integer","title":"Days Total"},"start_reading_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Start Reading At"},"end_reading_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"End Reading At"}},"type":"object","required":["battery_id","serial_number","display_name","timezone","status","import_kwh","export_kwh","export_import_pct","days_with_data","days_total"],"title":"RteReportRow","description":"One battery's row in the RTE report.\n\nstatus:\n  - \"ok\"        — every daily anchor has a meter reading within 2h\n  - \"partial\"   — at least the first and last anchor have data but some\n                  interior days are missing\n  - \"no_data\"   — endpoints missing; can't compute a delta. Could mean\n                  no meter installed, or the battery was offline at the\n                  snapshot time on both endpoints."},"ScheduleParameters":{"properties":{"power_kw":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Power Kw","description":"Power in kW"},"target_soc":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Target Soc","description":"Target state of charge (%)"}},"type":"object","title":"ScheduleParameters","description":"Parameters for a scheduled mode."},"ScheduleTimelineEntry":{"properties":{"start_at":{"type":"string","format":"date-time","title":"Start At"},"end_at":{"type":"string","format":"date-time","title":"End At"},"layer":{"type":"integer","title":"Layer","description":"1=base, 2=recurring, 3=one-off"},"source_id":{"type":"string","format":"uuid","title":"Source Id","description":"ID of the schedule/event"},"source_type":{"type":"string","title":"Source Type","description":"base_mode, recurring_schedule, or one_off_event"},"mode":{"$ref":"#/components/schemas/OperatingMode"},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters"}},"type":"object","required":["start_at","end_at","layer","source_id","source_type","mode","parameters"],"title":"ScheduleTimelineEntry","description":"An entry in the schedule timeline."},"SlackSettingsResponse":{"properties":{"warn_enabled":{"type":"boolean","title":"Warn Enabled"},"error_enabled":{"type":"boolean","title":"Error Enabled"},"webhook_configured":{"type":"boolean","title":"Webhook Configured"},"env_tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Env Tag"}},"type":"object","required":["warn_enabled","error_enabled","webhook_configured","env_tag"],"title":"SlackSettingsResponse"},"SlackSettingsUpdate":{"properties":{"warn_enabled":{"type":"boolean","title":"Warn Enabled"},"error_enabled":{"type":"boolean","title":"Error Enabled"}},"type":"object","required":["warn_enabled","error_enabled"],"title":"SlackSettingsUpdate"},"TargetType":{"type":"string","enum":["battery","group"],"title":"TargetType","description":"Target type for commands."},"TariffCreate":{"properties":{"name":{"type":"string","maxLength":200,"minLength":1,"title":"Name"},"provider":{"type":"string","maxLength":100,"minLength":1,"title":"Provider"},"description":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Description"},"tariff_type":{"$ref":"#/components/schemas/TariffType"},"flat_price_p":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Flat Price P","description":"Flat price in pence per kWh"},"off_peak_price_p":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Off Peak Price P","description":"Off-peak price in pence per kWh"},"peak_price_p":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Peak Price P","description":"Peak price in pence per kWh"},"off_peak_start":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Off Peak Start","description":"Start time of off-peak period"},"off_peak_end":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Off Peak End","description":"End time of off-peak period"},"agile_product_code":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Agile Product Code"},"agile_region_code":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Agile Region Code"},"charge_threshold_percentile":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Charge Threshold Percentile","default":25},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"}},"type":"object","required":["name","provider","tariff_type"],"title":"TariffCreate","description":"Schema for creating a tariff."},"TariffPeriodResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"tariff_name":{"type":"string","title":"Tariff Name"},"tariff_type":{"type":"string","title":"Tariff Type"},"off_peak_price_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Off Peak Price P"},"peak_price_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Peak Price P"},"off_peak_start":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Off Peak Start"},"off_peak_end":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Off Peak End"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"ended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ended At"}},"type":"object","required":["id","tariff_name","tariff_type","off_peak_price_p","peak_price_p","off_peak_start","off_peak_end","started_at","ended_at"],"title":"TariffPeriodResponse","description":"A tariff period for a battery."},"TariffPeriodUpdate":{"properties":{"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"ended_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Ended At"}},"type":"object","title":"TariffPeriodUpdate","description":"Update a tariff period's dates."},"TariffResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"provider":{"type":"string","title":"Provider"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"tariff_type":{"$ref":"#/components/schemas/TariffType"},"flat_price_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Flat Price P"},"off_peak_price_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Off Peak Price P"},"peak_price_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Peak Price P"},"off_peak_start":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Off Peak Start"},"off_peak_end":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Off Peak End"},"agile_product_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agile Product Code"},"agile_region_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agile Region Code"},"charge_threshold_percentile":{"type":"integer","title":"Charge Threshold Percentile"},"battery_count":{"type":"integer","title":"Battery Count","default":0},"battery_serials":{"items":{"type":"string"},"type":"array","title":"Battery Serials","default":[]},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","name","provider","description","tariff_type","flat_price_p","off_peak_price_p","peak_price_p","off_peak_start","off_peak_end","agile_product_code","agile_region_code","charge_threshold_percentile","metadata","created_at","updated_at"],"title":"TariffResponse","description":"Schema for tariff response."},"TariffScheduleResponse":{"properties":{"tariff_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Tariff Id"},"tariff_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tariff Type"},"tariff_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tariff Name"},"off_peak_start":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Off Peak Start"},"off_peak_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Off Peak End"},"off_peak_price_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Off Peak Price P"},"peak_price_p":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Peak Price P"},"timezone":{"type":"string","title":"Timezone"},"is_off_peak":{"type":"boolean","title":"Is Off Peak"}},"type":"object","required":["tariff_id","tariff_type","tariff_name","off_peak_start","off_peak_end","off_peak_price_p","peak_price_p","timezone","is_off_peak"],"title":"TariffScheduleResponse","description":"Tariff schedule for agent AUTO mode decisions."},"TariffType":{"type":"string","enum":["single_rate","dual_rate","agile"],"title":"TariffType","description":"Type of tariff pricing structure."},"TariffUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Name"},"provider":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Provider"},"description":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Description"},"flat_price_p":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Flat Price P"},"off_peak_price_p":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Off Peak Price P"},"peak_price_p":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Peak Price P"},"off_peak_start":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Off Peak Start"},"off_peak_end":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Off Peak End"},"agile_product_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agile Product Code"},"agile_region_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agile Region Code"},"charge_threshold_percentile":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Charge Threshold Percentile"},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","title":"TariffUpdate","description":"Schema for updating a tariff."},"TelemetryAggregatePoint":{"properties":{"time":{"type":"string","format":"date-time","title":"Time"},"avg_soc_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Soc Percent"},"avg_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Power Kw"},"min_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Min Power Kw"},"max_power_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Power Kw"},"avg_temperature_c":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Temperature C"},"avg_household_load_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Household Load Kw"},"avg_household_solar_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Household Solar Kw"},"avg_grid_import_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Grid Import Kw"},"avg_grid_export_kw":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Grid Export Kw"},"reading_count":{"type":"integer","title":"Reading Count"}},"type":"object","required":["time","avg_soc_percent","avg_power_kw","min_power_kw","max_power_kw","avg_temperature_c","reading_count"],"title":"TelemetryAggregatePoint","description":"Aggregated telemetry point."},"TelemetryBatch":{"properties":{"readings":{"items":{"$ref":"#/components/schemas/TelemetryPoint"},"type":"array","maxItems":100,"minItems":1,"title":"Readings"}},"type":"object","required":["readings"],"title":"TelemetryBatch","description":"Batch of telemetry readings from a battery."},"TelemetryPoint":{"properties":{"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"soc_percent":{"type":"number","maximum":100.0,"minimum":0.0,"title":"Soc Percent"},"power_kw":{"type":"number","title":"Power Kw"},"voltage_v":{"type":"number","minimum":0.0,"title":"Voltage V"},"current_a":{"type":"number","title":"Current A"},"temperature_c":{"type":"number","title":"Temperature C"},"status":{"type":"string","title":"Status"},"errors":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Errors"},"household_load_kw":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Household Load Kw","description":"Household consumption in kW"},"household_solar_kw":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Household Solar Kw","description":"Solar generation in kW"},"grid_import_kw":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Grid Import Kw","description":"Power imported from grid in kW"},"grid_export_kw":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Grid Export Kw","description":"Power exported to grid in kW"},"meter_voltage_v":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Meter Voltage V","description":"Meter voltage in V"},"meter_current_a":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Meter Current A","description":"Meter current in A"},"meter_power_w":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Meter Power W","description":"Meter active power in W"},"meter_reactive_var":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Meter Reactive Var","description":"Meter reactive power in VAr"},"meter_apparent_va":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Meter Apparent Va","description":"Meter apparent power in VA"},"meter_power_factor":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Meter Power Factor","description":"Meter power factor"},"meter_frequency_hz":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Meter Frequency Hz","description":"Meter frequency in Hz"},"meter_energy_kwh":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Meter Energy Kwh","description":"Meter total energy in kWh"},"meter_export_energy_kwh":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Meter Export Energy Kwh","description":"Meter cumulative export energy in kWh (reverse counter)"},"meter_import_energy_kwh":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Meter Import Energy Kwh","description":"Meter cumulative import energy in kWh (forward counter)"},"inverter_temps":{"anyOf":[{"additionalProperties":{"type":"number"},"type":"object"},{"type":"null"}],"title":"Inverter Temps"}},"type":"object","required":["timestamp","soc_percent","power_kw","voltage_v","current_a","temperature_c","status"],"title":"TelemetryPoint","description":"A single telemetry reading from a battery."},"TelemetryResponse":{"properties":{"battery_id":{"type":"string","format":"uuid","title":"Battery Id"},"start_time":{"type":"string","format":"date-time","title":"Start Time"},"end_time":{"type":"string","format":"date-time","title":"End Time"},"interval":{"type":"string","title":"Interval"},"data":{"items":{"$ref":"#/components/schemas/TelemetryAggregatePoint"},"type":"array","title":"Data"}},"type":"object","required":["battery_id","start_time","end_time","interval","data"],"title":"TelemetryResponse","description":"Response for telemetry query."},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"expires_in":{"type":"integer","title":"Expires In"},"user":{"$ref":"#/components/schemas/UserResponse"}},"type":"object","required":["access_token","refresh_token","expires_in","user"],"title":"TokenResponse","description":"OAuth token response."},"UnassignBatteriesRequest":{"properties":{"battery_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Battery Ids"}},"type":"object","required":["battery_ids"],"title":"UnassignBatteriesRequest"},"UserCreate":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"role":{"$ref":"#/components/schemas/UserRole","default":"viewer"}},"type":"object","required":["email"],"title":"UserCreate","description":"Schema for creating a user."},"UserResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","format":"email","title":"Email"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"oauth_provider":{"$ref":"#/components/schemas/OAuthProvider"},"role":{"$ref":"#/components/schemas/UserRole"},"is_active":{"type":"boolean","title":"Is Active"},"last_login":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Login"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","email","full_name","oauth_provider","role","is_active","last_login","created_at","updated_at"],"title":"UserResponse","description":"Schema for user response."},"UserRole":{"type":"string","enum":["admin","operator","installer","viewer"],"title":"UserRole","description":"User role for authorization."},"UserUpdate":{"properties":{"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"role":{"anyOf":[{"$ref":"#/components/schemas/UserRole"},{"type":"null"}]},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"UserUpdate","description":"Schema for updating a user."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"},"APIKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"}}}}