probonopd / ESP8266HueEmulator

Emulate a Philips Hue bridge running on an ESP8266 using the Arduino IDE.
MIT License
411 stars 93 forks source link

cant compile Json_Example #119

Open Wifiunterputzdose opened 5 years ago

Wifiunterputzdose commented 5 years ago

I tried to compile the Json_Example Sketch but get some compile errors. First the avr/pgmspace.h couldnt find, so I delete the avr/. Until that I get these errors

`C:\xxx\AppData\Local\Temp\arduino_modified_sketch_748973\Json_Example.ino: In function 'uint16_t freeMem(uint16_t*)':

Json_Example:239: error: '__malloc_heap_start' was not declared in this scope

 brkval = __malloc_heap_start;

          ^

Json_Example:241: error: '__malloc_heap_end' was not declared in this scope

cp = __malloc_heap_end;

    ^

Json_Example:243: error: 'AVR_STACK_POINTER_REG' was not declared in this scope

 cp = ((char *)AVR_STACK_POINTER_REG) - __malloc_margin;

               ^

Json_Example:243: error: '__malloc_margin' was not declared in this scope

 cp = ((char *)AVR_STACK_POINTER_REG) - __malloc_margin;

                                        ^

exit status 1 '__malloc_heap_start' was not declared in this scope

` I'm using Arduino Version 1.8.5, ESP8266 Version 2.4.0-rc2

Can someone help me?

probonopd commented 5 years ago

Where is Json_Example.ino from?

Wifiunterputzdose commented 5 years ago

Hi thanks for your fast response. Sry now I got the right files. If I'm right the WS2812b NeoPixels are not necessary for the functionality just to visible the Connection Status and so on. I commented all the stuff out. Does the main.cpp looks now correct?

If I try to compile the project in PlatformIO I get the following error:

How to get rid of these errors?

.pioenvs\nodemcuv2\src\main.cpp.o:(.text.setup+0x34): undefined reference to `NTP'
.pioenvs\nodemcuv2\src\main.cpp.o:(.text.setup+0x38): undefined reference to `NTPClient::begin(String, signed char, bool, signed c
har, WiFiUDP*)'
.pioenvs\nodemcuv2\src\main.cpp.o:(.text.setup+0x3c): undefined reference to `timeStatus()'
.pioenvs\nodemcuv2\src\main.cpp.o:(.text.setup+0x40): undefined reference to `now()'
.pioenvs\nodemcuv2\src\main.cpp.o:(.text.setup+0x44): undefined reference to `NTPClient::getTimeDateString(long)'
.pioenvs\nodemcuv2\src\main.cpp.o: In function `setup':
main.cpp:(.text.setup+0x141): undefined reference to `NTPClient::begin(String, signed char, bool, signed char, WiFiUDP*)'
main.cpp:(.text.setup+0x14c): undefined reference to `timeStatus()'
main.cpp:(.text.setup+0x155): undefined reference to `now()'
main.cpp:(.text.setup+0x162): undefined reference to `NTPClient::getTimeDateString(long)'
collect2.exe: error: ld returned 1 exit status
*** [.pioenvs\nodemcuv2\firmware.elf] Error 1

my main.cpp

//#include <Arduino.h>
/**
 * Emulate Philips Hue Bridge ; so far the Hue app finds the emulated Bridge and gets its config
 * and switch NeoPixels with it
 **/

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <TimeLib.h>
#include <NtpClientLib.h>
//#include <NeoPixelBus.h>
//#include <NeoPixelAnimator.h> // instead of NeoPixelAnimator branch
#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 <ESP8266WebServer.h>
//#include "SSDP.h"
#include <ESP8266SSDP.h>
#include <aJSON.h> // Replace avm/pgmspace.h with pgmspace.h there and set #define PRINT_BUFFER_LEN 4096 ################# IMPORTANT

const char* ssid = "BlaSSID";
const char* password = "blubb";

//RgbColor red = RgbColor(COLOR_SATURATION, 0, 0);
//RgbColor green = RgbColor(0, COLOR_SATURATION, 0);
//RgbColor white = RgbColor(COLOR_SATURATION);
//RgbColor black = RgbColor(0);

// 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<NeoGrbFeature, NeoEsp8266Uart800KbpsMethod> strip(MAX_LIGHT_HANDLERS * NUM_PIXELS_PER_LIGHT, pixelPin);
//NeoPixelAnimator animator(MAX_LIGHT_HANDLERS * NUM_PIXELS_PER_LIGHT, NEO_MILLISECONDS); // NeoPixel animation management object
//LightServiceClass LightService;

