From 6f765e89886544b3a20f02451b7a1068995b6359 Mon Sep 17 00:00:00 2001 From: Gregg Date: Sun, 7 Nov 2021 20:45:44 -0600 Subject: [PATCH 01/17] Added non-notify option to setVal() Second optional argument to setVal() determines whether or not HomeSpan sends notification of new value to HomeKit. Default if left blank is "true" for backwards compatibility. --- src/HomeSpan.h | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 299c0b8..fed75c0 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -534,7 +534,7 @@ struct SpanCharacteristic{ } // setString() - template void setVal(T val){ + template void setVal(T val, boolean notify=true){ if((perms & EV) == 0){ Serial.printf("\n*** WARNING: Attempt to update Characteristic::%s with setVal() ignored. No NOTIFICATION permission on this characteristic\n\n",hapName); @@ -550,17 +550,19 @@ struct SpanCharacteristic{ uvSet(newValue,value); updateTime=homeSpan.snapTime; - - SpanBuf sb; // create SpanBuf object - sb.characteristic=this; // set characteristic - sb.status=StatusCode::OK; // set status - char dummy[]=""; - sb.val=dummy; // set dummy "val" so that sprintfNotify knows to consider this "update" - homeSpan.Notifications.push_back(sb); // store SpanBuf in Notifications vector - if(nvsKey){ - nvs_set_blob(homeSpan.charNVS,nvsKey,&value,sizeof(UVal)); // store data - nvs_commit(homeSpan.charNVS); + if(notify){ + SpanBuf sb; // create SpanBuf object + sb.characteristic=this; // set characteristic + sb.status=StatusCode::OK; // set status + char dummy[]=""; + sb.val=dummy; // set dummy "val" so that sprintfNotify knows to consider this "update" + homeSpan.Notifications.push_back(sb); // store SpanBuf in Notifications vector + + if(nvsKey){ + nvs_set_blob(homeSpan.charNVS,nvsKey,&value,sizeof(UVal)); // store data + nvs_commit(homeSpan.charNVS); + } } } // setVal() From 9de26715f022ab8abd879399360414efd397f916 Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Mon, 8 Nov 2021 05:50:30 -0600 Subject: [PATCH 02/17] Update Reference.md --- docs/Reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Reference.md b/docs/Reference.md index 025c11d..144f885 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -201,8 +201,8 @@ The following methods are supported: * `boolean updated()` * returns *true* if a HomeKit Controller has requested an update to the value of the Characteristic, otherwise *false*. The requested value itself can retrieved with `getNewVal<>()` -* `void setVal(value)` - * sets the value of the Characteristic to *value*, and notifies all HomeKit Controllers of the change +* `void setVal(value [,boolean notify])` + * sets the value of the Characteristic to *value*, and, if *notify* is set to true, notifies all HomeKit Controllers of the change. The *notify* flag is optional and will be set to true if not specified. Setting the *notify* flag to false allows you to update a Characateristic without notifying any HomeKit Controllers, which is useful for Characteristics that HomeKit automatically adjusts (such as a countdown timer) but will be requested from the Accessory if the Home App closes and is then re-opened * works with any integer, boolean, or floating-based numerical *value*, though HomeSpan will convert *value* into the appropriate type for each Characteristic (e.g. calling `setValue(5.5)` on an integer-based Characteristic results in *value*=5) * throws a runtime warning if *value* is outside of the min/max range for the Characteristic, where min/max is either the HAP default, or any new min/max range set via a prior call to `setRange()` * *value* is **not** restricted to being an increment of the step size; for example it is perfectly valid to call `setVal(43.5)` after calling `setRange(0,100,5)` on a floating-based Characteristic even though 43.5 does does not align with the step size specified. The Home App will properly retain the value as 43.5, though it will round to the nearest step size increment (in this case 45) when used in a slider graphic (such as setting the temperature of a thermostat) From 3f833beb74e062dd0cd96b1f43c194162202bdaf Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Tue, 9 Nov 2021 21:08:52 -0600 Subject: [PATCH 03/17] Added ability to change permissions for Characteristics New methods for Characteristics: setPerms(uint8_t perms); addPerms(uint8_t dPerms); removePerms(uint8_t dPerms); where perms and dPerms = PR|PW|EV... --- src/HomeSpan.h | 31 +++++++++++++++++++++++++++++++ src/src.ino | 1 + 2 files changed, 32 insertions(+) diff --git a/src/HomeSpan.h b/src/HomeSpan.h index fed75c0..fc0a2fc 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -566,7 +566,38 @@ struct SpanCharacteristic{ } } // setVal() + + SpanCharacteristic *setPerms(uint8_t perms){ + this->perms=perms; + homeSpan.configLog+=String(" \u2b0c Change Permissions for ") + String(hapName) + " with AID=" + String(aid) + ", IID=" + String(iid) + ":"; + + char pNames[][7]={"PR","PW","EV","AA","TW","HD","WR"}; + char sep=' '; + + for(uint8_t i=0;i<7;i++){ + if(perms & (1<addPerms(PW+AA)->removePerms(EV+PR); } // end of setup() From fcf715d8745401d93a3d6717bf55cb559258879e Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Tue, 9 Nov 2021 21:18:34 -0600 Subject: [PATCH 04/17] Added getLinks() method to SpanServices This returns a vector of linked Services that can be used in a for-each loop as such: for(auto services : getLinks()){ ... } Must cast services into specific Service type to access anything not generic to the SpanService class --- src/HomeSpan.h | 2 +- src/src.ino | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/HomeSpan.h b/src/HomeSpan.h index fc0a2fc..481e7f7 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -225,6 +225,7 @@ struct SpanService{ SpanService *setPrimary(); // sets the Service Type to be primary and returns pointer to self SpanService *setHidden(); // sets the Service Type to be hidden and returns pointer to self SpanService *addLink(SpanService *svc); // adds svc as a Linked Service and returns pointer to self + vector getLinks(){return(linkedServices);} // returns linkedServices vector for use as range in "for-each" loops int sprintfAttributes(char *cBuf); // prints Service JSON records into buf; return number of characters printed, excluding null terminator void validate(); // error-checks Service @@ -238,7 +239,6 @@ struct SpanService{ struct SpanCharacteristic{ - union UVal { BOOL_t BOOL; UINT8_t UINT8; diff --git a/src/src.ino b/src/src.ino index 2d66f71..df75ea3 100644 --- a/src/src.ino +++ b/src/src.ino @@ -74,7 +74,7 @@ void setup() { new Characteristic::Name("Light 3"); new Characteristic::TargetPosition(); new Characteristic::OzoneDensity(); - (new Characteristic::OzoneDensity())->addPerms(PW+AA)->removePerms(EV+PR); + (new Characteristic::OzoneDensity())->addPerms(PW|AA)->removePerms(EV|PR); } // end of setup() From b5f4592b2916cd5624632e839c7ef7c4a7f08be7 Mon Sep 17 00:00:00 2001 From: Gregg Date: Wed, 10 Nov 2021 05:54:19 -0600 Subject: [PATCH 05/17] Removed Characteristic::ConfiguredNameStatic() end updated Television Example Characteristic::ConfiguredNameStatic() is no longer needed since you can now change permissions on ConfiguredStatic to remove PW with removePerms(PW). Updated Television Example accordingly. To Do: Add getLinks() and setPerms/addPerms/removePerms to API Reference Documentation --- Other Examples/Television/Television.ino | 2 +- src/Characteristics.h | 1 - src/Span.h | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Other Examples/Television/Television.ino b/Other Examples/Television/Television.ino index e745dbc..1d3fe58 100644 --- a/Other Examples/Television/Television.ino +++ b/Other Examples/Television/Television.ino @@ -193,7 +193,7 @@ void setup() { new Characteristic::TargetVisibilityState(0); SpanService *hdmi10 = new Service::InputSource(); - new Characteristic::ConfiguredNameStatic("HDMI 10"); // Source Name is static and cannot be edited in Settings Screen + (new Characteristic::ConfiguredName("HDMI 10"))->removePerms(PW); // Source Name permissions changed and now cannot be edited in Settings Screen new Characteristic::Identifier(10); new Characteristic::IsConfigured(1); // Source included in the Settings Screen... new Characteristic::CurrentVisibilityState(0); // ...and included in the Selection List... diff --git a/src/Characteristics.h b/src/Characteristics.h index 8b85fa2..dbb3424 100644 --- a/src/Characteristics.h +++ b/src/Characteristics.h @@ -94,7 +94,6 @@ struct HapCharacteristics { HAPCHAR( CoolingThresholdTemperature, D, PR+PW+EV, FLOAT, false ); HAPCHAR( ColorTemperature, CE, PR+PW+EV, UINT32, false ); HAPCHAR( ConfiguredName, E3, PW+PR+EV, STRING, false ); - HAPCHAR( ConfiguredNameStatic, E3, PR+EV, STRING, false ); HAPCHAR( ContactSensorState, 6A, PR+EV, UINT8, true ); HAPCHAR( CurrentAmbientLightLevel, 6B, PR+EV, FLOAT, false ); HAPCHAR( CurrentHorizontalTiltAngle, 6C, PR+EV, INT, false ); diff --git a/src/Span.h b/src/Span.h index 8af5e6b..e10c585 100644 --- a/src/Span.h +++ b/src/Span.h @@ -420,7 +420,6 @@ namespace Characteristic { CREATE_CHAR(uint32_t,ColorTemperature,200,140,500); CREATE_CHAR(uint8_t,ContactSensorState,1,0,1); CREATE_CHAR(const char *,ConfiguredName,"unnamed",0,1); - CREATE_CHAR(const char *,ConfiguredNameStatic,"unnamed",0,1); CREATE_CHAR(double,CurrentAmbientLightLevel,1,0.0001,100000); CREATE_CHAR(int,CurrentHorizontalTiltAngle,0,-90,90); CREATE_CHAR(uint8_t,CurrentAirPurifierState,1,0,2); From 6801dfe4c8ea24de478255cb7b6f9ad3f6a5840f Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Thu, 11 Nov 2021 20:57:02 -0600 Subject: [PATCH 06/17] Update Reference.md --- docs/Reference.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/Reference.md b/docs/Reference.md index 144f885..54a841c 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -159,6 +159,12 @@ The following methods are supported: * adds *svc* as a Linked Service. Returns a pointer to the calling Service itself so that the method can be chained during instantiation. * note that Linked Services are only applicable for select HAP Services. See Apple's [HAP-R2](https://developer.apple.com/support/homekit-accessory-protocol/) documentation for full details. * example: `(new Service::Faucet)->addLink(new Service::Valve)->addLink(new Service::Valve);` (links two Valves to a Faucet) + +* `vector getLinks()` + * returns a vector of pointers to Services that were added using `addLink()` + * useful for creating loops that iterate over all linked Services + * note that the returned vector points to generic SpanServices, which should be re-cast as needed + * example: `for(auto myValve : faucet::getLinks()) { if((MyValve *)myValve)->active->getVal()) ... }` checks all Valves linked to to a Faucet * `virtual boolean update()` * HomeSpan calls this method upon receiving a request from a HomeKit Controller to update one or more Characteristics associated with the Service. Users should override this method with code that implements that requested updates using one or more of the SpanCharacteristic methods below. Method **must** return *true* if update succeeds, or *false* if not. From 8ffb62715e6d1d7fb09712c5926ea78cf0c0b7d7 Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Thu, 11 Nov 2021 21:12:47 -0600 Subject: [PATCH 07/17] Update Reference.md --- docs/Reference.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/Reference.md b/docs/Reference.md index 54a841c..470a79e 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -234,6 +234,25 @@ The following methods are supported: * returns a pointer to the Characteristic itself so that the method can be chained during instantiation * example: `(new Characteristic::SecuritySystemTargetState())->setValidValues(3,0,1,3);` creates a new Valid Value list of length=3 containing the values 0, 1, and 3. This has the effect of informing HomeKit that a SecuritySystemTargetState value of 2 (Night Arm) is not valid and should not be shown as a choice in the Home App +* `SpanCharacteristic *setPerms(uint8_t perms)` + * changes the default permissions for a Characteristic to *perms*, where + * *perms* - additive list of permissions as described in HAP-R2 Table 6-4. Valid values are PR, PW, EV, AA, TW, HD, and WR + * returns a pointer to the Characteristic itself so that the method can be chained during instantiation + * example: `(new Characteristic::IsConfigured(1))->setPerms(PW+PR+EV);` + +* `SpanCharacteristic *addPerms(uint8_t perms)` + * adds new permissions, *perms*, to the default permissions for a Characteristic, where + * *perms* - additive list of permissions as described in HAP-R2 Table 6-4. Valid values are PR, PW, EV, AA, TW, HD, and WR + * returns a pointer to the Characteristic itself so that the method can be chained during instantiation + * example: `(new Characteristic::IsConfigured(1))->addPerms(PW);` + +* `SpanCharacteristic *removePerms(uint8_t perms)` + * removes permissions, *perms*, from the default permissions of a Characteristic, where + * *perms* - additive list of permissions as described in HAP-R2 Table 6-4. Valid values are PR, PW, EV, AA, TW, HD, and WR + * returns a pointer to the Characteristic itself so that the method can be chained during instantiation + * example: `(new Characteristic::ConfiguredName("HDMI 1"))->removePerms(PW);` + + ## *SpanButton(int pin, uint16_t longTime, uint16_t singleTime, uint16_t doubleTime)* Creating an instance of this **class** attaches a pushbutton handler to the ESP32 *pin* specified. From 8c93ac2e353999bb45272c5bb17a7bce0ee2173a Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Fri, 12 Nov 2021 06:58:06 -0600 Subject: [PATCH 08/17] Update Reference.md --- docs/Reference.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/Reference.md b/docs/Reference.md index 470a79e..7d4af90 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -235,20 +235,17 @@ The following methods are supported: * example: `(new Characteristic::SecuritySystemTargetState())->setValidValues(3,0,1,3);` creates a new Valid Value list of length=3 containing the values 0, 1, and 3. This has the effect of informing HomeKit that a SecuritySystemTargetState value of 2 (Night Arm) is not valid and should not be shown as a choice in the Home App * `SpanCharacteristic *setPerms(uint8_t perms)` - * changes the default permissions for a Characteristic to *perms*, where - * *perms* - additive list of permissions as described in HAP-R2 Table 6-4. Valid values are PR, PW, EV, AA, TW, HD, and WR + * changes the default permissions for a Characteristic to *perms*, where *perms* is an additive list of permissions as described in HAP-R2 Table 6-4. Valid values are PR, PW, EV, AA, TW, HD, and WR * returns a pointer to the Characteristic itself so that the method can be chained during instantiation * example: `(new Characteristic::IsConfigured(1))->setPerms(PW+PR+EV);` * `SpanCharacteristic *addPerms(uint8_t perms)` - * adds new permissions, *perms*, to the default permissions for a Characteristic, where - * *perms* - additive list of permissions as described in HAP-R2 Table 6-4. Valid values are PR, PW, EV, AA, TW, HD, and WR + * adds new permissions, *perms*, to the default permissions for a Characteristic, where *perms* is an additive list of permissions as described in HAP-R2 Table 6-4. Valid values are PR, PW, EV, AA, TW, HD, and WR * returns a pointer to the Characteristic itself so that the method can be chained during instantiation * example: `(new Characteristic::IsConfigured(1))->addPerms(PW);` * `SpanCharacteristic *removePerms(uint8_t perms)` - * removes permissions, *perms*, from the default permissions of a Characteristic, where - * *perms* - additive list of permissions as described in HAP-R2 Table 6-4. Valid values are PR, PW, EV, AA, TW, HD, and WR + * removes permissions, *perms*, from the default permissions of a Characteristic, where *perms* is an additive list of permissions as described in HAP-R2 Table 6-4. Valid values are PR, PW, EV, AA, TW, HD, and WR * returns a pointer to the Characteristic itself so that the method can be chained during instantiation * example: `(new Characteristic::ConfiguredName("HDMI 1"))->removePerms(PW);` From 48b21df3298820e338140d8f6f6490397cccd555 Mon Sep 17 00:00:00 2001 From: Gregg Date: Fri, 12 Nov 2021 18:01:27 -0600 Subject: [PATCH 09/17] Created method setPairingCode(const char *s) Allows for programmatic creation of Pairing Setup Code. Not recommended, but added for a convenience - should use 'S' from CLI instead. --- src/HAP.cpp | 6 +++++- src/HomeSpan.cpp | 4 ++-- src/HomeSpan.h | 3 +++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index 822f84e..a079b72 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -52,11 +52,15 @@ void HAPClient::init(){ otaPwdHash.getChars(homeSpan.otaPwd); } + if(strlen(homeSpan.pairingCodeCommand)){ // load verification setup code if provided + homeSpan.processSerialCommand(homeSpan.pairingCodeCommand); // if load failed due to invalid code, the logic below still runs and will pick up previous code or use the default one + } + struct { // temporary structure to hold SRP verification code and salt stored in NVS uint8_t salt[16]; uint8_t verifyCode[384]; } verifyData; - + if(!nvs_get_blob(srpNVS,"VERIFYDATA",NULL,&len)){ // if found verification code data in NVS nvs_get_blob(srpNVS,"VERIFYDATA",&verifyData,&len); // retrieve data srp.loadVerifyCode(verifyData.verifyCode,verifyData.salt); // load verification code and salt into SRP structure diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 3c2928e..f3af167 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -721,11 +721,11 @@ void Span::processSerialCommand(const char *c){ sscanf(c+1," %9[0-9]",setupCode); if(strlen(setupCode)!=8){ - Serial.print("\n*** Invalid request to change Setup Code. Code must be exactly 8 digits.\n"); + Serial.print("\n*** Invalid request to change Setup Code. Code must be exactly 8 digits.\n\n"); } else if(!network.allowedCode(setupCode)){ - Serial.print("\n*** Invalid request to change Setup Code. Code too simple.\n"); + Serial.print("\n*** Invalid request to change Setup Code. Code too simple.\n\n"); } else { sprintf(buf,"\n\nGenerating SRP verification data for new Setup Code: %.3s-%.2s-%.3s ... ",setupCode,setupCode+3,setupCode+5); diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 481e7f7..664d4b9 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -112,6 +112,7 @@ struct Span{ const char *sketchVersion="n/a"; // version of the sketch nvs_handle charNVS; // handle for non-volatile-storage of Characteristics data nvs_handle wifiNVS=0; // handle for non-volatile-storage of WiFi data + char pairingCodeCommand[12]=""; // user-specified Pairing Code - only needed if Pairing Setup Code is specified in sketch using setPairingCode() boolean connected=false; // WiFi connection status unsigned long waitTime=60000; // time to wait (in milliseconds) between WiFi connection attempts @@ -188,6 +189,8 @@ struct Span{ void setWifiCallback(void (*f)()){wifiCallback=f;} // sets an optional user-defined function to call once WiFi connectivity is established void setApFunction(void (*f)()){apFunction=f;} // sets an optional user-defined function to call when activating the WiFi Access Point + void setPairingCode(const char *s){sprintf(pairingCodeCommand,"S %9s",s);} // sets the Pairing Code - use is NOT recommended. Use 'S' from CLI instead + void enableAutoStartAP(){autoStartAPEnabled=true;} // enables auto start-up of Access Point when WiFi Credentials not found void setWifiCredentials(const char *ssid, const char *pwd); // sets WiFi Credentials }; From 07eaef9523d68a236a7ab32d174ffb42c1b94288 Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Fri, 12 Nov 2021 18:30:45 -0600 Subject: [PATCH 10/17] Update Reference.md --- docs/Reference.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/Reference.md b/docs/Reference.md index 7d4af90..9a74d7e 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -106,11 +106,17 @@ The following **optional** `homeSpan` methods enable additional features and pro * *ssid* and *pwd* are automatically saved in HomeSpan's non-volatile storage (NVS) for retrieval when the device restarts * note that the saved values are truncated if they exceed the maximum allowable characters (ssid=32; pwd=64) -> :warning: SECURITY WARNING: The purpose of this function is to allow advanced users to *dynamically* set the device's WiFi Credentials using a customized Access Point function specified by `setApFunction(func)`. It it NOT recommended to use this function to hardcode your WiFi SSID and password directly into your sketch. Instead, use one of the more secure methods provided by HomeSpan, such as typing 'W' from the CLI, or launching HomeSpan's Access Point by typing 'A' from the CLI, to set your WiFi credentials without hardcoding them into your sketch. +> :warning: SECURITY WARNING: The purpose of this function is to allow advanced users to *dynamically* set the device's WiFi Credentials using a customized Access Point function specified by `setApFunction(func)`. It it NOT recommended to use this function to hardcode your WiFi SSID and password directly into your sketch. Instead, use one of the more secure methods provided by HomeSpan, such as typing 'W' from the CLI, or launching HomeSpan's Access Point, to set your WiFi credentials without hardcoding them into your sketch * `void setWifiCallback(void (*func)())` * Sets an optional user-defined callback function, *func*, to be called by HomeSpan upon start-up just after WiFi connectivity has been established. This one-time call to *func* is provided for users that are implementing other network-related services as part of their sketch, but that cannot be started until WiFi connectivity is established. The function *func* must be of type *void* and have no arguments +* `void setPairingCode(const char *s)` + * sets the Setup Pairing Code to *s*, which **must** be exactly eight numerical digits (no dashes) + * a hashed version of the Pairing Code will be saved to the device's non-volatile storage, overwriting any currently-stored Pairing Code + * if *s* contains an invalid code, an error will be reported and the code will *not* be saved. Instead, the currently-stored Pairing Code (or the HomeSpan default Pairing Code if no code has been stored) will be used + * :exclamation: SECURTY WARNING: Hardcoding a device's Pairing Code into your sketch is considered a security risk and is **not** recommended. Instead, use one of the more secure methods provided by HomeSpan, such as typing 'S \' from the CLI, or launching HomeSpan's Access Point, to set your Pairing Code without hardcoding it into your sketch + * `void setSketchVersion(const char *sVer)` * sets the version of a HomeSpan sketch to *sVer*, which can be any arbitrary character string * if unspecified, HomeSpan uses "n/a" as the default version text From a8e6e643f96e4a41e2a9f7c2b2715ed5db80f495 Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Fri, 12 Nov 2021 18:40:21 -0600 Subject: [PATCH 11/17] Update Reference.md --- docs/Reference.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Reference.md b/docs/Reference.md index 9a74d7e..cb7e88d 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -113,6 +113,7 @@ The following **optional** `homeSpan` methods enable additional features and pro * `void setPairingCode(const char *s)` * sets the Setup Pairing Code to *s*, which **must** be exactly eight numerical digits (no dashes) + * example: `homeSpan.setPairingCode("46637726");` * a hashed version of the Pairing Code will be saved to the device's non-volatile storage, overwriting any currently-stored Pairing Code * if *s* contains an invalid code, an error will be reported and the code will *not* be saved. Instead, the currently-stored Pairing Code (or the HomeSpan default Pairing Code if no code has been stored) will be used * :exclamation: SECURTY WARNING: Hardcoding a device's Pairing Code into your sketch is considered a security risk and is **not** recommended. Instead, use one of the more secure methods provided by HomeSpan, such as typing 'S \' from the CLI, or launching HomeSpan's Access Point, to set your Pairing Code without hardcoding it into your sketch From d8bb51902f77ef48ec6757a97808d9ea05b7e5ae Mon Sep 17 00:00:00 2001 From: Gregg Date: Wed, 24 Nov 2021 18:27:55 -0600 Subject: [PATCH 12/17] Fixed Bug in TimedWrites The loop over TimedWrites incorrectly erased iterators inside a for-loop. For some reason this never caused an issue on the ESP32, but crashed on the ESP32-C3. Solution is to change the for-loop to a while-loop with proper handling of the iterator when an element is deleted. This appears to fix the problem. --- src/HAP.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index a079b72..2120511 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -1285,14 +1285,18 @@ void HAPClient::checkTimedWrites(){ unsigned long cTime=millis(); // get current time char c[64]; - - for(auto tw=homeSpan.TimedWrites.begin(); tw!=homeSpan.TimedWrites.end(); tw++){ // loop over all Timed Writes using an iterator + + auto tw=homeSpan.TimedWrites.begin(); + while(tw!=homeSpan.TimedWrites.end()){ if(cTime>tw->second){ // timer has expired sprintf(c,"Removing PID=%llu ALARM=%u\n",tw->first,tw->second); LOG2(c); - homeSpan.TimedWrites.erase(tw); + tw=homeSpan.TimedWrites.erase(tw); } + else + tw++; } + } ////////////////////////////////////// From 83170306f5e77b4585e04ea41397ee42ea0068ab Mon Sep 17 00:00:00 2001 From: Gregg Date: Thu, 25 Nov 2021 10:03:57 -0600 Subject: [PATCH 13/17] Updated Blinker class for compatibility with Arduino-ESP32 v2.0.1 The update from Arduino-ESP32 2.0.0 to 2.0.1 contained significant changes to the structures used by the IDF for generic timers. This broke the Blinker code (would not compile for ESP32-S2 and C3 chips). The solution: Modified Blinker::isrTimer() to use a *generic* interrupt-clearing function when available (IDF version >= 4.0.0). Below 4.0.0 the code continues to manually clear the interrupt flag by resetting specific structure variables, though the logic is simpler since this is only needed for the ESP32 chip (the S2 and C3 are not supported in earlier versions of Arduino-ESP32). This provides for full compatibility with Arduino-ESP32 versions 2.0.1, 2.0.0, and 1.0.6. The use of a generic interrupt clearing function when IDF>=4.0.0 will hopefully make this future-proof to any further changes by Espressif to the underlying timer structures. --- src/Utils.cpp | 24 ++++-------------------- src/src.ino | 2 +- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/src/Utils.cpp b/src/Utils.cpp index 15de921..e6f5294 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -279,7 +279,9 @@ void Blinker::isrTimer(void *arg){ Blinker *b=(Blinker *)arg; -#if CONFIG_IDF_TARGET_ESP32 +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0) // use new method that is generic to ESP32, S2, and C3 + timer_group_clr_intr_status_in_isr(b->group,b->idx); +#else // use older method that is only for ESP32 if(b->group){ if(b->idx) TIMERG1.int_clr_timers.t1=1; @@ -291,26 +293,8 @@ void Blinker::isrTimer(void *arg){ else TIMERG0.int_clr_timers.t0=1; } -#elif CONFIG_IDF_TARGET_ESP32S2 // for some reason, the ESP32-S2 and ESP32-C3 use "int_clr" instead of "int_clr_timers" in their timer structure - if(b->group){ - if(b->idx) - TIMERG1.int_clr.t1=1; - else - TIMERG1.int_clr.t0=1; - } else { - if(b->idx) - TIMERG0.int_clr.t1=1; - else - TIMERG0.int_clr.t0=1; - } -#elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3 only has one timer per timer group - if(b->group){ - TIMERG1.int_clr.t0=1; - } else { - TIMERG0.int_clr.t0=1; - } #endif - + if(!digitalRead(b->pin)){ digitalWrite(b->pin,1); timer_set_alarm_value(b->group,b->idx,b->onTime); diff --git a/src/src.ino b/src/src.ino index df75ea3..e90df18 100644 --- a/src/src.ino +++ b/src/src.ino @@ -11,7 +11,7 @@ void setup() { Serial.begin(115200); homeSpan.setLogLevel(2); - homeSpan.setStatusPin(5); + homeSpan.setStatusPin(13); homeSpan.setControlPin(33); homeSpan.setHostNameSuffix("-lamp1"); From bc5299cf573b3bd3ce2735540bee4aa314d4809d Mon Sep 17 00:00:00 2001 From: Gregg Date: Sat, 27 Nov 2021 09:48:07 -0600 Subject: [PATCH 14/17] Updated version number to 1.4.2 Ready for release! --- library.properties | 2 +- src/Settings.h | 2 +- src/src.ino | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.properties b/library.properties index 274ff4b..42657a9 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=HomeSpan -version=1.4.1 +version=1.4.2 author=Gregg maintainer=Gregg sentence=A robust and extremely easy-to-use HomeKit implementation for the Espressif ESP32 running on the Arduino IDE. diff --git a/src/Settings.h b/src/Settings.h index 037c60b..fa694be 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -36,7 +36,7 @@ #define HS_MAJOR 1 #define HS_MINOR 4 -#define HS_PATCH 1 +#define HS_PATCH 2 #define STRINGIFY(x) _STR(x) #define _STR(x) #x diff --git a/src/src.ino b/src/src.ino index e90df18..671ca89 100644 --- a/src/src.ino +++ b/src/src.ino @@ -11,8 +11,8 @@ void setup() { Serial.begin(115200); homeSpan.setLogLevel(2); - homeSpan.setStatusPin(13); - homeSpan.setControlPin(33); +// homeSpan.setStatusPin(13); +// homeSpan.setControlPin(33); homeSpan.setHostNameSuffix("-lamp1"); homeSpan.setPortNum(1201); From 6aff9bfa751a8fb388b240e0d2c886eadd30b906 Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Sat, 27 Nov 2021 10:14:11 -0600 Subject: [PATCH 15/17] Update README.md --- docs/README.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/README.md b/docs/README.md index ab8e871..7f9440b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -41,14 +41,21 @@ HomeSpan is fully compatible with both Versions 1 and 2 of the [Arduino-ESP32 Bo * Launch the WiFi Access Point * A standalone, detailed End-User Guide -## ❗Latest Update - HomeSpan 1.4.1 (10/31/2021) - -* **Television Services and Characteristics have been added to HomeSpan!** See [HomeSpan Television Services](https://github.com/HomeSpan/HomeSpan/blob/master/docs/TVServices.md) for complete details +## ❗Latest Update - HomeSpan 1.4.2 (11/27/2021) -* **The RFControl library has been updated to allow for the generation of a modulating carrier wave suitable for controlling an infrared LED.** This allows you to create HomeKit-enabled TV remote controls with HomeSpan. See [HomeSpan Projects](https://github.com/topics/homespan) for some real-world examples! +* **Updated for compatability with Arduino-ESP32 Board Manager 2.0.1.** + * Maintains backward compatability with all previous versions. + +* **Some new methods and options for advance-use circumstances:** + + * Added *optional* second argument to the `setVal()` method that allows the value of a Characteristic to be updated *without* sending notification messages to HomeKit. Useful for keeping track of duration time when implementing a Sprinkler System - see [HomeSpan Reference Sprinkler](https://github.com/HomeSpan/HomeSpanReferenceSketches/tree/main/ReferenceSprinklers) for an example + + * Added `getLinks()` as a new method to SpanService. Returns a vector of pointers to SpanServices that have been linked to another Service with the addLink() method. Useful for looping over all linked services, such as checking all valves in a Shower System - see [HomeSpan Reference Shower](https://github.com/HomeSpan/HomeSpanReferenceSketches/blob/main/ReferenceShower/ReferenceShower) or an example + + * Added `setPerms()`, `addPerms()`, and `removePerms()` as new methods to SpanCharacteristic. Allows the user to modify (set/add/remove) the default permissions for any Characteristic. Useful for adding/deleting write-permissions for certain Characteristics + + * Added `setPairingCode()` method to the global homeSpan object that allows for programmatically configuring the Pairing Setup Code inside your sketch. See the HomeSpan API for important security considerations when using this function! -* **User-defined Custom Characteristics can be added to HomeSpan with a new macro.** See the [HomeSpan API](https://github.com/HomeSpan/HomeSpan/blob/master/docs/Reference.md#define-custom_charnameuuidpermsformatdefaultvalueminvaluemaxvaluestaticrange) for details (for *advanced* users only) - See [Releases](https://github.com/HomeSpan/HomeSpan/releases) for details on all changes included in this update. # HomeSpan Resources From c492f516044dc73e238d2f3606298010cc645177 Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Sat, 27 Nov 2021 10:14:34 -0600 Subject: [PATCH 16/17] Update README.md --- docs/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index 7f9440b..62107a4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -43,8 +43,8 @@ HomeSpan is fully compatible with both Versions 1 and 2 of the [Arduino-ESP32 Bo ## ❗Latest Update - HomeSpan 1.4.2 (11/27/2021) -* **Updated for compatability with Arduino-ESP32 Board Manager 2.0.1.** - * Maintains backward compatability with all previous versions. +* **Updated for compatability with Arduino-ESP32 Board Manager 2.0.1** + * Maintains backward compatability with all previous versions * **Some new methods and options for advance-use circumstances:** From d902408b08ae2be4b887370932cc94d70e73e958 Mon Sep 17 00:00:00 2001 From: HomeSpan Date: Sat, 27 Nov 2021 10:15:28 -0600 Subject: [PATCH 17/17] Update README.md --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 62107a4..7452336 100644 --- a/docs/README.md +++ b/docs/README.md @@ -50,7 +50,7 @@ HomeSpan is fully compatible with both Versions 1 and 2 of the [Arduino-ESP32 Bo * Added *optional* second argument to the `setVal()` method that allows the value of a Characteristic to be updated *without* sending notification messages to HomeKit. Useful for keeping track of duration time when implementing a Sprinkler System - see [HomeSpan Reference Sprinkler](https://github.com/HomeSpan/HomeSpanReferenceSketches/tree/main/ReferenceSprinklers) for an example - * Added `getLinks()` as a new method to SpanService. Returns a vector of pointers to SpanServices that have been linked to another Service with the addLink() method. Useful for looping over all linked services, such as checking all valves in a Shower System - see [HomeSpan Reference Shower](https://github.com/HomeSpan/HomeSpanReferenceSketches/blob/main/ReferenceShower/ReferenceShower) or an example + * Added `getLinks()` as a new method to SpanService. Returns a vector of pointers to SpanServices that have been linked to another Service with the addLink() method. Useful for looping over all linked services, such as checking all valves in a Shower System - see [HomeSpan Reference Shower](https://github.com/HomeSpan/HomeSpanReferenceSketches/tree/main/ReferenceShower) or an example * Added `setPerms()`, `addPerms()`, and `removePerms()` as new methods to SpanCharacteristic. Allows the user to modify (set/add/remove) the default permissions for any Characteristic. Useful for adding/deleting write-permissions for certain Characteristics