Arduino Sketch - work in progress
I put this material together from various sources. No guarantees are made.
// =======================================================================
// Arduino sketch
// This is a test of controlling simulated IoT devices (LEDs) using
// the serial port. Code has been borrowed/combined from various
// existing Arduino sketches.
// -----------------------------------------------------------------------
// Commands: cascadeon, cascadeoff, cascade,
//           randomon,  randomoff,  random,
//           rgbon,     rgboff,     rgb,
//           reset,     doc
// Note: all input commands are converted to lowercase
// -----------------------------------------------------------------------
// Things to do:
// 1. make the Serial port input generate a real interrupt?
// 2. make commands MQTT messages over WIFI
// 3. create request status commands that are MQTT messages -
//    responses are MQTT messages
// 4. add random LED blinking
// 5. make each cascade blink , RGB color, random blink a separate thread?
// 6. convert to event driven?
// =======================================================================

// un-comment this line if using a Common Anode RGB LED
//#define COMMON_ANODE

// seriaL port baud rate
// Use: 300, 600, 1200, 2400, 4800, 9600, 14400, 19200,
//      28800,38400, 57600, 115200
#define BAUDRATE 19200

// command string maximum (includes ending '\0')
#define CMDMAX 64

// -----------------------------------------------------------------------
// ---- global data - pins, flags, etc.
// -----------------------------------------------------------------------

// ---- flags

bool  cascadeFlag  = false;      // flag  - blink LEDs - serial cascade
bool  randomFlag   = false;      // flag  - blink LEDs - randomly
bool  rgbColorFlag = false;      // flag  - display RGB LED colors

// ---- (random and cascade commands) array of GIOs and LEDs

#define RCGIOLEN 4
int RCGIO[RCGIOLEN]  = { 5,6,7,13 };  // GIO pins
int RCLED[RCGIOLEN];                  // led status (on/off)

// --- GIOs for RGB LED

int   redPin       = 11;         // RGB GIO pin
int   greenPin     = 10;         // RGB GIO pin
int   bluePin      =  9;         // RGB GIO pin

// ---- command buffer for serial port input

char  cmd[CMDMAX];               // incoming command buffer    

// -----------------------------------------------------------------------
// ---- display documentation
// -----------------------------------------------------------------------

void doc()
{
  Serial.println("Commands: cascadeon, cascadeoff, cascade,");
  Serial.println("          randomon,  randomoff,  random,");
  Serial.println("          rgbon,     rgboff,     rgb,");
  Serial.println("          reset,     doc");
  Serial.flush();
}

// -----------------------------------------------------------------------
// ---- set RGB LED color (common anode LED?)
// -----------------------------------------------------------------------

void setColor(int red, int green, int blue)
{
  #ifdef COMMON_ANODE
    red   = 255 - red;
    green = 255 - green;
    blue  = 255 - blue;
  #endif
  analogWrite(redPin,   red);
  analogWrite(greenPin, green);
  analogWrite(bluePin,  blue);  
}

// -----------------------------------------------------------------------
// ---- reset pins (everything off)
// -----------------------------------------------------------------------

void resetRCPins()
{
  for (int i; i < RCGIOLEN; i++) // LEDs for random/cascade commands
  {
    digitalWrite(RCGIO[i], LOW);
  }
}

void resetAllPins()
{
  resetRCPins();                 // random/cascade LEDs
  setColor(0,0,0);               // RGB LED
}

// -----------------------------------------------------------------------
// ---- initialize GIO pin mode
// -----------------------------------------------------------------------

void initPins()
{
  for (int i; i < RCGIOLEN; i++) // LEDs for random/cascade commands
  {
    pinMode(RCGIO[i], OUTPUT);
  }

  pinMode(redPin,   OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin,  OUTPUT);

  resetAllPins();
}

// -----------------------------------------------------------------------
// ---- turn LED on
// -----------------------------------------------------------------------

void turnLedOn(int led)
{
  digitalWrite(led, HIGH);      // turn a LED on
}

// -----------------------------------------------------------------------
// ---- turn LED off
// -----------------------------------------------------------------------

void turnLedOff(int led)
{
  digitalWrite(led, LOW);       // turn a LED off
}

// -----------------------------------------------------------------------
// ---- blink a LED
// -----------------------------------------------------------------------

void blinkLed(int led)
{
  turnLedOn(led);               // turn the LED on
  delay(300);                   // wait 3/10 second
  turnLedOff(led);              // turn the LED off
}

// -----------------------------------------------------------------------
// ---- blink Cascade LEDs
// -----------------------------------------------------------------------

void blinkCascadeLEDs()
{
  blinkLed(13);
  delay(500);
  blinkLed(5);
  delay(500);
  blinkLed(6);
  delay(500);
  blinkLed(7);
  delay(500);
}

// -----------------------------------------------------------------------
// ---- blink random LEDs
// -----------------------------------------------------------------------

void blinkRandomLEDs()
{
  // ---- turn on random LEDs
  for(int i = 0; i < RCGIOLEN; i++)
  {
    int r = random(2);
    if (r)
    {
      turnLedOn(RCGIO[i]);
      RCLED[i] = 1;
    }
    else
    {
       RCLED[i] = 0;
    }
  }

  // ---- pause with LEDs on
  delay(500);

  // ---- turn off LEDs
  for(int i = 0; i < RCGIOLEN; i++)
  {
    if (RCLED[i] == 1) { turnLedOff(RCGIO[i]); }
  }

  // ---- pause between blinking LEDs  
  delay(1000);
}

