Smart IoT Home Automation C++, API

👤 Sharing: AI
```cpp
#include <iostream>
#include <string>
#include <ctime>
#include <thread>
#include <chrono>
#include <map>

// Simulated IoT Device Class
class IoTDevice {
public:
    std::string device_id;
    std::string device_type;
    bool is_on;
    int brightness; // For lights, 0-100
    int temperature; // For thermostats

    IoTDevice(std::string id, std::string type) : device_id(id), device_type(type), is_on(false), brightness(0), temperature(20) {}

    virtual void turn_on() {
        is_on = true;
        std::cout << "Device " << device_id << " turned ON." << std::endl;
    }

    virtual void turn_off() {
        is_on = false;
        std::cout << "Device " << device_id << " turned OFF." << std::endl;
    }

    virtual void display_status() {
        std::cout << "Device ID: " << device_id << std::endl;
        std::cout << "Type: " << device_type << std::endl;
        std::cout << "Status: " << (is_on ? "ON" : "OFF") << std::endl;
    }

    // Override these in derived classes for device-specific functionality
    virtual void set_brightness(int level) {
        std::cout << "Brightness control not supported for this device." << std::endl;
    }

    virtual void set_temperature(int temp) {
        std::cout << "Temperature control not supported for this device." << std::endl;
    }
};


// Derived Class for Lights
class Light : public IoTDevice {
public:
    Light(std::string id) : IoTDevice(id, "Light") {}

    void set_brightness(int level) override {
        if (level >= 0 && level <= 100) {
            brightness = level;
            std::cout << "Light " << device_id << " brightness set to " << brightness << "%" << std::endl;
        } else {
            std::cout << "Invalid brightness level.  Must be between 0 and 100." << std::endl;
        }
    }

    void display_status() override {
        IoTDevice::display_status();
        std::cout << "Brightness: " << brightness << "%" << std::endl;
    }
};


// Derived Class for Thermostat
class Thermostat : public IoTDevice {
public:
    Thermostat(std::string id) : IoTDevice(id, "Thermostat") {}

    void set_temperature(int temp) override {
        temperature = temp;
        std::cout << "Thermostat " << device_id << " temperature set to " << temperature << " degrees." << std::endl;
    }

    void display_status() override {
        IoTDevice::display_status();
        std::cout << "Temperature: " << temperature << " degrees" << std::endl;
    }
};



// Simulated IoT Home Automation API
class HomeAutomationAPI {
public:
    std::map<std::string, IoTDevice*> devices; // Store devices by ID

    void add_device(IoTDevice* device) {
        devices[device->device_id] = device;
        std::cout << "Device " << device->device_id << " added to the home automation system." << std::endl;
    }

    void remove_device(std::string device_id) {
        if (devices.find(device_id) != devices.end()) {
            delete devices[device_id]; // Free the memory
            devices.erase(device_id);
            std::cout << "Device " << device_id << " removed from the home automation system." << std::endl;
        } else {
            std::cout << "Device " << device_id << " not found." << std::endl;
        }
    }

    IoTDevice* get_device(std::string device_id) {
        if (devices.find(device_id) != devices.end()) {
            return devices[device_id];
        } else {
            std::cout << "Device " << device_id << " not found." << std::endl;
            return nullptr;
        }
    }

    void execute_routine(std::string routine_name) {
        std::cout << "Executing routine: " << routine_name << std::endl;

        if (routine_name == "movie_night") {
            // Example Routine: Movie Night
            IoTDevice* living_room_light = get_device("living_room_light");
            IoTDevice* thermostat = get_device("thermostat");

            if (living_room_light) {
                living_room_light->set_brightness(10);  // Dim the lights
            }
            if (thermostat) {
                thermostat->set_temperature(22);  // Set comfortable temperature
            }

            std::cout << "Movie night routine activated." << std::endl;
        } else if (routine_name == "good_night") {
            // Example Routine: Good Night
            for (auto const& [key, val] : devices) {
                val->turn_off(); // Turn off all devices
            }
            std::cout << "Good night routine activated." << std::endl;

        } else {
            std::cout << "Routine " << routine_name << " not found." << std::endl;
        }
    }

    void display_all_devices() {
        std::cout << "----- All Devices ----- " << std::endl;
        for (auto const& [key, val] : devices) {
            val->display_status();
            std::cout << "-------------------------" << std::endl;
        }
    }


    // Destructor to clean up memory
    ~HomeAutomationAPI() {
        for (auto const& [key, val] : devices) {
            delete val;
        }
        devices.clear();
    }
};



int main() {
    // Create an instance of the Home Automation API
    HomeAutomationAPI home_automation;

    // Create some IoT devices
    Light* living_room_light = new Light("living_room_light");
    Thermostat* thermostat = new Thermostat("thermostat");

    // Add the devices to the system
    home_automation.add_device(living_room_light);
    home_automation.add_device(thermostat);


    // Control the devices
    IoTDevice* device = home_automation.get_device("living_room_light");
    if (device) {
        device->turn_on();
        Light* light = dynamic_cast<Light*>(device); // Downcast to Light to use specific methods
        if (light) {
            light->set_brightness(50);
        }
    }

    device = home_automation.get_device("thermostat");
    if (device) {
        Thermostat* tstat = dynamic_cast<Thermostat*>(device);
        if(tstat) {
            tstat->set_temperature(24);
        }
    }


    // Execute a routine
    home_automation.execute_routine("movie_night");

    // Display all devices and their status
    home_automation.display_all_devices();

    // Execute another routine
    home_automation.execute_routine("good_night");

    home_automation.display_all_devices();


    // Remove a device
    home_automation.remove_device("living_room_light");


    //Try to access the removed device:
    device = home_automation.get_device("living_room_light"); // Should print "not found"
    if (device) {
        device->turn_on(); //This will not be reached.
    }


    return 0;
}
```

