api : référence régénérée depuis le banc en 1.15.2+etm71 (droits NymeaEnergy.* séparés, GetOptimizerProtocol)
All checks were successful
Build & Deploy docs / build-deploy (push) Successful in 3m52s

Le badge PUBLIC de PermissionScopeNone devient AUTH : sur un transport
authentifié, nymea exige un token valide pour toute méthode sauf
JSONRPC.Hello, Authenticate et RequestPushButtonAuth
(jsonrpcserverimplementation.cpp, tag 1.15.2). « Lecture publique, aucun
token requis » était faux, en trois langues.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Patrick Schurig 2026-10-20 08:49:15 +02:00
parent 6214be9548
commit 4a7a1bddf4
14 changed files with 109 additions and 81 deletions

View File

@ -42,7 +42,7 @@ der ETM-Erweiterungen (`Energy`, `AirConditioning`, `EvDash`).
| Badge | Scope | Beschreibung |
| --- | --- | --- |
| <span class="badge perm-none">PUBLIC</span> | `PermissionScopeNone` | Öffentlich lesbar, kein Token nötig |
| <span class="badge perm-none">AUTH</span> | `PermissionScopeNone` | Jedes angemeldete Konto (Token nötig, sobald der Transport Authentifizierung verlangt; nur `JSONRPC.Hello`, `Authenticate` und `RequestPushButtonAuth` gehen ohne) |
| <span class="badge perm-control">CONTROL</span> | `PermissionScopeControlThings` / `ExecuteRules` | Steuerung von Geräten und Regeln |
| <span class="badge perm-configure">CONFIGURE</span> | `PermissionScopeConfigureThings` / `ConfigureRules` | Konfiguration |
| <span class="badge perm-admin">ADMIN</span> | `PermissionScopeAdmin` | Systemadministration |

View File

@ -41,7 +41,7 @@ extensions (`Energy`, `AirConditioning`, `EvDash`).
| Badge | Scope | Description |
| --- | --- | --- |
| <span class="badge perm-none">PUBLIC</span> | `PermissionScopeNone` | Public read, no token required |
| <span class="badge perm-none">AUTH</span> | `PermissionScopeNone` | Any authenticated account (token required whenever the transport requires authentication; only `JSONRPC.Hello`, `Authenticate` and `RequestPushButtonAuth` work without one) |
| <span class="badge perm-control">CONTROL</span> | `PermissionScopeControlThings` / `ExecuteRules` | Control of things and rules |
| <span class="badge perm-configure">CONFIGURE</span> | `PermissionScopeConfigureThings` / `ConfigureRules` | Configuration |
| <span class="badge perm-admin">ADMIN</span> | `PermissionScopeAdmin` | System administration |

View File