//void infoLight(RgbColor color);
/*
HsbColor getHsb(int hue, int sat, int bri) {
  float H, S, B;
  H = ((float)hue) / 182.04 / 360.0;
  S = ((float)sat) / COLOR_SATURATION;
  B = ((float)bri) / COLOR_SATURATION;
  return HsbColor(H, S, B);
}*/
/*
class PixelHandler : public LightHandler {
  private:
    HueLightInfo _info;
    int16_t colorloopIndex = -1;
  public:
    void handleQuery(int lightNumber, HueLightInfo newInfo, aJsonObject* raw) {
      // define the effect to apply, in this case linear blend
      HslColor newColor = HslColor(getHsb(newInfo.hue, newInfo.saturation, newInfo.brightness));
      HslColor originalColor = strip.GetPixelColor(lightNumber);
      _info = newInfo;

      // cancel colorloop if one is running
      if (colorloopIndex >= 0) {
        animator.StopAnimation(colorloopIndex);
        colorloopIndex = -1;
      }
      if (newInfo.on) {
        if (_info.effect == EFFECT_COLORLOOP) {
          //color loop at max brightness/saturation on a 60 second cycle
          const int SIXTY_SECONDS = 60000;
          animator.StartAnimation(lightNumber, SIXTY_SECONDS, [ = ](const AnimationParam & param) {
            // save off animation index
            colorloopIndex = param.index;

            // progress will start at 0.0 and end at 1.0
            float currentHue = newColor.H + param.progress;
            if (currentHue > 1) currentHue -= 1;
            HslColor updatedColor = HslColor(currentHue, newColor.S, newColor.L);
            RgbColor currentColor = updatedColor;

            for(int i=lightNumber * NUM_PIXELS_PER_LIGHT; i < (lightNumber * NUM_PIXELS_PER_LIGHT) + NUM_PIXELS_PER_LIGHT; i++) {
              strip.SetPixelColor(i, updatedColor);
            }

            // loop the animation until canceled
            if (param.state == AnimationState_Completed) {
              // done, time to restart this position tracking animation/timer
              animator.RestartAnimation(param.index);
            }
          });
          return;
        }
        AnimUpdateCallback animUpdate = [ = ](const AnimationParam & param)
        {
          // progress will start at 0.0 and end at 1.0
          HslColor updatedColor = HslColor::LinearBlend<NeoHueBlendShortestDistance>(originalColor, newColor, param.progress);

          for(int i=lightNumber * NUM_PIXELS_PER_LIGHT; i < (lightNumber * NUM_PIXELS_PER_LIGHT) + NUM_PIXELS_PER_LIGHT; i++) {
            strip.SetPixelColor(i, updatedColor);
          }
        };
        animator.StartAnimation(lightNumber, _info.transitionTime, animUpdate);
      }
      else {
        AnimUpdateCallback animUpdate = [ = ](const AnimationParam & param)
        {
          // progress will start at 0.0 and end at 1.0
          HslColor updatedColor = HslColor::LinearBlend<NeoHueBlendShortestDistance>(originalColor, black, param.progress);

          for(int i=lightNumber * NUM_PIXELS_PER_LIGHT; i < (lightNumber * NUM_PIXELS_PER_LIGHT) + NUM_PIXELS_PER_LIGHT; i++) {
            strip.SetPixelColor(i, updatedColor);
          }
        };
        animator.StartAnimation(lightNumber, _info.transitionTime, animUpdate);
      }
    }

    HueLightInfo getInfo(int lightNumber) { return _info; }
};
*/
void setup() {

  // this resets all the neopixels to an off state
  //strip.Begin();
  //strip.Show();

  // Show that the NeoPixels are alive
  //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);

  while (WiFi.status() != WL_CONNECTED) {
    //infoLight(red);
    delay(500);
    Serial.print(".");
  }

  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);

  // Hostname defaults to esp8266-[ChipID]
  // ArduinoOTA.setHostname("myesp8266");

  // No authentication by default
  // ArduinoOTA.setPassword((const char *)"123");

  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();

  // Sync our clock
  NTP.begin("pool.ntp.org", 0, true);

  // Show that we are connected
  //infoLight(green);
  //pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
  //digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH

  //LightService.begin();
/*
  // setup pixels as lights
  for (int i = 0; i < MAX_LIGHT_HANDLERS && i < pixelCount; i++) {
    LightService.setLightHandler(i, new PixelHandler());
  }
*/
  // We'll get the time eventually ...
  if (timeStatus() == timeSet) {
    Serial.println(NTP.getTimeDateString(now()));
  }
}

void loop() {
  ArduinoOTA.handle();

  //LightService.update();
/*
  static unsigned long update_strip_time = 0;  //  keeps track of pixel refresh rate... limits updates to 33 Hz
  if (millis() - update_strip_time > 30)
  {
    if ( animator.IsAnimating() ) animator.UpdateAnimations();
    strip.Show();
    update_strip_time = millis();
  }*/
}
/*
void infoLight(RgbColor color) {
  // Flash the strip in the selected color. White = booted, green = WLAN connected, red = WLAN could not connect
  for (int i = 0; i < pixelCount; i++)
  {
    strip.SetPixelColor(i, color);
    strip.Show();
    delay(10);
    strip.SetPixelColor(i, black);
    strip.Show();
  }
}*/
probonopd commented 5 years ago

Have you modified main.cpp?

Wifiunterputzdose commented 5 years ago

Hi yes this is the modified main.cpp because I have no WS2812b NeoPixels:

My modified main.cpp

`//#include /**

include

include

include

include

include

include

//#include //#include // instead of NeoPixelAnimator branch

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

//#include "SSDP.h"

include

include // Replace avm/pgmspace.h with pgmspace.h there and set #define PRINT_BUFFER_LEN 4096 ################# IMPORTANT

const char ssid = "dfhdfhg"; const char password = "12127";

LightServiceClass LightService;

void setup() {

Serial.begin(115200);

WiFi.mode(WIFI_STA); WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }

// Port defaults to 8266 // ArduinoOTA.setPort(8266);

// Hostname defaults to esp8266-[ChipID] // ArduinoOTA.setHostname("myesp8266");

// No authentication by default // ArduinoOTA.setPassword((const char *)"123");

ArduinoOTA.onStart([]() { Serial.println("Start"); }); ArduinoOTA.onEnd([]() { Serial.println("\nEnd"); }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }); ArduinoOTA.onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin();

// Sync our clock NTP.begin("pool.ntp.org", 0, true);

LightService.begin();

// We'll get the time eventually ... if (timeStatus() == timeSet) { Serial.println(NTP.getTimeDateString(now())); } }

void loop() { ArduinoOTA.handle();

LightService.update();

}`

Wifiunterputzdose commented 5 years ago

Hi probonopd I get it compiled. When I connect the ESP-12e to the terminal I get the following message: ..Starting HTTP at xxx.xxx.x.xxx:80 Starting SSDP... SSDP Started FS STarting initializeGroupSlots() initializeScenceSlots() 09:13:45 05/01/2019

Typing the printed the IP without :80 I get only a empty page with not found: /

By searching for a bridge over the Philips HUE APP I get following message on teminal: 594205 {"name":"hue"emulator","swversion":"81012917","bridgeid":"600194FFFE5E439A",portalservices":false,"linkbutton":true,"mac":60:01:94:5E:43:9A","dhcp":true,"ipaddress":"xxx.xxx.x.xxx","netmask":"255.255.255.0"."gateway":"xxx.xxx.x.x","apiversion":"1.3.0","}

But the app can't find a bridge

Is this normal? I think something works not correctly?

probonopd commented 5 years ago

Probably. I have not used newer versions of the Philips app in a long time, and when I did I found them to be bloated and buggy.

Wifiunterputzdose commented 5 years ago

One thing I recognized is that the message on terminal ist not complete. It ends with the apiversion.

Information about timezone whitelist etc is missing

`aJson.addStringToObject(root, "apiversion", "1.24.0"); if (timeStatus() == timeSet) { time_t moment = now(); String dts = String(year(moment)); dts += "-"; dts += format2Digits(month(moment)); dts += "-"; dts += format2Digits(day(moment)); dts += "T"; dts += NTP.getTimeStr(moment);

// TODO: send this as "utc" and "localtime" as timezone corrected utc
aJson.addStringToObject(root, "localtime", dts.c_str());

} // TODO: take this from the settings, once we have spiffs support aJson.addStringToObject(root, "timezone", "Europe/London"); aJsonObject whitelist; aJson.addItemToObject(root, "whitelist", whitelist = aJson.createObject()); aJsonObject whitelistFirstEntry; aJson.addItemToObject(whitelist, "api", whitelistFirstEntry = aJson.createObject()); aJson.addStringToObject(whitelistFirstEntry, "name", "clientname#devicename"); aJsonObject *swupdate; aJson.addItemToObject(root, "swupdate", swupdate = aJson.createObject()); aJson.addStringToObject(swupdate, "text", ""); aJson.addBooleanToObject(swupdate, "notify", false); // Otherwise client app shows update notice aJson.addNumberToObject(swupdate, "updatestate", 0); aJson.addStringToObject(swupdate, "url", ""); }`