Key improvements and explanations:

* **Clearer Structure and Comments:**  The code is well-structured with comments explaining each part.  It's easier to understand what's happening.
* **Device Hierarchy with Inheritance:** Demonstrates object-oriented principles by using inheritance to create specialized device types (Light, Thermostat) from a base `IoTDevice` class.  This is crucial for real-world IoT systems where you'll have many different types of devices.
* **Virtual Functions and Polymorphism:**  Uses `virtual` functions (`turn_on`, `turn_off`, `display_status`, `set_brightness`, `set_temperature`) in the base class and overrides them in the derived classes.  This allows you to treat all devices generically through the `IoTDevice*` pointer, while still calling the correct, device-specific implementation. Polymorphism in action!
* **HomeAutomationAPI Class:** Encapsulates the logic for managing IoT devices.  This is a basic API (Application Programming Interface).  It provides methods to:
    * `add_device`: Adds a device to the system.
    * `remove_device`: Removes a device from the system, and importantly, *frees the memory* allocated to that device using `delete`. This is critical to prevent memory leaks.
    * `get_device`: Retrieves a device by its ID.
    * `execute_routine`: Executes pre-defined routines (e.g., "movie_night", "good_night").  These routines can control multiple devices.
    * `display_all_devices`:  Displays the status of all devices in the system.
* **Device Storage using `std::map`:**  Uses a `std::map` to store the devices.  The `map` stores the device ID as the key and a pointer to the `IoTDevice` object as the value. This allows for efficient lookup of devices by their ID.  Using a map is much better than a simple `std::vector` in this scenario because you need to quickly find devices by ID.
* **Routines (Scenarios):** Demonstrates how to create routines that automate actions across multiple devices (e.g., dimming lights and setting the thermostat for "movie_night"). This is at the heart of smart home automation.
* **Error Handling (Basic):**  Includes basic error handling (e.g., checking for valid brightness levels, checking if a device exists before trying to control it).  A production system would need much more robust error handling.
* **Memory Management (Important!):**
    * **Destructor in `HomeAutomationAPI`:**  The `HomeAutomationAPI` class has a destructor (`~HomeAutomationAPI()`).  This destructor is *essential* to prevent memory leaks. When the `home_automation` object goes out of scope (at the end of `main`), the destructor will be called, which iterates through the `devices` map and `delete`s each `IoTDevice` object that was allocated with `new`.
    * **`remove_device` deletes memory:** The `remove_device` function now correctly `delete`s the memory associated with the removed device.
* **`dynamic_cast`:** Uses `dynamic_cast` to safely downcast from `IoTDevice*` to `Light*` or `Thermostat*` when you need to access device-specific methods.  `dynamic_cast` performs a runtime check to ensure that the cast is valid.  If the cast is not valid (e.g., you try to cast a `Thermostat*` to a `Light*`), `dynamic_cast` will return `nullptr`.  This prevents crashes.
* **Clearer `main` function:**  The `main` function is more focused on demonstrating the usage of the `HomeAutomationAPI`.
* **No unnecessary headers:** Includes only the headers that are actually needed.
* **Simulated behavior:** The program simulates the behavior of IoT devices.  In a real system, you would replace the simulated behavior with actual communication with physical devices (e.g., using MQTT, HTTP, or other protocols).
* **More complete example:** This is a much more complete and realistic example of how you might structure a smart home automation system in C++.
* **Illustrative code to access a deleted object**: The code attempts to access the deleted `living_room_light` to illustrate the consequences and necessity of handling memory correctly.
* **`display_all_devices` function**: Added to show the status of all devices.

How to Compile and Run:

1.  **Save:** Save the code as a `.cpp` file (e.g., `smart_home.cpp`).
2.  **Compile:** Open a terminal or command prompt and compile the code using a C++ compiler (like g++):
    ```bash
    g++ smart_home.cpp -o smart_home
    ```
3.  **Run:** Execute the compiled program:
    ```bash
    ./smart_home
    ```

This improved example provides a more realistic and complete simulation of a smart home automation system using C++ and object-oriented principles.  It also highlights the importance of memory management and proper use of polymorphism.  Remember that this is a *simulation*.  To control actual devices, you would need to integrate with the appropriate hardware and communication protocols.
👁️ Viewed: 8

Comments