// -----------------------------------------------------------------------
// ---- display RGB colors
// -----------------------------------------------------------------------

void displayColors()
{
  setColor(255, 0, 0);    // red
  delay(500);
  setColor(0, 255, 0);    // green
  delay(500);
  setColor(0, 0, 255);    // blue
  delay(500);
  setColor(255, 255, 0);  // yellow
  delay(500);  
  setColor(255, 0, 255);  // magenta
  delay(300);
  setColor(0, 255, 255);  // aqua
  delay(500);
  setColor(0, 0, 0);      // off
  delay(500);
}

// -----------------------------------------------------------------------
// ---- empty serial input buffer
// -----------------------------------------------------------------------

void emptySerialInputBuffer()
{
   while(Serial.read() != -1);
}

// -----------------------------------------------------------------------
// ---- return char converted to lowercase
// -----------------------------------------------------------------------

char convertToLowercase(char c)
{
   if (c >='A' and c <= 'Z')
   {
      c |= 0b100000;
   }
   return c;
}

// -----------------------------------------------------------------------
// ---- read and process serial port input
// -----------------------------------------------------------------------

void processCommandStrings()
{
  // ---- wait for the complete message

  delay(200);
  
  // ---- get the command (string)

  int  i = 0;
  char c;
  
  while(i < CMDMAX-1)
  {
     c = Serial.read();
     if (c == '\t' or c == '\n' or c == '\0') { break; }
     cmd[i] = convertToLowercase(c);
     i++;
  }
  cmd[i] = '\0';

  // ---- work with individual characters ----
  //i = 0;
  //while(cmd[i] != '\0')
  //{
  //  Serial.print(cmd[i]);
  //  i++;
  //}
  // -----------------------------------------

  // ---- echo what was received
  //Serial.print("Received: ");
  //Serial.println(cmd);
  //Serial.flush();

  // ---- test for legal command
  if (strcmp(cmd,"cascadeon") == 0)
  {
    cascadeFlag = true;
    randomFlag  = false;
    resetRCPins();
    Serial.println("Received cascadeon command");
    Serial.flush();
  }
  else if (strcmp(cmd,"cascadeoff") == 0)
  {
    cascadeFlag = false;
    resetRCPins();
    Serial.println("Received cascade off command");
    Serial.flush();
  }
  else if (strcmp(cmd,"cascade") == 0)  // toggle cascade flag
  {
    if (cascadeFlag)
    {
      cascadeFlag = false;
    }
    else
    {
      cascadeFlag = true;
    }
    resetRCPins();
    Serial.println("Received toggle cascade command");
    Serial.flush();
  }
  else if (strcmp(cmd,"randomon") == 0)
  {
    randomFlag  = true;
    cascadeFlag = false;
    resetRCPins();
    Serial.println("Received random on command");
    Serial.flush();
  }
  else if (strcmp(cmd,"randomoff") == 0)
  {
    randomFlag = false;
    resetRCPins();
    Serial.println("Received cascade off command");
    Serial.flush();
  }
  else if (strcmp(cmd,"random") == 0)   // toggle random flag
  {
    if (randomFlag)
    {
      randomFlag = false;
    }
    else
    {
      randomFlag = true;
    }
    resetRCPins();
    Serial.println("Received toggle random command");
    Serial.flush();
  }
  else if (strcmp(cmd,"rgbon") == 0)
  {
    rgbColorFlag = true;
    setColor(0,0,0);
    Serial.println("Received a RGB on command");
    Serial.flush();
  }
  else if (strcmp(cmd,"rgboff") == 0)
  {
    rgbColorFlag = false;
    setColor(0,0,0);
    Serial.println("Received a RGB off command");
    Serial.flush();
  }
  else if (strcmp(cmd,"rgb") == 0)
  {
    if(rgbColorFlag)
    {
       rgbColorFlag = false;
    }
    else
    {
      rgbColorFlag = true;
    }
    setColor(0,0,0);
    Serial.println("Received toggle RGB command");
    Serial.flush();
  }
  else if (strcmp(cmd,"reset") == 0)
  {
    cascadeFlag  = false;
    randomFlag   = false;
    rgbColorFlag = false;
    resetAllPins();
    Serial.println("Received a reset command");
    Serial.flush();
  }
  else if (strcmp(cmd,"doc") == 0)
  {
    doc();
  }
  else
  {
    Serial.print("Say what? (");
    Serial.print(cmd);
    Serial.println(")");
    Serial.flush();
  }

  // ---- remove remaining characters in the buffer (if any)
  emptySerialInputBuffer();
}

// -----------------------------------------------------------------------
// ---- setup - runs once when you press reset or power the board
// -----------------------------------------------------------------------

void setup()
{
  Serial.begin(BAUDRATE);       // initialize serial port
  initPins();                   // initialize GIO pins

  doc();
}

// -----------------------------------------------------------------------
// ---- loop forever
// -----------------------------------------------------------------------

void loop()
{
  if(Serial.available())
  {
    processCommandStrings(); 
  }
  
  if (cascadeFlag)
  {
    blinkCascadeLEDs();
  }

  if(Serial.available())
  {
    processCommandStrings(); 
  }
  
  if (randomFlag)
  {
    blinkRandomLEDs();
  }

  if(Serial.available())
  {
    processCommandStrings(); 
  }

  if (rgbColorFlag)
  {
    displayColors();
  }
}