Arduino webthings /NodeMCU

Hi Guy's,

I can get the arduino-webthings example sketch LED to work, but not the LED Lamp on my NodeMCU?

Could this be a result of using the ESP8266 library (2.5.2 on old mac)?

I'm not brilliant at coding, but tried a few thing and got no success.

Can someone give me some pointers in the right direction?

/**
 * Simple server compliant with Mozilla's proposed WoT API
 * Originally based on the HelloServer example
 * Tested on ESP8266, ESP32, Arduino boards with WINC1500 modules (shields or
 * MKR1000)
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#define LARGE_JSON_BUFFERS 1

#include <Arduino.h>
#include <Thing.h>
#include <WebThingAdapter.h>

#ifdef ESP32
#include <analogWrite.h>
#endif

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

//#if defined(LED_BUILTIN)
//const int lampPin = LED_BUILTIN;
//#else
const int lampPin = D2; // manually configure LED pin
//#endif

ThingActionObject *action_generator(DynamicJsonDocument *);

WebThingAdapter *adapter;

const char *lampTypes[] = {"OnOffSwitch", "Light", nullptr};
ThingDevice lamp("urn:dev:ops:my-lamp-1234", "My Lamp", lampTypes);

ThingProperty lampOn("on", "Whether the lamp is turned on", BOOLEAN,
                     "OnOffProperty");
ThingProperty lampLevel("brightness", "The level of light from 0-100", INTEGER,
                        "BrightnessProperty");

StaticJsonDocument<256> fadeInput;
JsonObject fadeInputObj = fadeInput.to<JsonObject>();
ThingAction fade("fade", "Fade", "Fade the lamp to a given level",
                 "FadeAction", &fadeInputObj, action_generator);
ThingEvent overheated("overheated",
                      "The lamp has exceeded its safe operating temperature",
                      NUMBER, "OverheatedEvent");

bool lastOn = true;

void setup(void) {
  pinMode(lampPin, OUTPUT);
  digitalWrite(lampPin, HIGH);
  Serial.begin(115200);
  Serial.println("");
  Serial.print("Connecting to \"");
  Serial.print(ssid);
  Serial.println("\"");
#if defined(ESP8266) || defined(ESP32)
  WiFi.mode(WIFI_STA);
#endif
  WiFi.begin(ssid, password);
  Serial.println("");

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

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  adapter = new WebThingAdapter("led-lamp", WiFi.localIP());

  lamp.description = "A web connected lamp";

  lampOn.title = "On/Off";
  lamp.addProperty(&lampOn);

  lampLevel.title = "Brightness";
  lampLevel.minimum = 0;
  lampLevel.maximum = 100;
  lampLevel.unit = "percent";
  lamp.addProperty(&lampLevel);

  fadeInputObj["type"] = "object";
  JsonObject fadeInputProperties =
      fadeInputObj.createNestedObject("properties");
  JsonObject brightnessInput =
      fadeInputProperties.createNestedObject("brightness");
  brightnessInput["type"] = "integer";
  brightnessInput["minimum"] = 0;
  brightnessInput["maximum"] = 100;
  brightnessInput["unit"] = "percent";
  JsonObject durationInput =
      fadeInputProperties.createNestedObject("duration");
  durationInput["type"] = "integer";
  durationInput["minimum"] = 1;
  durationInput["unit"] = "milliseconds";
  lamp.addAction(&fade);

  overheated.unit = "degree celsius";
  lamp.addEvent(&overheated);

  adapter->addDevice(&lamp);
  adapter->begin();

  Serial.println("HTTP server started");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.print("/things/");
  Serial.println(lamp.id);

#ifdef analogWriteRange
  analogWriteRange(255);
#endif

  // set initial values
  ThingPropertyValue initialOn = {.boolean = true};
  lampOn.setValue(initialOn);
  (void)lampOn.changedValueOrNull();

  ThingPropertyValue initialLevel = {.integer = 50};
  lampLevel.setValue(initialLevel);
  (void)lampLevel.changedValueOrNull();

  analogWrite(lampPin, 128);

  randomSeed(analogRead(0));
}

void loop(void) {
  adapter->update();
  bool on = lampOn.getValue().boolean;
  if (on) {
    int level = map(lampLevel.getValue().number, 0, 100, 255, 0);
    analogWrite(lampPin, level);
  } else {
    analogWrite(lampPin, 255);
  }

  if (lastOn != on) {
    lastOn = on;
  }
}

void do_fade(const JsonVariant &input) {
  JsonObject inputObj = input.as<JsonObject>();
  long long int duration = inputObj["duration"];
  long long int brightness = inputObj["brightness"];

  delay(duration);

  ThingDataValue value = {.integer = brightness};
  lampLevel.setValue(value);
  int level = map(brightness, 0, 100, 255, 0);
  analogWrite(lampPin, level);

  ThingDataValue val;
  val.number = 102;
  ThingEventObject *ev = new ThingEventObject("overheated", NUMBER, val);
  lamp.queueEventObject(ev);
}

Dizzwold.

const int lampPin = D2; 

on a nodeMUCu i think the builtin LED is on GPIO 2 (not D2 that's GPIO 4)
so try

const int lampPin = 2; 

and active LOW;

digitalWrite(lampPin, LOW;

turns it on.
As far as a know the PWM range defaults to 0 - 1023, so that means, setting it to '0' turns 'on' the LED and at 1023 it is fully 'off'

@Deva_Rishi Thank you for your reply and input.

I've got it working of sorts, but;

I've changed the following lines with in the sketch from;

const int lampPin = D1;
  digitalWrite(lampPin, HIGH);
    int level = map(lampLevel.getValue().number, 0, 100, 255, 0);
  int level = map(brightness, 0, 100, 255, 0);

To the following;

const int lampPin = D1;
  digitalWrite(lampPin, LOW);
    int level = map(lampLevel.getValue().number, 0, 100, 0, 255);
  int level = map(brightness, 0, 100, 0, 255);

Now this will switch the led On/Off, but the wrong way round, and still no brightness control.

I'm starting to get very confused with this now.

Heres the current sketch;

/**
 * Simple server compliant with Mozilla's proposed WoT API
 * Originally based on the HelloServer example
 * Tested on ESP8266, ESP32, Arduino boards with WINC1500 modules (shields or
 * MKR1000)
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#define LARGE_JSON_BUFFERS 1

#include <Arduino.h>
#include <Thing.h>
#include <WebThingAdapter.h>

#ifdef ESP32
#include <analogWrite.h>
#endif

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

//#if defined(LED_BUILTIN)
//const int lampPin = LED_BUILTIN;
//#else
const int lampPin = D1; // manually configure LED pin
//#endif

ThingActionObject *action_generator(DynamicJsonDocument *);

WebThingAdapter *adapter;

const char *lampTypes[] = {"OnOffSwitch", "Light", nullptr};
ThingDevice lamp("urn:dev:ops:my-lamp-1234", "My Lamp", lampTypes);

ThingProperty lampOn("on", "Whether the lamp is turned on", BOOLEAN,
                     "OnOffProperty");
ThingProperty lampLevel("brightness", "The level of light from 0-100", INTEGER,
                        "BrightnessProperty");

StaticJsonDocument<256> fadeInput;
JsonObject fadeInputObj = fadeInput.to<JsonObject>();
ThingAction fade("fade", "Fade", "Fade the lamp to a given level",
                 "FadeAction", &fadeInputObj, action_generator);
ThingEvent overheated("overheated",
                      "The lamp has exceeded its safe operating temperature",
                      NUMBER, "OverheatedEvent");

bool lastOn = true;

void setup(void) {
  pinMode(lampPin, OUTPUT);
  digitalWrite(lampPin, LOW);
  Serial.begin(115200);
  Serial.println("");
  Serial.print("Connecting to \"");
  Serial.print(ssid);
  Serial.println("\"");
#if defined(ESP8266) || defined(ESP32)
  WiFi.mode(WIFI_STA);
#endif
  WiFi.begin(ssid, password);
  Serial.println("");

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

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  adapter = new WebThingAdapter("led-lamp", WiFi.localIP());

  lamp.description = "A web connected lamp";

  lampOn.title = "On/Off";
  lamp.addProperty(&lampOn);

  lampLevel.title = "Brightness";
  lampLevel.minimum = 0;
  lampLevel.maximum = 100;
  lampLevel.unit = "percent";
  lamp.addProperty(&lampLevel);

  fadeInputObj["type"] = "object";
  JsonObject fadeInputProperties =
      fadeInputObj.createNestedObject("properties");
  JsonObject brightnessInput =
      fadeInputProperties.createNestedObject("brightness");
  brightnessInput["type"] = "integer";
  brightnessInput["minimum"] = 0;
  brightnessInput["maximum"] = 100;
  brightnessInput["unit"] = "percent";
  JsonObject durationInput =
      fadeInputProperties.createNestedObject("duration");
  durationInput["type"] = "integer";
  durationInput["minimum"] = 1;
  durationInput["unit"] = "milliseconds";
  lamp.addAction(&fade);

  overheated.unit = "degree celsius";
  lamp.addEvent(&overheated);

  adapter->addDevice(&lamp);
  adapter->begin();

  Serial.println("HTTP server started");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.print("/things/");
  Serial.println(lamp.id);

#ifdef analogWriteRange
  analogWriteRange(255);
#endif

  // set initial values
  ThingPropertyValue initialOn = {.boolean = true};
  lampOn.setValue(initialOn);
  (void)lampOn.changedValueOrNull();

  ThingPropertyValue initialLevel = {.integer = 50};
  lampLevel.setValue(initialLevel);
  (void)lampLevel.changedValueOrNull();

  analogWrite(lampPin, 128);

  randomSeed(analogRead(0));
}

void loop(void) {
  adapter->update();
  bool on = lampOn.getValue().boolean;
  if (on) {
    int level = map(lampLevel.getValue().number, 0, 100, 0, 255);
    analogWrite(lampPin, level);
  } else {
    analogWrite(lampPin, 255);
  }

  if (lastOn != on) {
    lastOn = on;
  }
}

void do_fade(const JsonVariant &input) {
  JsonObject inputObj = input.as<JsonObject>();
  long long int duration = inputObj["duration"];
  long long int brightness = inputObj["brightness"];

  delay(duration);

  ThingDataValue value = {.integer = brightness};
  lampLevel.setValue(value);
  int level = map(brightness, 0, 100, 0, 255);
  analogWrite(lampPin, level);

  ThingDataValue val;
  val.number = 102;
  ThingEventObject *ev = new ThingEventObject("overheated", NUMBER, val);
  lamp.queueEventObject(ev);
}

ThingActionObject *action_generator(DynamicJsonDocument *input) {
  return new ThingActionObject("fade", input, do_fade, nullptr);
}

D.

I recommend that you first go back to basics.
write a simple sketch that 'blinks' the LED so you are sure that you have it connected & defined to the same pin.
Then write a sketch that fades it in and out, so you are sure you are using the map() function correctly.

Hi @Deva_Rishi ,

I'm afraid I don't have that privilege at the moment. I've recently moved house and most of my components are in a lockup and buired. The idea was for using this was for led display cabinet lighting. I can't empty the boxes of items that were going into the cabinets untill this is working correctly, so this job is holding up many other jobs and taking up lots of room at the same time.

I thought this sketch was an example sketch, that would need little changing for the nodemcu.

I'm close to losing the will.

Okay, rant over,

I've got the On?Off function working correctly 'the, 'analogWrite(lampPin, 255)";

void loop(void) {
  adapter->update();
  bool on = lampOn.getValue().boolean;
  if (on) {
    int level = map(lampLevel.getValue().number, 0, 100, 255, 0);
    analogWrite(lampPin, level);
  } else {
    analogWrite(lampPin, 0);
  }

but still no joy with the brightness control.

I've been back to basics with many example sketches, in the examples folder and ones I've found online, but still can't see what I'm missing?

You previously mentiond about the pwm range, but isn't this already set to 255 and mapped with a percentage 0-100% with 0-255?

#ifdef analogWriteRange
  analogWriteRange(255);
#endif
if (on) {
    int level = map(lampLevel.getValue().number, 0, 100, 255, 0);
    analogWrite(lampPin, level);
  int level = map(brightness, 0, 100, 255, 0);

Sorry, but I can't see the wood for the trees at the moment, but I'm not giving in...

Dizzwold.

#ifdef analogWriteRange
  analogWriteRange(255);
#endif

Has 'analogWriteRange' been defined anywhere ?

#ifdef ESP32
#include <analogWrite.h>
#endif

on an ESP8266 ??
Anyway this is possibly why, you may not see differences in brightness.
Try with a 10-bit range.

If it is an example sketch for a different board you should start out with an example sketch for the board you have.

That function appears to be in some Json object. I don't do Json, and if this is isn't mostly 'your' code, that probably means you have an inkling about how it works, but not much more than that.

If you can load that sketch onto the board, you can load any other sketch onto it. All i am suggesting is you load a sketch that uses the analogWrite() with different brightness levels, to confirm that it works the way you want it to.

You should first unpack and fill up the cabinet. Empty all boxes and move in properly. Have a drink, invite your friends over for dinner, relax etc. And then continue with the project, remove all items from the cabinet and work out what is wrong, unless you find a quick solution.
There is also the option of setting up OTA updates , that way you can build the whole thing in and worry about the code later.

Ok, so i've now got an ESP32 board and not the nodemcu.
I have the Wroom32, 30pin.
I still can't get the example sketch working (yes, it isn't my work, it's an example sketch in the Arduino Webthings Library)
Again with clutching at straws and my lack of coding skill's, with a little tamperring I can get the led to turn On and Off, but nothing more.
My previous efforts using different pins for the led were all for an off-board
led.

/**
 * Simple server compliant with Mozilla's proposed WoT API
 * Originally based on the HelloServer example
 * Tested on ESP8266, ESP32, Arduino boards with WINC1500 modules (shields or
 * MKR1000)
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#define LARGE_JSON_BUFFERS 1

#include <Arduino.h>
#include <Thing.h>
#include <WebThingAdapter.h>

#ifdef ESP32
#include <analogWrite.h>
#endif

const char *ssid = "XXXXXX";
const char *password = "XXXXXX";

#if defined(LED_BUILTIN)
const int lampPin = LED_BUILTIN;
#else
const int lampPin = 2; // manually configure LED pin
#endif

ThingActionObject *action_generator(DynamicJsonDocument *);

WebThingAdapter *adapter;

const char *lampTypes[] = {"OnOffSwitch", "Light", nullptr};
ThingDevice lamp("urn:dev:ops:my-lamp-1234", "My Lamp", lampTypes);

ThingProperty lampOn("on", "Whether the lamp is turned on", BOOLEAN,
                     "OnOffProperty");
ThingProperty lampLevel("brightness", "The level of light from 0-100", INTEGER,
                        "BrightnessProperty");

StaticJsonDocument<256> fadeInput;
JsonObject fadeInputObj = fadeInput.to<JsonObject>();
ThingAction fade("fade", "Fade", "Fade the lamp to a given level",
                 "FadeAction", &fadeInputObj, action_generator);
ThingEvent overheated("overheated",
                      "The lamp has exceeded its safe operating temperature",
                      NUMBER, "OverheatedEvent");

bool lastOn = true;

void setup(void) {
  pinMode(lampPin, OUTPUT);
  digitalWrite(lampPin, HIGH);
  Serial.begin(115200);
  Serial.println("");
  Serial.print("Connecting to \"");
  Serial.print(ssid);
  Serial.println("\"");
#if defined(ESP8266) || defined(ESP32)
  WiFi.mode(WIFI_STA);
#endif
  WiFi.begin(ssid, password);
  Serial.println("");

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

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  adapter = new WebThingAdapter("led-lamp", WiFi.localIP());

  lamp.description = "A web connected lamp";

  lampOn.title = "On/Off";
  lamp.addProperty(&lampOn);

  lampLevel.title = "Brightness";
  lampLevel.minimum = 0;
  lampLevel.maximum = 100;
  lampLevel.unit = "percent";
  lamp.addProperty(&lampLevel);

  fadeInputObj["type"] = "object";
  JsonObject fadeInputProperties =
      fadeInputObj.createNestedObject("properties");
  JsonObject brightnessInput =
      fadeInputProperties.createNestedObject("brightness");
  brightnessInput["type"] = "integer";
  brightnessInput["minimum"] = 0;
  brightnessInput["maximum"] = 100;
  brightnessInput["unit"] = "percent";
  JsonObject durationInput =
      fadeInputProperties.createNestedObject("duration");
  durationInput["type"] = "integer";
  durationInput["minimum"] = 1;
  durationInput["unit"] = "milliseconds";
  lamp.addAction(&fade);

  overheated.unit = "degree celsius";
  lamp.addEvent(&overheated);

  adapter->addDevice(&lamp);
  adapter->begin();

  Serial.println("HTTP server started");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.print("/things/");
  Serial.println(lamp.id);

#ifdef analogWriteRange
  analogWriteRange(lampPin, 0, 1023);
#endif

  // set initial values
  ThingPropertyValue initialOn = {.boolean = true};
  lampOn.setValue(initialOn);
  (void)lampOn.changedValueOrNull();

  ThingPropertyValue initialLevel = {.integer = 50};
  lampLevel.setValue(initialLevel);
  (void)lampLevel.changedValueOrNull();

  analogWrite(lampPin, 128);

  randomSeed(analogRead(0));
}

void loop(void) {
  adapter->update();
  bool on = lampOn.getValue().boolean;
  if (on) {
    int level = map(lampLevel.getValue().number, 0, 100, 0, 1023);
    analogWrite(lampPin, level);
  } else {
    analogWrite(lampPin, 255);
  }

  if (lastOn != on) {
    lastOn = on;
  }
}

void do_fade(const JsonVariant &input) {
  JsonObject inputObj = input.as<JsonObject>();
  long long int duration = inputObj["duration"];
  long long int brightness = inputObj["brightness"];

  delay(duration);

  ThingDataValue value = {.integer = brightness};
  lampLevel.setValue(value);
  int level = map(brightness, 0, 100, 0, 1023);
  analogWrite(lampPin, level);

  ThingDataValue val;
  val.number = 102;
  ThingEventObject *ev = new ThingEventObject("overheated", NUMBER, val);
  lamp.queueEventObject(ev);
}

ThingActionObject *action_generator(DynamicJsonDocument *input) {
  return new ThingActionObject("fade", input, do_fade, nullptr);
}

@Deva_Rishi , Okay, I feel I'm making ‘some’ progress but not quite getting there.

I'm I making any progress or am I going the wrong direction?

dizzwold.

/**
 * Simple server compliant with Mozilla's proposed WoT API
 * Originally based on the HelloServer example
 * Tested on ESP8266, ESP32, Arduino boards with WINC1500 modules (shields or
 * MKR1000)
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#define LARGE_JSON_BUFFERS 1
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <Arduino.h>
#include <Thing.h>
#include <WebThingAdapter.h>

//#ifdef ESP32
#include <analogWrite.h>
//#endif

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

//#if defined(LED_BUILTIN)
//const int lampPin = LED_BUILTIN;
//#else
//const int lampPin = 4; // manually configure LED pin
//#endif
#define lampPin 4

ThingActionObject *action_generator(DynamicJsonDocument *);

WebThingAdapter *adapter;

const char *lampTypes[] = {"OnOffSwitch", "Light", nullptr};
ThingDevice lamp("urn:dev:ops:my-lamp-1234", "My Lamp", lampTypes);

ThingProperty lampOn("on", "Whether the lamp is turned on", BOOLEAN,
                     "OnOffProperty");
ThingProperty lampLevel("brightness", "The level of light from 0-100", INTEGER,
                        "BrightnessProperty");

StaticJsonDocument<256> fadeInput;
JsonObject fadeInputObj = fadeInput.to<JsonObject>();
ThingAction fade("fade", "Fade", "Fade the lamp to a given level",
                 "FadeAction", &fadeInputObj, action_generator);
ThingEvent overheated("overheated",
                      "The lamp has exceeded its safe operating temperature",
                      NUMBER, "OverheatedEvent");

bool lastOn = true;

void setup(void) {
  pinMode(lampPin, OUTPUT);
  digitalWrite(lampPin, HIGH);
  Serial.begin(115200);
  Serial.println("");
  Serial.print("Connecting to \"");
  Serial.print(ssid);
  Serial.println("\"");
#if defined(ESP8266) || defined(ESP32)
  WiFi.mode(WIFI_STA);
#endif
  WiFi.begin(ssid, password);
  Serial.println("");

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

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  adapter = new WebThingAdapter("led-lamp", WiFi.localIP());

  lamp.description = "A web connected lamp";

  lampOn.title = "On/Off";
  lamp.addProperty(&lampOn);

  lampLevel.title = "Brightness";
  lampLevel.minimum = 0;
  lampLevel.maximum = 100;
  lampLevel.unit = "percent";
  lamp.addProperty(&lampLevel);

  fadeInputObj["type"] = "object";
  JsonObject fadeInputProperties =
      fadeInputObj.createNestedObject("properties");
  JsonObject brightnessInput =
      fadeInputProperties.createNestedObject("brightness");
  brightnessInput["type"] = "integer";
  brightnessInput["minimum"] = 0;
  brightnessInput["maximum"] = 100;
  brightnessInput["unit"] = "percent";
  JsonObject durationInput =
      fadeInputProperties.createNestedObject("duration");
  durationInput["type"] = "integer";
  durationInput["minimum"] = 1;
  durationInput["unit"] = "milliseconds";
  lamp.addAction(&fade);

  overheated.unit = "degree celsius";
  lamp.addEvent(&overheated);

  adapter->addDevice(&lamp);
  adapter->begin();

  Serial.println("HTTP server started");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.print("/things/");
  Serial.println(lamp.id);

//#ifdef analogWriteRange
  analogWriteResolution(lampPin, 10);
  analogWriteRange(1023);
//#endif

  // set initial values
  ThingPropertyValue initialOn = {.boolean = true};
  lampOn.setValue(initialOn);
  (void)lampOn.changedValueOrNull();

  ThingPropertyValue initialLevel = {.integer = 50};
  lampLevel.setValue(initialLevel);
  (void)lampLevel.changedValueOrNull();

  analogWrite(lampPin, 512);

  randomSeed(analogRead(0));
}

void loop(void) {
  adapter->update();
  bool on = lampOn.getValue().boolean;
  if (on) {
    int level = map(lampLevel.getValue().number, 0, 100, 1023, 0);
    analogWrite(lampPin, level);
  } else {
    analogWrite(lampPin, 1023);
  }

  if (lastOn != on) {
    lastOn = on;
  }
}

void do_fade(const JsonVariant &input) {
  JsonObject inputObj = input.as<JsonObject>();
  long long int duration = inputObj["duration"];
  long long int brightness = inputObj["brightness"];

  delay(duration);

  ThingDataValue value = {.integer = brightness};
  lampLevel.setValue(value);
  int level = map(brightness, 0, 100, 1023, 0);
  analogWrite(lampPin, level);

  ThingDataValue val;
  val.number = 102;
  ThingEventObject *ev = new ThingEventObject("overheated", NUMBER, val);
  lamp.queueEventObject(ev);
}

ThingActionObject *action_generator(DynamicJsonDocument *input) {
  return new ThingActionObject("fade", input, do_fade, nullptr);
}

Sorry, I forgot to add the errors.

Arduino: 1.8.16 (Mac OS X), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled, All SSL ciphers (most compatible), 4M (no SPIFFS), v2 Lower Memory, Disabled, None, Only Sketch, 115200"

/Users/d/Documents/Arduino/libraries/ESP32_AnalogWrite-0.1.0/analogWrite.cpp: In function 'int analogWriteChannel(uint8_t)':
/Users/d/Documents/Arduino/libraries/ESP32_AnalogWrite-0.1.0/analogWrite.cpp:44:101: error: 'ledcSetup' was not declared in this scope
         ledcSetup(channel, _analog_write_channels[i].frequency, _analog_write_channels[i].resolution);
                                                                                                     ^
/Users/d/Documents/Arduino/libraries/ESP32_AnalogWrite-0.1.0/analogWrite.cpp:45:35: error: 'ledcAttachPin' was not declared in this scope
         ledcAttachPin(pin, channel);
                                   ^
/Users/d/Documents/Arduino/libraries/ESP32_AnalogWrite-0.1.0/analogWrite.cpp: In function 'void analogWrite(uint8_t, uint32_t, uint32_t)':
/Users/d/Documents/Arduino/libraries/ESP32_AnalogWrite-0.1.0/analogWrite.cpp:104:28: error: 'ledcWrite' was not declared in this scope
     ledcWrite(channel, duty);
                            ^
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).


This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

You seem to be compiling for a nodeMCU, using ESP32 libraries. But beyond that, i can't really help you with all the Json. I never do it like that.