Report helpers for every tier-1 property, asset ids, AlexaCapability::isValid()
AlexaStatusMessage gets a helper for color, percentage, power level, range, mode, lock state, contact, motion, humidity and the thermostat (target, lower and upper setpoint, mode), and addProperty(row, place, value) for a property without one. Each is a function of its own on one shared builder; a value outside of the range of its property is reported as the nearest of the range with an error. AlexaResources.h holds the 103 asset ids of resources-and-assets.html (AlexaAssets, AlexaUnits); AlexaState has the seven states that were missing; addStateMapping() takes a number of any type. A setter that refuses its argument makes isValid() false, and the capability is left out of discovery with an error instead of being announced without what was refused. basicLight: static RAM 30,520 B (was 30,540), flash 333,389 B (was 334,981); 130 host tests (was 112). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
3215457f91
commit
77156ffbe5
10 changed files with 995 additions and 100 deletions
|
|
@ -9,6 +9,7 @@
|
|||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include "AlexaInterfaces.h"
|
||||
#include "AlexaLimits.h"
|
||||
|
||||
|
|
@ -23,11 +24,19 @@ enum class AlexaAction : uint8_t
|
|||
SetEcoOff
|
||||
};
|
||||
|
||||
// What Alexa says about the device: "the blind is open" (alexa-discovery-objects.html#state-mapping)
|
||||
// What Alexa says about the device: "the blind is open" (alexa-discovery-objects.html#state-mapping). EcoOn and
|
||||
// EcoOff are for a ToggleController; Low, Empty, Full, Done and Stuck are what Alexa announces a device for.
|
||||
enum class AlexaState : uint8_t
|
||||
{
|
||||
Open,
|
||||
Closed
|
||||
Closed,
|
||||
EcoOn,
|
||||
EcoOff,
|
||||
Low,
|
||||
Empty,
|
||||
Full,
|
||||
Done,
|
||||
Stuck
|
||||
};
|
||||
|
||||
// "Alexa.Actions.Open", in program memory
|
||||
|
|
@ -74,7 +83,9 @@ struct AlexaCapabilityName
|
|||
// 116 bytes on the heap of an ESP8266, whatever the capability holds. Every setter returns the capability:
|
||||
// device->addCapability(AlexaInterfaces::RangeController, "Blind.Lift")
|
||||
// ->addFriendlyName("Lift", "en-US").setConfiguration(fillLift).addStateMapping({AlexaState::Closed}, 0.0f);
|
||||
// What a capability refuses is printed at ERROR with what to change, and leaves the capability as it was.
|
||||
// What a capability refuses is printed at ERROR with what to change, and leaves the capability as it was. The
|
||||
// chain goes on after a call that was refused; isValid() is false from then on, and the device leaves the
|
||||
// capability out of discovery, where Alexa would otherwise learn half of it.
|
||||
class AlexaCapability
|
||||
{
|
||||
public:
|
||||
|
|
@ -97,6 +108,9 @@ public:
|
|||
bool isProactivelyReported() const { return proactivelyReported; }
|
||||
bool isNonControllable() const { return nonControllable; }
|
||||
|
||||
// false when a setter has refused what it was given. The reason was printed when it happened.
|
||||
bool isValid() const { return valid; }
|
||||
|
||||
// The instance tells the capabilities of one interface on a device apart ("Blind.Lift", "Blind.Tilt"). It is
|
||||
// copied. addCapability(row, instance) sets it; this is for a capability that was added by its type.
|
||||
AlexaCapability &setInstance(const char *instance);
|
||||
|
|
@ -104,7 +118,8 @@ public:
|
|||
// A name of the capability in words. The text is copied, the locale ("en-US") is not: pass a literal.
|
||||
AlexaCapability &addFriendlyName(const char *text, const char *locale);
|
||||
|
||||
// A name from the catalog of Alexa, which Alexa translates: PSTR("Alexa.Setting.Opening"). Not copied.
|
||||
// A name from the catalog of Alexa, which Alexa translates: AlexaAssets::Setting_Opening of AlexaResources.h,
|
||||
// or PSTR("Alexa.Setting.Opening"). Not copied.
|
||||
AlexaCapability &addFriendlyAsset(PGM_P assetId);
|
||||
|
||||
AlexaCapability &setRetrievable(bool value);
|
||||
|
|
@ -124,13 +139,21 @@ public:
|
|||
AlexaCapability &addStateMapping(std::initializer_list<AlexaState> states, float minimum, float maximum);
|
||||
AlexaCapability &addStateMapping(std::initializer_list<AlexaState> states, const char *value);
|
||||
|
||||
// A number of another type, addStateMapping({AlexaState::Closed}, 0): without this a 0 is as much a text
|
||||
// that is missing as it is a number, and the call does not compile
|
||||
template <typename Number, typename = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
|
||||
AlexaCapability &addStateMapping(std::initializer_list<AlexaState> states, Number value)
|
||||
{
|
||||
return addStateMapping(states, static_cast<float>(value));
|
||||
}
|
||||
|
||||
// Whether a directive with this namespace and instance is for this capability. The instance counts only
|
||||
// for an interface that has instances.
|
||||
bool matches(const char *ns, const char *directiveInstance) const;
|
||||
|
||||
// Adds the discovery object of the capability to the capabilities of its endpoint. A capability that Alexa
|
||||
// would reject the endpoint for, a generic controller without an instance or without a name, adds nothing,
|
||||
// prints what is missing and returns false.
|
||||
// prints what is missing and returns false. So does one that is not valid.
|
||||
bool toJson(JsonArray capabilities, const char *endpointId) const;
|
||||
|
||||
private:
|
||||
|
|
@ -149,8 +172,8 @@ private:
|
|||
|
||||
struct StateMapping
|
||||
{
|
||||
uint8_t states; // one bit per AlexaState
|
||||
uint8_t kind; // StateMappingKind
|
||||
uint16_t states; // one bit per AlexaState
|
||||
uint8_t kind; // StateMappingKind
|
||||
union
|
||||
{
|
||||
float value; // the value, or the lowest of a range
|
||||
|
|
@ -160,6 +183,7 @@ private:
|
|||
};
|
||||
|
||||
StateMapping *newStateMapping(std::initializer_list<AlexaState> states, StateMappingKind kind);
|
||||
AlexaCapability &refused();
|
||||
void writeSemantics(JsonObject capability) const;
|
||||
void writeNames(JsonObject capability) const;
|
||||
|
||||
|
|
@ -176,6 +200,7 @@ private:
|
|||
bool retrievable : 1;
|
||||
bool proactivelyReported : 1;
|
||||
bool nonControllable : 1;
|
||||
bool valid : 1;
|
||||
};
|
||||
|
||||
#endif // ALEXA_CAPABILITY_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue