diff --git a/.gitignore b/.gitignore index 7feac1c..e267bfb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.webarchive +.vscode \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 0289a40..b10f539 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ install: - git clone -o 3c22f2f https://github.com/gmag11/NtpClient - git clone -o b592ac6 https://github.com/me-no-dev/ESPAsyncUDP - git clone -o ec56354 https://github.com/interactive-matter/aJson + - git clone -o cadf6b4 https://github.com/tablatronix/WiFiManager - sed -i -e 's|#define PRINT_BUFFER_LEN 256|#define PRINT_BUFFER_LEN 4096|g' aJson/aJSON.h - cd aJson - curl -OSLs https://gitlab.com/xarduino/lightsw/raw/2424e3a9348e7144373311af132ced38f14489ba/patch/ajson-void-flush.patch @@ -18,6 +19,4 @@ install: - rm ajson-void-flush.patch - cd $TRAVIS_BUILD_DIR script: - - sed -i -e 's|#include "/secrets.h"|//#include "/secrets.h"|g' ESP8266HueEmulator/ESP8266HueEmulator.ino - - sed -i -e 's|//const char|const char|g' ESP8266HueEmulator/ESP8266HueEmulator.ino - build_platform esp8266 diff --git a/ESP8266HueEmulator.code-workspace b/ESP8266HueEmulator.code-workspace new file mode 100644 index 0000000..686355b --- /dev/null +++ b/ESP8266HueEmulator.code-workspace @@ -0,0 +1,15 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "files.associations": { + "map": "cpp", + "set": "cpp", + "xtree": "cpp", + "functional": "cpp" + } + } +} \ No newline at end of file diff --git a/ESP8266HueEmulator/ESP8266HueEmulator.ino b/ESP8266HueEmulator/ESP8266HueEmulator.ino index 2badcfd..6cd8216 100644 --- a/ESP8266HueEmulator/ESP8266HueEmulator.ino +++ b/ESP8266HueEmulator/ESP8266HueEmulator.ino @@ -7,31 +7,89 @@ #include #include #include +#include #include #include #include #include // instead of NeoPixelAnimator branch + +#define MAX_LIGHT_HANDLERS 1 +#define lightName "Hue RGB Light" // Light name, change this if you se multiple lights for easy identification + #include "LightService.h" // these are only used in LightHandler.cpp, but it seems that the IDE only scans the .ino and real libraries for dependencies #include "SSDP.h" #include // Replace avm/pgmspace.h with pgmspace.h there and set #define PRINT_BUFFER_LEN 4096 ################# IMPORTANT -#include "/secrets.h" // Delete this line and populate the following -//const char* ssid = "********"; -//const char* password = "********"; - RgbColor red = RgbColor(COLOR_SATURATION, 0, 0); RgbColor green = RgbColor(0, COLOR_SATURATION, 0); RgbColor white = RgbColor(COLOR_SATURATION); RgbColor black = RgbColor(0); +// Uncomment to use WS2812 light strips +// instead of RGB PWM +//#define USE_WS2812_STRIP +#if defined(USE_WS2812_STRIP) // Settings for the NeoPixels #define NUM_PIXELS_PER_LIGHT 10 // How many physical LEDs per emulated bulb - #define pixelCount 30 + #define pixelPin 2 // Strip is attached to GPIO2 on ESP-01 NeoPixelBus strip(MAX_LIGHT_HANDLERS * NUM_PIXELS_PER_LIGHT, pixelPin); +#else +// Defines for PWM Mode +#define NUM_PIXELS_PER_LIGHT 1 +#define PWM_CHANNELS 3 +#define pixelCount 1 + +class RGBStripe { +public: + RGBStripe(uint8_t pinRed, uint8_t pinGreen, uint8_t pinBlue) { + _pins[0] = pinRed; + _pins[1] = pinGreen; + _pins[2] = pinBlue; + } + + void Begin() + { + // Setup pins for output + for (uint8_t pin = 0; pin < PWM_CHANNELS; pin++) { + pinMode(_pins[pin], OUTPUT); + analogWrite(_pins[pin], 0); + } + } + + void SetPixelColor(uint16_t indexPixel, RgbColor updatedColor) + { + // Store current color value + _color[0] = updatedColor.R; + _color[1] = updatedColor.G; + _color[2] = updatedColor.B; + + // Update outputs + for (uint8_t pin = 0; pin < PWM_CHANNELS; pin++) { + analogWrite(_pins[pin], (int)(_color[pin] * 4.0)); + } + } + + void Show() + { + } + + RgbColor GetPixelColor(uint16_t indexPixel) const + { + RgbColor result(_color[0], _color[1], _color[2]); + return result; + } + +private: + uint8_t _pins[PWM_CHANNELS]; + uint8_t _color[PWM_CHANNELS]; +}; + +RGBStripe strip(12, 14, 13); // red (D6), green (D5), blue (D7) +#endif NeoPixelAnimator animator(MAX_LIGHT_HANDLERS * NUM_PIXELS_PER_LIGHT, NEO_MILLISECONDS); // NeoPixel animation management object LightServiceClass LightService; @@ -123,9 +181,9 @@ void setup() { delay(120); // Apparently needed to make the first few pixels animate correctly Serial.begin(115200); - WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - infoLight(white); + WiFiManager wifiManager; + wifiManager.setConfigPortalTimeout(120); + wifiManager.autoConnect(lightName); while (WiFi.status() != WL_CONNECTED) { infoLight(red); @@ -202,7 +260,7 @@ void infoLight(RgbColor color) { { strip.SetPixelColor(i, color); strip.Show(); - delay(10); + delay(250); strip.SetPixelColor(i, black); strip.Show(); } diff --git a/ESP8266HueEmulator/LightService.cpp b/ESP8266HueEmulator/LightService.cpp index 129c1e1..db14494 100644 --- a/ESP8266HueEmulator/LightService.cpp +++ b/ESP8266HueEmulator/LightService.cpp @@ -1203,8 +1203,8 @@ void addSingleLightJson(aJsonObject* root, int numberOfTheLight, LightHandler *l String lightNumber = (String) (numberOfTheLight + 1); String lightName = lightHandler->getFriendlyName(numberOfTheLight); - aJson.addStringToObject(root, "manufacturername", "OpenSource"); // type of lamp (all "Extended colour light" for now) - aJson.addStringToObject(root, "modelid", "LST001"); // the model number + aJson.addStringToObject(root, "manufacturername", "Philips"); // type of lamp (all "Extended colour light" for now) + aJson.addStringToObject(root, "modelid", "LCT015"); // the model number aJson.addStringToObject(root, "name", lightName.c_str()); // // the name as set through the web UI or app aJsonObject *state; aJson.addItemToObject(root, "state", state = aJson.createObject()); @@ -1221,7 +1221,7 @@ void addSingleLightJson(aJsonObject* root, int numberOfTheLight, LightHandler *l aJson.addStringToObject(state, "colormode", "hs"); // the current color mode aJson.addBooleanToObject(state, "reachable", true); // lamp can be seen by the hub aJson.addStringToObject(root, "type", "Extended color light"); // type of lamp (all "Extended colour light" for now) - aJson.addStringToObject(root, "swversion", "0.1"); // type of lamp (all "Extended colour light" for now) + aJson.addStringToObject(root, "swversion", "1.46.13_r26312"); // type of lamp (all "Extended colour light" for now) if (info.bulbType == HueBulbType::DIMMABLE_LIGHT) { aJson.addStringToObject(root, "type", "Dimmable light"); } else { @@ -1235,8 +1235,7 @@ void addSingleLightJson(aJsonObject* root, int numberOfTheLight, LightHandler *l void addLightJson(aJsonObject* root, int numberOfTheLight, LightHandler *lightHandler) { if (!lightHandler) return; - - + String lightNumber = (String) (numberOfTheLight + 1); String lightName = lightHandler->getFriendlyName(numberOfTheLight); aJsonObject *light; @@ -1249,11 +1248,11 @@ void addLightJson(aJsonObject* root, int numberOfTheLight, LightHandler *lightHa aJson.addStringToObject(light, "type", "Extended color light"); } - aJson.addStringToObject(light, "manufacturername", "OpenSource"); // type of lamp (all "Extended colour light" for now) - aJson.addStringToObject(light, "swversion", "0.1"); + aJson.addStringToObject(light, "manufacturername", "Philips"); // type of lamp (all "Extended colour light" for now) + aJson.addStringToObject(light, "swversion", "1.46.13_r26312"); aJson.addStringToObject(light, "name", lightName.c_str()); // // the name as set through the web UI or app aJson.addStringToObject(light, "uniqueid", (macString + "-" + (String) (numberOfTheLight + 1)).c_str()); - aJson.addStringToObject(light, "modelid", "LST001"); // the model number + aJson.addStringToObject(light, "modelid", "LCT015"); // the model number aJsonObject *state; aJson.addItemToObject(light, "state", state = aJson.createObject()); @@ -1294,8 +1293,9 @@ static String format2Digits(int num) { void addConfigJson(aJsonObject *root) { - aJson.addStringToObject(root, "name", "hue emulator"); - aJson.addStringToObject(root, "swversion", "81012917"); + aJson.addStringToObject(root, "name", "Philips hue"); + aJson.addStringToObject(root, "modelid", "BSB002"); + aJson.addStringToObject(root, "swversion", "1809121051"); aJson.addStringToObject(root, "bridgeid", bridgeIDString.c_str()); aJson.addBooleanToObject(root, "portalservices", false); aJson.addBooleanToObject(root, "linkbutton", true); @@ -1304,7 +1304,7 @@ void addConfigJson(aJsonObject *root) aJson.addStringToObject(root, "ipaddress", ipString.c_str()); aJson.addStringToObject(root, "netmask", netmaskString.c_str()); aJson.addStringToObject(root, "gateway", gatewayString.c_str()); - aJson.addStringToObject(root, "apiversion", "1.3.0"); + aJson.addStringToObject(root, "apiversion", "1.24.0"); if (timeStatus() == timeSet) { time_t moment = now(); String dts = String(year(moment)); diff --git a/ESP8266HueEmulator/LightService.h b/ESP8266HueEmulator/LightService.h index 28e6aac..032bc9d 100644 --- a/ESP8266HueEmulator/LightService.h +++ b/ESP8266HueEmulator/LightService.h @@ -47,7 +47,9 @@ class LightHandler { }; // Max number of exposed lights is directly related to aJSON PRINT_BUFFER_LEN, 14 for 4096 +#ifndef MAX_LIGHT_HANDLERS #define MAX_LIGHT_HANDLERS 2 +#endif #define COLOR_SATURATION 255.0f class LightServiceClass {