@ -42,7 +42,7 @@ ETM PowerSync expose l'**API JSON-RPC de nymea** en local, y compris les extensi
| Badge | Scope | Description |
| --- | --- | --- |
| <span class="badge perm-none">PUBLIC</span> | `PermissionScopeNone` | Lecture publique, aucun token requis |
| <span class="badge perm-none">AUTH</span> | `PermissionScopeNone` | Tout compte authentifié (token requis dès que le transport exige l'authentification ; seuls `JSONRPC.Hello`, `Authenticate` et `RequestPushButtonAuth` passent sans) |
| <span class="badge perm-control">CONTROL</span> | `PermissionScopeControlThings` / `ExecuteRules` | Contrôle des appareils et règles |
| <span class="badge perm-configure">CONFIGURE</span> | `PermissionScopeConfigureThings` / `ConfigureRules` | Configuration |
| <span class="badge perm-admin">ADMIN</span> | `PermissionScopeAdmin` | Administration système |

View File

@ -5,7 +5,7 @@
### Energy.GetPowerBalance
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get the current power balance. That is, production, consumption and acquisition.
@ -30,7 +30,7 @@ _No parameters._
### Energy.GetPowerBalanceLogs
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get logs for the power balance. If from is not give, the log will start at the beginning of recording. If to is not given, the logs will and at the last sample for this sample rate before now.
@ -52,7 +52,7 @@ Get logs for the power balance. If from is not give, the log will start at the b
### Energy.GetRootMeter
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get the root meter ID. If there is no root meter set, the params will be empty.
@ -70,7 +70,7 @@ _No parameters._
### Energy.GetThingPowerLogs
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get logs for one or more things power values. If thingIds is not given, logs for all energy related things will be returned. If from is not given, the log will start at the beginning of recording. If to is not given, the logs will and at the last sample for this sample rate before now. If the parameter "includeCurrent" is set to true, the result will contain the newest log entries available, regardless of the sample rate (that is, 1 minute). This may be useful to calculate the difference to the newest entry of the fetched sample rate and the current values to display the live value until the current sample is completed.

View File

@ -30,7 +30,7 @@ Add a new thing to the system. Only things with a setupMethod of SetupMethodJust
### Integrations.BrowseThing
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Browse a thing. If a ThingClass indicates a thing is browsable, this method will return the BrowserItems. If no parameter besides the thingId is used, the root node of this thingwill be returned. Any returned item which is browsable can be passed as node. Results will be children of the given node.
In case of an error during browsing, the error will be indicated and the displayMessage may contain additional information for the user. The displayMessage will be translated. A client UI showing this message to the user should be prepared for empty, but also longer strings.
@ -238,7 +238,7 @@ In case of an error during execution, the error will be indicated and the displa
### Integrations.GetActionTypes
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get action types for a specified thingClassId.
@ -258,7 +258,7 @@ Get action types for a specified thingClassId.
### Integrations.GetBrowserItem
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get a single item from the browser. This won't give any more info on an item than a regular BrowseThing call, but it allows to fetch details of an item if only the ID is known.
In case of an error during browsing, the error will be indicated and the displayMessage may contain additional information for the user. The displayMessage will be translated. A client UI showing this message to the user should be prepared for empty, but also longer strings.
@ -282,7 +282,7 @@ In case of an error during browsing, the error will be indicated and the display
### Integrations.GetEventTypes
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get event types for a specified thingClassId.
@ -302,7 +302,7 @@ Get event types for a specified thingClassId.
### Integrations.GetIOConnections
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Fetch IO connections. Optionally filtered by thingId and stateTypeId.
@ -344,7 +344,7 @@ Get a plugin's params.
### Integrations.GetPlugins
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Returns a list of loaded plugins.
@ -362,7 +362,7 @@ _No parameters._
### Integrations.GetStateTypes
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get state types for a specified thingClassId.
@ -382,7 +382,7 @@ Get state types for a specified thingClassId.
### Integrations.GetStateValue
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get the value of the given thing and the given stateType
@ -404,7 +404,7 @@ Get the value of the given thing and the given stateType
### Integrations.GetStateValues
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get all the state values of the given thing.
@ -425,7 +425,7 @@ Get all the state values of the given thing.
### Integrations.GetThingClasses
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Returns a list of supported thing classes, optionally filtered by vendorId or by a list of thing class ids.
@ -447,7 +447,7 @@ Returns a list of supported thing classes, optionally filtered by vendorId or by
### Integrations.GetThings
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Returns a list of configured things, optionally filtered by thingId.
@ -468,7 +468,7 @@ Returns a list of configured things, optionally filtered by thingId.
### Integrations.GetVendors
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Returns a list of supported Vendors.

View File

@ -5,7 +5,7 @@
### JSONRPC.Authenticate
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Authenticate a client to the api via user & password challenge. Provide a device name which allows the user to identify the client and revoke the token in case the device is lost or stolen. This will return a new token to be used to authorize a client at the API.
@ -53,7 +53,7 @@ Create a new user in the API. This is only allowed to be called when the initial
### JSONRPC.Hello
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Initiates a connection. Use this method to perform an initial handshake of the connection. Optionally, a parameter "locale" is can be passed to set up the used locale for this connection. Strings such as ThingClass displayNames etc will be localized to this locale. If this parameter is omitted, the default system locale (depending on the configuration) is used. The reply of this method contains information about this core instance such as version information, uuid and its name. The locale valueindicates the locale used for this connection. Note: This method can be called multiple times. The locale used in the last call for this connection will be used. Other values, like initialSetupRequired might change if the setup has been performed in the meantime.
The field cacheHashes may contain a map of methods and MD5 hashes. As long as the hash for a method does not change, a client may use a previously cached copy of the call instead of fetching the content again. While the Hello call doesn't necessarily require a token, this can be called with a token. If a token is provided, it will be verified and the reply contains information about the tokens validity and the user and permissions for the given token.
@ -88,7 +88,7 @@ Initiates a connection. Use this method to perform an initial handshake of the c
### JSONRPC.Introspect
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Introspect this API.
@ -108,7 +108,7 @@ _No parameters._
### JSONRPC.KeepAlive
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
This is basically a Ping/Pong mechanism a client app may use to check server connectivity. Currently, the server does not actually do anything with this information and will return the call providing the given sessionId back to the caller. It is up to the client whether to use this or not and not required by the server to keep the connection alive.
@ -129,7 +129,7 @@ This is basically a Ping/Pong mechanism a client app may use to check server con
### JSONRPC.RequestPushButtonAuth
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Authenticate a client to the api via Push Button method. Provide a device name which allows the user to identify the client and revoke the token in case the device is lost or stolen. If push button hardware is available, this will return with success and start listening for push button presses. When the push button is pressed, the PushButtonAuthFinished notification will be sent to the requesting client. The procedure will be cancelled when the connection is interrupted. If another client requests push button authentication while a procedure is still going on, the second call will take over and the first one will be notified by the PushButtonAuthFinished signal about the error. The application should make it clear to the user to not press the button when the procedure fails as this can happen for 2 reasons: a) a second user is trying to auth at the same time and only the currently active user should press the button or b) it might indicate an attacker trying to take over and snooping in for tokens.
@ -150,7 +150,7 @@ Authenticate a client to the api via Push Button method. Provide a device name w
### JSONRPC.SetNotificationStatus
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Enable/Disable notifications for this connections. Either "enabled" or "namespaces" needs to be given but not both of them. The boolean based "enabled" parameter will enable/disable all notifications at once. If instead the list-based "namespaces" parameter is provided, all given namespaceswill be enabled, the others will be disabled. The return value of "success" will indicate success of the operation. The "enabled" property in the return value is deprecated and used for legacy compatibilty only. It will be set to true if at least one namespace has been enabled.
@ -172,7 +172,7 @@ Enable/Disable notifications for this connections. Either "enabled" or "namespac
### JSONRPC.Version
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Version of this nymea/JSONRPC interface.

