Needed to support ESP-NOW on ESP-8266 chips, which seem to only work if connecting into softAP MAC Address once HomeSpan is connected to WiFi network (prior to connection ESP-8266 will properly connect to normal STA address as well as softAP address).
If invert=true, PWM output will be phase-inverted. This is useful when creating a pair of PWM pins that need to be out of phase by 180 degrees (e.g driving a piezo-electric buzzer via two PWM pins).
Provides for additional control over Status LED when a generic device has been used. If the color of the device is changed, the change will only take effect when the LED is next turned on. If the LED is blinking, the color changes upon the next blink. But if the LED is ON, there is no next blink and color will not change.
This method check the status of the LED, and if it is ON, is calls the on() function again, which will result in an update of the color. The method does nothing if the LED is OFF or BLINKING.
Similar to CUSTOM_CHAR_STRING() macro, but does not include a parameter to set the default value (since the user can type an invalid string). Instead, user setData after creating the Characteristic as needed.
Applicable only for remote devices (i.e. not a Hub device). Last channel stored is used as initial channel upon reboot, provided that this channel is allowed by the channel mask (if not, the first allowed channel is selected instead).
* Changed ~SpanService to virtual function to ensure any user-defined destructor is also called
* Found/corrected bug in error message related to defining a Characteristic without any Service
* Added warning/error ID numbers to warning/error messages
* Other misc changes to clean up compiler warnings
Allows for bi-directional transmission between main HomeSpan device and one or more remote devices.
To Do: Create and test with Temperature Sensor Example
Added SpanPoint::setAsHub(), which is called after homeSpan.begin() to set device as Hub so SpanPoint knows not to change WiFi channel.
Also added check to make sure there are no SpanPoint objects instantiated before a call to homeSpan.begin() (if it is called at all).
This enables SpanPoint to operate as a standalone library with no reliance on anything in HomeSpan.
To Do: migrate all HomePeer code into SpanPoint. This will yield a universal standalone HomePoint library that can be used for BOTH the receiver and the sender (which automatically means two-way communication is always possible)
Verified ESP-NOW is communicating correctly with HomeSpan. Verified encryption works. Next step - create linkages between incoming data and Services; create queue structure to transfer data.
This allows the "src.ino" test file to once again properly compile without requiring modifications to any existing HomeSpan sketches. This was needed to ensure src.ino can find object code in "extras", which is now required to use the new statusDevice() method. Since the Arduino IDE only copies files that are in "src" folders, "extras" needed to be moved to "src/extras". For backwards compatibility with all other sketches, the "extras" directory now contains stubs for the ".h" include files.
Rather than use ESP32 timers, simply spawn a new task that turn on/off LED using simple delays. By avoiding the use of the ESP32 timer, we are no longer limited by the number of Blinkers possible. Also, Blinker relied on the timer interrupt, which crashed when it tried to call Pixel since Pixel in turn uses interrupts from the RMT. Switching to spawned tasks is much cleaner and does not consume more CPU time since the timer interrupts were driven by CPU anyway.
Blinker class and generic LED class are now in extras.h. Blinkable Interface is also in extras.h.
To Do: Incorporate new Blinker class into HomeSpan code
Eliminated constructor that had no pin parameter. Pin parameter is now always required. Since PushButton was not part of HomeSpan API, these changes should not impact any users.
This optional flag does not seem to have any affect on the Home App and does not produce any messages indicating that the device needs additional setup. Was hopeful this would have prevented the "Not Supported" message on a Home App Tile that is configured as a bridge, but without any other Accessories.
Needed to set idle_level to LOW even though idle_output was already disabled. This is likely because 2.0.4 introduced an entirely new API for RMT, though version 2.0.3 IDF functions and structures seem to be accepted as well.
Only initialize MDNS, WebLog, and OTA when first connecting to WiFi. Do not re-initialize upon re-connections after a disconnect.
Also, add number of disconnects, and reset_reason() to WebLog
Added Feather.h mappings; and
Changed RMT clock logic in RFControl to check for presence of RMT_SYS_CON_REG instead of simply looking for CONFIG_IDF_TARGET_ESP32C3;
** NOTE: Can ignore warnings about RMT_CH4...CH7+RX_LIM_REG redefine errors. This has been reported to Espressif IDF Github, been acknowledged as a bug, and will be fixed in a future release of the IDF. Since HomeSpan does NOT use the RMT peripheral for RECEIVING, these warning messages have no effect.
The only reason to have used getAccessory(aid) is to delete it, so the delete command is now invoked automatically. Function returns 0 on success (matching aid found) or -1 on fail (aid not found)
Method homeSpan.updateDatabase(boolean updateMDNS) recomputes database hash and compares with previous hash. If changed, config number is updated and saved in NVS along with new hash. If updateMDNS is true, a new "c#" MDNS record is also broadcast with the new config number. This triggers HomeKit to call for a database refresh. Method returns true if config number has changed, or false if it has not.
The "C" command computes a hash of the current database config and updates the config number if needed. If config number has changed, the MDNS "c#" record is updated and the new config number is rebroadcast. This triggers HomeKit to immediately request an update of the HAP database so that the changes can be shortly reflected in the Home App without the need to close any Client connections or reboot the device.
The config number logic has also been updated/fixed. Previously it would create a hash from the full HAP database, which includes the value of each characteristic. Thus, initial value changes of Characteristics, as a result of stored values in NVS, would cause an update to the config number upon reboot.
This is not problematic, but also not intended, as a change in value is not really a change in the database config. The new logic computes a hash of the database that EXCLUDES all Characteristic values.
Instead of creating a static configLog for display upon start-up, an info log will be generated based on real-time data whenever the 'i' CLI command is requested. This provides for more streamlined error-checking as well.
Rather than call homeSpan.poll() in the main Arduino loop() function, you can instead call homeSpan.start() at the end of the set-up function. This keeps the main Arduino loop() function free for user-defined code that will not block, and does not get blocked by, homeSpan.poll().
If using a dual-core processor, polling now occurs on core 0, instead of the core 1 (where all other Arduino stuff normally runs).
HomeSpan will throw a fatal error and halt processing if both homeSpan.poll() and homeSpan.start() are used in the same sketch.
Need to revisit Television sketch - the latest iOS seemed to have disabled the ability to dynamically set visibility of input sources. Checking/Un-Checking the visibility radio buttons either during pairing, or after pairing on the settings screen, seems to be ignored by the Home App (the same input sources are shown in the selector regardless of any changes made). However, dynamically changing the name of an input source seems to work fine.
Rather than auto-enable OTA if not already enabled in safemode, changed the logic to simply rollback to previous app if OTA was used to download a sketch that does not itself have OTA enabled, unless OTA was previously enabled without safemode.
To do: Delete all complicated SpanOTA logic that (unsuccessfully) tried to track OTA status and check SHA246 partition codes to determine if reboot was OTA or Serial. None of this is need, but some of the code may be useful for other things in the future.
Since much of the Arduino-ESP32 library is precompiled, you cannot use -DCONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE to define this during compile time (it gets defined but is not used by the precompiled libraries).
TO DO: create an NVS entry that flags whether last update was via OTA. If so, automatically enable OTA regardless of enableOTA setting. This would ensure that OTA cannot be disabled accidentally by uploading a non-enabledOTA sketch to remote device.
Also updated SpanWebLog::addLog() so that the log message is also output to the Serial Monitor if the HomeSpan Log Level is set to 1 or greater.
To do: DOCUMENT ALL THIS!
If LOG1() or LOG2() is only provided with a SINGLE argument, then Serial.print() is called. This allows you to continue using LOG1() and LOG2() to directly print any variable or object that is handled by Serial.print(), such as an int, double, or even an IPAddress.
If LOG1() or LOG2() is provided with multiple arguments, the first is considered the format and Serial.printf(format...) is called. This allows you to use printf-like functionality within LOG1() and LOG2().
Gets IP address (as char *) of last client to send a request. Useful as part of web log messages. Will return 0.0.0.0 if used outside of any code that is responding to a client request.
Added isEnabled to SpanWebLog to indicate whether Web Log has been enabled. This allows the use of homeSpan.webLog.addLog() without ever enabling (in which case the log entries are ignored).
Also included logic so that clockTime is set to "Unknown" is addLog() is called prior to WiFi being established.
Next up: replace addLog(const char *) with a variadic set of parameters with dynamic storage allocation.
Also, updated error checking so that the UUID for both custom Services and custom Characteristics are checked for syntax. A fatal error is thrown if an ill-formatted UUID is found, since this will definitely prevent pairing with the HomeApp.
The UUID for HAP Services and Characteristics are NOT error checked, since these are fixed in HomeSpan.
Also, the custom Characteristics are not validated against the optional list for a service. If the user adds a custom Characteristic to a HAP Service, it is assumed to be valid. Similarly, none of the Characteristics (HAP of Custom) in a Custom Service are validated at all.
For developer use only - facilitates testing the same code across an ESP32, ESP32-S2, and ESP32-C3 without re-wiring by using an Adafruit FeatherBoard as a common jig.
Use homeSpan.reserveSocketConnections(n) to reserve n sockets *not* to be used for HAP. Multiple calls can be used to cumulate a total number of reserved sockets. This makes is easy to add reserveSocketConnections(n) at multiple point in the code whenever a certain number of sockets need to be reserved for use with that portion of the code. For example enableOTA() calls reserveSocketConnections(1).
If both setMaxConnections(), and one or more reserveSocketConnections(), methods are called HomeSpan will use the more restrictive net value.