From 6c7bf03c3b29e2039d3c97ef8935e6819cc95bc6 Mon Sep 17 00:00:00 2001 From: Gregg Date: Sat, 25 Jun 2022 18:44:31 -0500 Subject: [PATCH] Added Other Examples -> ProgrammableHub --- Other Examples/ProgrammableHub/DEV_Identify.h | 38 +++ Other Examples/ProgrammableHub/DEV_LED.h | 69 ++++++ .../ProgrammableHub/ProgrammableHub.ino | 224 ++++++++++++++++++ src/HAP.cpp | 2 +- 4 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 Other Examples/ProgrammableHub/DEV_Identify.h create mode 100644 Other Examples/ProgrammableHub/DEV_LED.h create mode 100644 Other Examples/ProgrammableHub/ProgrammableHub.ino diff --git a/Other Examples/ProgrammableHub/DEV_Identify.h b/Other Examples/ProgrammableHub/DEV_Identify.h new file mode 100644 index 0000000..b8d21d6 --- /dev/null +++ b/Other Examples/ProgrammableHub/DEV_Identify.h @@ -0,0 +1,38 @@ + +////////////////////////////////// +// DEVICE-SPECIFIC SERVICES // +////////////////////////////////// + +struct DEV_Identify : Service::AccessoryInformation { + + int nBlinks; // number of times to blink built-in LED in identify routine + SpanCharacteristic *identify; // reference to the Identify Characteristic + + DEV_Identify(const char *name, const char *manu, const char *sn, const char *model, const char *version, int nBlinks) : Service::AccessoryInformation(){ + + new Characteristic::Name(name); // create all the required Characteristics with values set based on above arguments + new Characteristic::Manufacturer(manu); + new Characteristic::SerialNumber(sn); + new Characteristic::Model(model); + new Characteristic::FirmwareRevision(version); + identify=new Characteristic::Identify(); // store a reference to the Identify Characteristic for use below + + this->nBlinks=nBlinks; // store the number of times to blink the LED + + pinMode(homeSpan.getStatusPin(),OUTPUT); // make sure LED is set for output + } + + boolean update(){ + + for(int i=0;isetRange(5,100,1); // sets the range of the Brightness to be from a min of 5%, to a max of 100%, in steps of 1% + } + + this->LED=new LedPin(ledPin); // configures a PWM LED for output to pin number "ledPin" + + Serial.printf("Configuring LED: Pin=%d %s\n",LED->getPin(),isDimmable?"(Dimmable)":""); // initialization message + + LED->set(power->getVal()*(isDimmable?(level->getVal()):100)); // set the LED to its initial state at startup. + + } // end constructor + + boolean update(){ // update() method + + LOG1("Updating LED on pin="); + LOG1(LED->getPin()); + LOG1(": Current Power="); + LOG1(power->getVal()?"true":"false"); + if(isDimmable){ + LOG1(" Current Brightness="); + LOG1(level->getVal()); + } + + if(power->updated()){ + LOG1(" New Power="); + LOG1(power->getNewVal()?"true":"false"); + } + + if(isDimmable && level->updated()){ + LOG1(" New Brightness="); + LOG1(level->getNewVal()); + } + + LOG1("\n"); + + LED->set(power->getNewVal()*(isDimmable?(level->getNewVal()):100)); // update the physical LED to reflect the new values + + return(true); // return true + + } // update + +}; + +////////////////////////////////// diff --git a/Other Examples/ProgrammableHub/ProgrammableHub.ino b/Other Examples/ProgrammableHub/ProgrammableHub.ino new file mode 100644 index 0000000..41034ea --- /dev/null +++ b/Other Examples/ProgrammableHub/ProgrammableHub.ino @@ -0,0 +1,224 @@ +/********************************************************************************* + * MIT License + * + * Copyright (c) 2022 Gregg E. Berman + * + * https://github.com/HomeSpan/HomeSpan + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + ********************************************************************************/ + +//////////////////////////////////////////////////////////// +// // +// HomeSpan: A HomeKit implementation for the ESP32 // +// ------------------------------------------------ // +// // +// Demonstrates how to implement a Web Server alongside // +// of HomeSpan to create a Programmable Hub serving up to // +// 16 Configurable Lights. // +// // +//////////////////////////////////////////////////////////// + +#include "HomeSpan.h" +#include "DEV_LED.h" +#include "DEV_Identify.h" + +#include // include WebServer library +WebServer webServer(80); // create WebServer on port 80 + +#define NLIGHTS 16 // maximum number of Lightbulb Accessories + +uint8_t pinList[]={0,4,5,12,14,15,16,17,18,19,22,23,25,26,27,32,33}; // list of allowed pins +char lightNames[NLIGHTS][9]; // storage for default light names + +nvs_handle lightNVS; // handle for NVS storage + +struct { // structure to store pin numbers and dimmable flag + uint8_t pin=0; + uint8_t dimmable=0; +} lightData[NLIGHTS]; + +//////////////////////////////////////////////////////////// + +void setup() { + + Serial.begin(115200); + + homeSpan.setLogLevel(1); + + homeSpan.setHostNameSuffix(""); // use null string for suffix (rather than the HomeSpan device ID) + homeSpan.setPortNum(1201); // change port number for HomeSpan so we can use port 80 for the Web Server + homeSpan.enableOTA(); // enable OTA updates + homeSpan.setMaxConnections(5); // reduce max connection to 5 (default is 8) since WebServer and a connecting client will need 2, and OTA needs 1 + homeSpan.setWifiCallback(setupWeb); // need to start Web Server after WiFi is established + + homeSpan.begin(Category::Bridges,"HomeSpan Light Hub","homespanhub"); + + for(int i=0;i0){ + new SpanAccessory(i+2); + new DEV_Identify(lightNames[i],"HomeSpan",lightNames[i],lightData[i].dimmable?"Dimmable":"Not Dimmable","1.0",0); + new DEV_GenericLED(lightData[i].pin,lightData[i].dimmable); + } + } + +} // end of setup() + +////////////////////////////////////// + +void loop(){ + + homeSpan.poll(); + webServer.handleClient(); // need to process webServer once each loop + +} // end of loop() + +////////////////////////////////////// + +void setupWeb(){ + Serial.print("Starting Light Server Hub...\n\n"); + webServer.begin(); + + // Create web routines inline + + webServer.on("/addForm", []() { + String content="

Add New Light Accessory

"; + + content+="
"; + content+=""; + content+="

"; + content+=""; + + content+="
"; + content+=""; + + content+="
"; + content+=""; + + webServer.send(200, "text/html", content); + + }); + + webServer.on("/", []() { + + String content = "
HomeSpan Light Server Hub Configuration

"; + content += "Select pins and check box if dimmable:

"; + + for(int i=0;i"; + + content += String(lightNames[i]) + ": "; + + content += " "; + content += "
"; + } + + content += "

"; + + webServer.send(200, "text/html", content); + + }); + + webServer.on("/configure", []() { + + for(int i=0;i"; + else + lightData[i].dimmable=0; + + content += "
"; + content += ""; + + nvs_set_blob(lightNVS,"LIGHTDATA",&lightData,sizeof(lightData)); // update data + nvs_commit(lightNVS); // commit to NVS + + webServer.send(200, "text/html", content); + + }); + + webServer.on("/reboot", []() { + + String content = "Rebooting! Will return to configuration page in 10 seconds.

"; + content += ""; + webServer.send(200, "text/html", content); + + for(int j=0;j\n"; response+="\n"; response+="\n";