View File

@ -45,7 +45,7 @@ Clear the fault latch of a controllable load (ECS-410). Deliberate operator acti
### NymeaEnergy.GetAcquisitionTolerance
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get the acquisition tolerance. This value will control how much solar surplus is required to start the charging.
@ -63,7 +63,7 @@ _No parameters._
### NymeaEnergy.GetAvailableSpotMarketProviders
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get the list of available spot market data providers.
@ -81,7 +81,7 @@ _No parameters._
### NymeaEnergy.GetBatteryLevelConsideration
<span class="badge perm-admin">ADMIN</span>
<span class="badge perm-none">AUTH</span>
Get the battery level consideration. This value will control how much the energy storage is taking in account
@ -99,7 +99,7 @@ _No parameters._
### NymeaEnergy.GetChargingInfos
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get the charging info for all EV chargers, or for a single one when evChargerId is given. An unknown id yields an EMPTY list, never an error: every configured charger has an entry, so an empty list means 'no such charger' and nothing else.
@ -119,7 +119,7 @@ Get the charging info for all EV chargers, or for a single one when evChargerId
### NymeaEnergy.GetChargingSchedules
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get the planed charging schedules, and whether the L2 degraded mode is currently active (meter silent > 90s, planning suspended).
@ -138,7 +138,7 @@ _No parameters._
### NymeaEnergy.GetEnergyRatios
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get the current energy ratios (self-consumption / autonomy) in percent, derived from the energy manager's cumulative counters over the current local day. A rate field is omitted (never null) when not available (denominator <= 0).
@ -160,7 +160,7 @@ _No parameters._
### NymeaEnergy.GetForecastSite
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Read which site's PV forecast is kept, and which sites COULD be. 'forecastSiteThingId' is omitted when none is designated - a NORMAL state, not a fault. 'candidateSiteThingIds' lists every site with at least one plane publishing a curve; it is what a configuration screen offers. When exactly one candidate exists and nothing has ever been chosen, the engine designates it by itself - designating is not CHOOSING when there is nothing to choose. NOTHING is ever designated automatically: the choice is persisted, and the day a second site appears it would look deliberate when nobody made it. 'fault' carries MISSING_FORECAST_SITE when planes publish but no site is designated - it is ABSENT when no site exists at all, since announcing a missing designation to an installation that has nothing to designate would be an unsatisfiable warning.
@ -181,7 +181,7 @@ _No parameters._
### NymeaEnergy.GetForecastSnapshot
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
The CURRENT PV forecast, read straight from the channel - never from the stored table. GetPvForecast serves the TABLE (history, revisions, reproducible reads); this one serves the DECISION. An arbiter reading the table would read its own trace instead of its input: it would no longer measure, it would re-read itself. 'capturedAt' is when this reply was built. 'contentChangedAt' is when the current content FIRST APPEARED - and it is the one that matters: without it, a FROZEN provider reads as a stable forecast, which is the costliest form of 'silence that looks like a result' since whoever reads it decides to BUY. It is omitted when the store has never seen this content, rather than guessed. 'forecastPoints' is ABSENT when nothing is readable - never a curve of zeros; a missing forecast and a forecast of zero are different statements. 'fault' carries MISSING_FORECAST_SITE (nobody designated a site, and one exists) or FORECAST_PAYLOAD_REFUSED with its cause (the channel publishes something we cannot read). Two faults, two gestures: configure, or look at the provider. With a curve come 'corrections' (physical corrections applied, canonical order: 'temperature' by the provider, 'ac-limit' when the site has an AC limit; empty = raw GTI x kWp x PR; when planes disagree, only the corrections ALL of them received), 'perField' (one entry per summed plane: its thing 'id' and the 'corrections' it declared - where a divergence between planes is read), 'conversion' ('physics' - this engine has no other) and 'acLimitW' when an AC limit is configured: the curve is the sum of the planes CLIPPED to it. ALWAYS (ETM build), whatever the PV outcome: the GRID 'start' (instant), 'resolutionS' and 'steps' - the PV grid when a curve exists (first slot to last, holes included), otherwise hourly from local midnight today to local midnight after tomorrow - and on it, index by index: 'baseload' {model: profile|none, p50W: [W or null], quality} - consumption WITHOUT the controlled loads, median per local slot and day type over 28 days, 'none' with nulls under 7 covered days - and 'price' (null when no tariff is set) {currency, importCtkWh, exportCtkWh, includes, source: fixed|tou, knownUntil}. A slot straddling two tariff zones gets the time-weighted mean. NOTHING here is read by any decision.
@ -214,7 +214,7 @@ _No parameters._
### NymeaEnergy.GetLoadConfig
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get the configured controllable loads (etmvariableload).
@ -232,7 +232,7 @@ _No parameters._
### NymeaEnergy.GetLoadTelemetry
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get a snapshot of the arbitration runtime state: surplus budget, per-load allocation, availability, fault code, active lock (seconds remaining), mechanism payload and decision reason. Reason and fault are CODES with numeric params - never human-readable sentences: the client renders them in the user's language. Identical payload to the LoadTelemetryChanged notification. 'timestamp' is the end of the last arbitration cycle and is omitted while no cycle has run yet.
@ -255,7 +255,7 @@ _No parameters._
### NymeaEnergy.GetLockOnUnplug
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get the lock on unplug setting.
@ -271,9 +271,28 @@ _No parameters._
---
### NymeaEnergy.GetOptimizerProtocol
<span class="badge perm-none">AUTH</span>
The OpenRPC 1.3 document of the engine <-> optimizer protocol spoken by THIS engine (docs/etm-powersync-optimizer-protocol.openrpc.json, embedded at build time). protocolVersion: the version sent at handshake. schema: the document (methods Handshake, GetPlan, UpdateLearned; components.schemas; x-etm-* extensions for transport, fallback machine and semantic rules). No secret. Static for a given binary: no notification.
**Parameters:**
_No parameters._
**Returns:**
| Field | Type | Notes |
| --- | --- | --- |
| `protocolVersion` | `String` | |
| `schema` | `Object` | |
---
### NymeaEnergy.GetOptimizerStatus
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
State of the external-optimizer fallback machine (OPTIMIZER_PROTOCOL 7). optimizerExpected: an endpoint is configured. optimizerAlive: the optimizer answered with a valid plan and has not failed two consecutive requests nor lost its connection since. activeStrategy: optimizer | rules | none (none = degraded mode L2, planning suspended). The other fields are for the installer view; an unknown value is OMITTED, never 0. The token is never returned: tokenConfigured only says whether one is set. Same payload as OptimizerStatusChanged.
@ -321,7 +340,7 @@ _No parameters._
### NymeaEnergy.GetPhasePowerLimit
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get the phase power consumption limit. 0 if unset. This needs to be set in order for the smart charging to do anything.
@ -339,7 +358,7 @@ _No parameters._
### NymeaEnergy.GetPlan
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
The plan IN FORCE at the last planned cycle. Under an optimizer: the current slot with the power APPLIED by the adapters, then the following slots with the power REQUESTED (informative). Under the rule-based: one slot, strategy rules, and fallbackCode when an optimizer is configured but did not command this cycle. Reasons are codes and params only, never text. inForce is false, and nothing else is returned, before the first cycle and in degraded mode L2 (no plan in force). No notification: read it again on LoadTelemetryChanged or OptimizerStatusChanged.
@ -363,7 +382,7 @@ _No parameters._
### NymeaEnergy.GetPvForecast
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Read the stored PV production FORECAST for a window. This is a forecast, NEVER a measurement: the conversion ignores shading, soiling, module temperature and inverter clipping - all optimistic - so the curve is a CEILING, systematically above what will be produced. Hours with no forecast are ABSENT, never zero: a zero would read as 'we expect night'. 'knownAt' makes the read reproducible - it returns the curve as it was known at that instant. A revision exists only when the FORECAST CHANGED; the provider's run id does NOT identify the content (it comes from a domain that supplies none of the curve's values), so revisions are keyed on the content itself. 'firstSeenAt' is when this content first appeared - it ORDERS revisions; 'lastSeenAt' is the last time it was republished unchanged - FRESHNESS. Neither is an emission time, and no horizon may be computed from them. The provider blends two model domains, so the FIRST HOURS ARE FRESHER THAN THE REST - a single age cannot date the whole curve, which is why none is published per slot. And beware what a near horizon buys: it reduces the METEOROLOGICAL error, never the CONVERSION bias - shading, soiling, module temperature and inverter clipping are as wrong at three hours as at thirty-six, and all in the optimistic direction. 'Nearer forecast is more reliable' must NOT be shown as 'nearer figure is more accurate'. An UNREADABLE date ('from', 'to' or 'knownAt') is an ERROR, never a window: 'energyError' is EnergyErrorInvalidParameter, 'fault' is FORECAST_DATE_UNREADABLE with 'faultParams.fields' naming the parameters, and 'forecastPoints' is empty and MEANS NOTHING - read 'energyError' first. 'energyError' is EnergyErrorNoError on every successful read.
@ -388,7 +407,7 @@ Read the stored PV production FORECAST for a window. This is a forecast, NEVER a
### NymeaEnergy.GetSpotMarketConfiguration
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get the current spotmarket configuration.
@ -408,7 +427,7 @@ _No parameters._
### NymeaEnergy.GetSpotMarketScoreEntries
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
Get the current score entries from the current spot market. If spot market is not enabled or not available, the list will be empty. The weighting of the available score entries goes from 0 (worst) to 1.0 (best).
@ -426,7 +445,7 @@ _No parameters._
### NymeaEnergy.GetTariff
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-none">AUTH</span>
The tariff entered by the installer. 'zones', 'exportCtkWh' and 'source' (fixed = one zone over 24 h, tou = several) are OMITTED when no tariff is set - never an empty tariff at 0. Ranges are LOCAL wall-clock times of the box, in 'timeZone' (IANA id, always returned): the phone may live in another zone. Prices are FULL prices paid, in c€/kWh incl. taxes ('includes'). Read by no decision.
@ -449,7 +468,7 @@ _No parameters._
### NymeaEnergy.SetAcquisitionTolerance
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-configure">CONFIGURE</span>
Set the acquisition tolerance for the charging.
@ -509,7 +528,7 @@ Set the charging info for an EV charger. The given object REPLACES the stored on
### NymeaEnergy.SetForecastSite
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-configure">CONFIGURE</span>
Designate the site whose PV forecast is kept. ALL the PV planes under that site are SUMMED - not chosen between: a site's production is physically the sum of its planes, and the curve is superimposed on the MEASURED total. Keeping one plane would put the forecast systematically below the measurement, which reads as an under-performing installation. Planes from DIFFERENT runs are never summed: a partly refreshed roof published as the whole would be a chimera, so the engine waits for the next pass. Pass an empty id to keep no forecast at all. 'acLimitW' is the site's inverter AC limit in W, applied AFTER the sum of the planes. It is the ONE field that is not replaced: OMITTED = UNCHANGED (an older client that ignores it must not clear it each time it saves the site), null = CLEAR the limit, an integer = set it. Declared Variant because nymea refuses null on a Uint; anything but null or an integer is refused. Refused (EnergyErrorInvalidParameter, nothing changed) outside [100, 1000000] W or without a site. Designating no site clears the limit too: a limit has no object without a site.
@ -530,7 +549,7 @@ Designate the site whose PV forecast is kept. ALL the PV planes under that site
### NymeaEnergy.SetLoadConfig
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-configure">CONFIGURE</span>
Replace the full set of controllable load configs. Rejected as a whole (energyError) if any entry is invalid; persisted and applied atomically.
@ -677,7 +696,7 @@ Set the phase power consumption limit. This is the maximum allowed Ampere per ph
### NymeaEnergy.SetSpotMarketConfiguration
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-configure">CONFIGURE</span>
Set the current spotmarket configuration. If enabled, the provideId must be valid. You can get the available providers using GetAvailableSpotMarketProviders. [ETM] The shipped build compiles NO spot market provider (no outbound network flow): enabling is then refused with EnergyErrorInvalidParameter and 'fault' SPOT_MARKET_NOT_IN_BUILD - a code, never a sentence. Disabling is always accepted.
@ -699,7 +718,7 @@ Set the current spotmarket configuration. If enabled, the provideId must be vali
### NymeaEnergy.SetTariff
<span class="badge perm-control">CONTROL</span>
<span class="badge perm-configure">CONFIGURE</span>
Replace the tariff, effective immediately and persisted. One zone covering 00:00-24:00 is a single tariff; several zones are a time-of-use tariff, each with one or more LOCAL ranges [from, to) - a range may cross midnight (22:00-06:00). The ranges must cover the 24 h with NO gap and NO overlap. 'priceCtkWh' >= 0, in c€/kWh incl. taxes (NOT €/kWh). 'exportCtkWh' is the resale price, 0 when omitted. An EMPTY 'zones' clears the tariff. On refusal: EnergyErrorInvalidParameter, 'fault' TARIFF_REFUSED and 'faultParams' {cause, zone?, range?, at?, zones?} - codes and indexes, never a sentence - and NOTHING is changed.

View File

@ -207,7 +207,7 @@ Generate a download entry for an existing configuration backup file.
### Configuration.GetAvailableLanguages
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Returns a list of locale codes available for the server. i.e. en_US, de_AT
@ -243,7 +243,7 @@ _No parameters._
### Configuration.GetConfigurations
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get all configuration parameters of the server.
@ -303,7 +303,7 @@ _No parameters._
### Configuration.GetTimeZones
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get the list of available timezones.

View File

@ -90,7 +90,7 @@ _No parameters._
### Users.GetUserInfo
<span class="badge perm-none">PUBLIC</span>
<span class="badge perm-none">AUTH</span>
Get info about the current token (the currently logged in user).

View File

@ -44,7 +44,7 @@ Feld `id` (Ganzzahl), um die Antwort zuzuordnen. Benachrichtigungen haben kein `
| Badge | Scope | Beschreibung |
| --- | --- | --- |
| <span class="badge perm-none">PUBLIC</span> | `PermissionScopeNone` | Öffentlich lesbar, kein Token nötig |
| <span class="badge perm-none">AUTH</span> | `PermissionScopeNone` | Jedes angemeldete Konto (Token nötig, sobald der Transport Authentifizierung verlangt; nur `JSONRPC.Hello`, `Authenticate` und `RequestPushButtonAuth` gehen ohne) |
| <span class="badge perm-control">CONTROL</span> | `PermissionScopeControlThings` / `ExecuteRules` | Steuerung von Geräten und Regeln |
| <span class="badge perm-configure">CONFIGURE</span> | `PermissionScopeConfigureThings` / `ConfigureRules` | Konfiguration von Integrationen und Regeln |
| <span class="badge perm-admin">ADMIN</span> | `PermissionScopeAdmin` | Systemadministration |

View File

@ -44,7 +44,7 @@ Every message is a JSON object terminated by `\n`. Requests carry an `id` field
| Badge | Scope | Description |
| --- | --- | --- |
| <span class="badge perm-none">PUBLIC</span> | `PermissionScopeNone` | Public read, no token required |
| <span class="badge perm-none">AUTH</span> | `PermissionScopeNone` | Any authenticated account (token required whenever the transport requires authentication; only `JSONRPC.Hello`, `Authenticate` and `RequestPushButtonAuth` work without one) |
| <span class="badge perm-control">CONTROL</span> | `PermissionScopeControlThings` / `ExecuteRules` | Control of things and rules |
| <span class="badge perm-configure">CONFIGURE</span> | `PermissionScopeConfigureThings` / `ConfigureRules` | Configuration of integrations and rules |
| <span class="badge perm-admin">ADMIN</span> | `PermissionScopeAdmin` | System administration |

View File

@ -43,7 +43,7 @@ Chaque message est un objet JSON terminé par `\n`. Les requêtes incluent un ch
| Badge | Scope | Description |
| --- | --- | --- |
| <span class="badge perm-none">PUBLIC</span> | `PermissionScopeNone` | Lecture publique, aucun token requis |
| <span class="badge perm-none">AUTH</span> | `PermissionScopeNone` | Tout compte authentifié (token requis dès que le transport exige l'authentification ; seuls `JSONRPC.Hello`, `Authenticate` et `RequestPushButtonAuth` passent sans) |
| <span class="badge perm-control">CONTROL</span> | `PermissionScopeControlThings` / `ExecuteRules` | Contrôle des appareils et règles |
| <span class="badge perm-configure">CONFIGURE</span> | `PermissionScopeConfigureThings` / `ConfigureRules` | Configuration des intégrations et règles |
| <span class="badge perm-admin">ADMIN</span> | `PermissionScopeAdmin` | Administration système |

View File

@ -1926,7 +1926,7 @@
"NymeaEnergy.GetAcquisitionTolerance": {
"description": "Get the acquisition tolerance. This value will control how much solar surplus is required to start the charging.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"acquisitionTolerance": "Double"
}
@ -1934,7 +1934,7 @@
"NymeaEnergy.GetAvailableSpotMarketProviders": {
"description": "Get the list of available spot market data providers.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"providers": [
"$ref:SpotMarketProviderInfo"
@ -1944,7 +1944,7 @@
"NymeaEnergy.GetBatteryLevelConsideration": {
"description": "Get the battery level consideration. This value will control how much the energy storage is taking in account",
"params": {},
"permissionScope": "PermissionScopeAdmin",
"permissionScope": "PermissionScopeNone",
"returns": {
"batteryLevelConsideration": "Double"
}
@ -1954,7 +1954,7 @@
"params": {
"o:evChargerId": "Uuid"
},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"chargingInfos": [
"$ref:ChargingInfo"
@ -1964,7 +1964,7 @@
"NymeaEnergy.GetChargingSchedules": {
"description": "Get the planed charging schedules, and whether the L2 degraded mode is currently active (meter silent > 90s, planning suspended).",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"chargingSchedules": [
"$ref:ChargingSchedule"
@ -1975,7 +1975,7 @@
"NymeaEnergy.GetEnergyRatios": {
"description": "Get the current energy ratios (self-consumption / autonomy) in percent, derived from the energy manager's cumulative counters over the current local day. A rate field is omitted (never null) when not available (denominator <= 0).",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"measuredSince": "Uint",
"o:autonomyRate": "Double",
@ -1987,7 +1987,7 @@
"NymeaEnergy.GetForecastSite": {
"description": "Read which site's PV forecast is kept, and which sites COULD be. 'forecastSiteThingId' is omitted when none is designated - a NORMAL state, not a fault. 'candidateSiteThingIds' lists every site with at least one plane publishing a curve; it is what a configuration screen offers. When exactly one candidate exists and nothing has ever been chosen, the engine designates it by itself - designating is not CHOOSING when there is nothing to choose. NOTHING is ever designated automatically: the choice is persisted, and the day a second site appears it would look deliberate when nobody made it. 'fault' carries MISSING_FORECAST_SITE when planes publish but no site is designated - it is ABSENT when no site exists at all, since announcing a missing designation to an installation that has nothing to designate would be an unsatisfiable warning.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"candidateSiteThingIds": [
"Uuid"
@ -2000,7 +2000,7 @@
"NymeaEnergy.GetForecastSnapshot": {
"description": "The CURRENT PV forecast, read straight from the channel - never from the stored table. GetPvForecast serves the TABLE (history, revisions, reproducible reads); this one serves the DECISION. An arbiter reading the table would read its own trace instead of its input: it would no longer measure, it would re-read itself. 'capturedAt' is when this reply was built. 'contentChangedAt' is when the current content FIRST APPEARED - and it is the one that matters: without it, a FROZEN provider reads as a stable forecast, which is the costliest form of 'silence that looks like a result' since whoever reads it decides to BUY. It is omitted when the store has never seen this content, rather than guessed. 'forecastPoints' is ABSENT when nothing is readable - never a curve of zeros; a missing forecast and a forecast of zero are different statements. 'fault' carries MISSING_FORECAST_SITE (nobody designated a site, and one exists) or FORECAST_PAYLOAD_REFUSED with its cause (the channel publishes something we cannot read). Two faults, two gestures: configure, or look at the provider. With a curve come 'corrections' (physical corrections applied, canonical order: 'temperature' by the provider, 'ac-limit' when the site has an AC limit; empty = raw GTI x kWp x PR; when planes disagree, only the corrections ALL of them received), 'perField' (one entry per summed plane: its thing 'id' and the 'corrections' it declared - where a divergence between planes is read), 'conversion' ('physics' - this engine has no other) and 'acLimitW' when an AC limit is configured: the curve is the sum of the planes CLIPPED to it. ALWAYS (ETM build), whatever the PV outcome: the GRID 'start' (instant), 'resolutionS' and 'steps' - the PV grid when a curve exists (first slot to last, holes included), otherwise hourly from local midnight today to local midnight after tomorrow - and on it, index by index: 'baseload' {model: profile|none, p50W: [W or null], quality} - consumption WITHOUT the controlled loads, median per local slot and day type over 28 days, 'none' with nulls under 7 covered days - and 'price' (null when no tariff is set) {currency, importCtkWh, exportCtkWh, includes, source: fixed|tou, knownUntil}. A slot straddling two tariff zones gets the time-weighted mean. NOTHING here is read by any decision.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"capturedAt": "String",
"o:acLimitW": "Uint",
@ -2043,7 +2043,7 @@
"NymeaEnergy.GetLoadConfig": {
"description": "Get the configured controllable loads (etmvariableload).",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"loadConfigs": [
"$ref:LoadConfig"
@ -2053,7 +2053,7 @@
"NymeaEnergy.GetLoadTelemetry": {
"description": "Get a snapshot of the arbitration runtime state: surplus budget, per-load allocation, availability, fault code, active lock (seconds remaining), mechanism payload and decision reason. Reason and fault are CODES with numeric params - never human-readable sentences: the client renders them in the user's language. Identical payload to the LoadTelemetryChanged notification. 'timestamp' is the end of the last arbitration cycle and is omitted while no cycle has run yet.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"degradedMode": "Bool",
"loads": [
@ -2127,15 +2127,24 @@
"NymeaEnergy.GetLockOnUnplug": {
"description": "Get the lock on unplug setting.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"lockOnUnplug": "Bool"
}
},
"NymeaEnergy.GetOptimizerProtocol": {
"description": "The OpenRPC 1.3 document of the engine <-> optimizer protocol spoken by THIS engine (docs/etm-powersync-optimizer-protocol.openrpc.json, embedded at build time). protocolVersion: the version sent at handshake. schema: the document (methods Handshake, GetPlan, UpdateLearned; components.schemas; x-etm-* extensions for transport, fallback machine and semantic rules). No secret. Static for a given binary: no notification.",
"params": {},
"permissionScope": "PermissionScopeNone",
"returns": {
"protocolVersion": "String",
"schema": "Object"
}
},
"NymeaEnergy.GetOptimizerStatus": {
"description": "State of the external-optimizer fallback machine (OPTIMIZER_PROTOCOL 7). optimizerExpected: an endpoint is configured. optimizerAlive: the optimizer answered with a valid plan and has not failed two consecutive requests nor lost its connection since. activeStrategy: optimizer | rules | none (none = degraded mode L2, planning suspended). The other fields are for the installer view; an unknown value is OMITTED, never 0. The token is never returned: tokenConfigured only says whether one is set. Same payload as OptimizerStatusChanged.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"activeStrategy": "String",
"o:capabilities": {
@ -2173,7 +2182,7 @@
"NymeaEnergy.GetPhasePowerLimit": {
"description": "Get the phase power consumption limit. 0 if unset. This needs to be set in order for the smart charging to do anything.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"phasePowerLimit": "Uint"
}
@ -2181,7 +2190,7 @@
"NymeaEnergy.GetPlan": {
"description": "The plan IN FORCE at the last planned cycle. Under an optimizer: the current slot with the power APPLIED by the adapters, then the following slots with the power REQUESTED (informative). Under the rule-based: one slot, strategy rules, and fallbackCode when an optimizer is configured but did not command this cycle. Reasons are codes and params only, never text. inForce is false, and nothing else is returned, before the first cycle and in degraded mode L2 (no plan in force). No notification: read it again on LoadTelemetryChanged or OptimizerStatusChanged.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"inForce": "Bool",
"o:computedAt": "String",
@ -2215,7 +2224,7 @@
"o:knownAt": "String",
"to": "String"
},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"energyError": "$ref:EnergyError",
"forecastPoints": [
@ -2233,7 +2242,7 @@
"NymeaEnergy.GetSpotMarketConfiguration": {
"description": "Get the current spotmarket configuration.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"available": "Bool",
"enabled": "Bool",
@ -2243,7 +2252,7 @@
"NymeaEnergy.GetSpotMarketScoreEntries": {
"description": "Get the current score entries from the current spot market. If spot market is not enabled or not available, the list will be empty. The weighting of the available score entries goes from 0 (worst) to 1.0 (best).",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"spotMarketScoreEntries": [
"$ref:ScoreEntry"
@ -2253,7 +2262,7 @@
"NymeaEnergy.GetTariff": {
"description": "The tariff entered by the installer. 'zones', 'exportCtkWh' and 'source' (fixed = one zone over 24 h, tou = several) are OMITTED when no tariff is set - never an empty tariff at 0. Ranges are LOCAL wall-clock times of the box, in 'timeZone' (IANA id, always returned): the phone may live in another zone. Prices are FULL prices paid, in c\u20ac/kWh incl. taxes ('includes'). Read by no decision.",
"params": {},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeNone",
"returns": {
"currency": "String",
"includes": [
@ -2281,7 +2290,7 @@
"params": {
"acquisitionTolerance": "Double"
},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeConfigureThings",
"returns": {
"energyError": "$ref:EnergyError"
}
@ -2312,7 +2321,7 @@
"o:acLimitW": "Variant",
"o:forecastSiteThingId": "Uuid"
},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeConfigureThings",
"returns": {
"energyError": "$ref:EnergyError"
}
@ -2366,7 +2375,7 @@
}
]
},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeConfigureThings",
"returns": {
"energyError": "$ref:EnergyError"
}
@ -2444,7 +2453,7 @@
"enabled": "Bool",
"o:providerId": "Uuid"
},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeConfigureThings",
"returns": {
"energyError": "$ref:EnergyError",
"o:fault": "String"
@ -2467,7 +2476,7 @@
}
]
},
"permissionScope": "PermissionScopeControlThings",
"permissionScope": "PermissionScopeConfigureThings",
"returns": {
"energyError": "$ref:EnergyError",
"o:fault": "String",

View File

@ -49,7 +49,7 @@ NS_SYSTEM = set(NS_SYSTEM_ORDER)
PERM_BADGES: dict[str, str] = {
"PermissionScopeNone":
'<span class="badge perm-none">PUBLIC</span>',
'<span class="badge perm-none">AUTH</span>',
"PermissionScopeControlThings":
'<span class="badge perm-control">CONTROL</span>',
"PermissionScopeExecuteRules":
@ -422,7 +422,7 @@ ETM PowerSync expose l'**API JSON-RPC de nymea** en local, y compris les extensi
| Badge | Scope | Description |
| --- | --- | --- |
| <span class="badge perm-none">PUBLIC</span> | `PermissionScopeNone` | Lecture publique, aucun token requis |
| <span class="badge perm-none">AUTH</span> | `PermissionScopeNone` | Tout compte authentifié (token requis dès que le transport exige l'authentification ; seuls `JSONRPC.Hello`, `Authenticate` et `RequestPushButtonAuth` passent sans) |
| <span class="badge perm-control">CONTROL</span> | `PermissionScopeControlThings` / `ExecuteRules` | Contrôle des appareils et règles |
| <span class="badge perm-configure">CONFIGURE</span> | `PermissionScopeConfigureThings` / `ConfigureRules` | Configuration |
| <span class="badge perm-admin">ADMIN</span> | `PermissionScopeAdmin` | Administration système |