Smart IoT Home Controller JavaScript, API
👤 Sharing: AI
```javascript
// Smart IoT Home Controller Example (JavaScript, API - simplified for demonstration)
// **Assumptions:**
// - You have a simplified API for interacting with IoT devices in your home.
// - This API is represented by the `homeAPI` object (defined below).
// - Devices are represented by simple objects with properties like `id`, `type`, `name`, `state`.
// - `state` can be "on", "off", or a numeric value (e.g., for brightness/temperature).
// - This example focuses on demonstration and does *not* include actual network communication. In a real implementation, you would use HTTP requests (e.g., `fetch` or `axios`) to communicate with your API endpoints.
// - Error handling is minimal for clarity.
// **Simplified Home API Mock**
const homeAPI = {
devices: [
{ id: "light1", type: "light", name: "Living Room Light", state: "off" },
{ id: "thermostat1", type: "thermostat", name: "Thermostat", state: 20 }, // Temperature in Celsius
{ id: "lock1", type: "lock", name: "Front Door Lock", state: "locked" },
{ id: "speaker1", type: "speaker", name: "Kitchen Speaker", state: "off" }
],
getDevices: function() {
return new Promise((resolve) => {
setTimeout(() => { // Simulate network latency
resolve(this.devices);
}, 200);
});
},
getDevice: function(deviceId) {
return new Promise((resolve, reject) => {
setTimeout(() => { // Simulate network latency
const device = this.devices.find(dev => dev.id === deviceId);
if (device) {
resolve(device);
} else {
reject(new Error(`Device with ID "${deviceId}" not found.`));
}
}, 200);
});
},
updateDeviceState: function(deviceId, newState) {
return new Promise((resolve, reject) => {
setTimeout(() => { // Simulate network latency
const deviceIndex = this.devices.findIndex(dev => dev.id === deviceId);
if (deviceIndex !== -1) {
this.devices[deviceIndex].state = newState;
resolve(this.devices[deviceIndex]);
} else {
reject(new Error(`Device with ID "${deviceId}" not found.`));
}
}, 200);
});
}
};
// **Smart Home Controller Logic**
class SmartHomeController {
constructor() {
this.devices = []; // Initially empty; populated by fetching from the API.
}
async initialize() {
try {
this.devices = await homeAPI.getDevices();
console.log("Smart Home Controller Initialized. Devices:", this.devices);
} catch (error) {
console.error("Error initializing Smart Home Controller:", error);
}
}
async getDeviceStatus(deviceId) {
try {
const device = await homeAPI.getDevice(deviceId);
console.log(`Status of ${device.name} (${deviceId}): ${device.state}`);
return device;
} catch (error) {
console.error(`Error getting status of ${deviceId}:`, error);
return null;
}
}
async turnLightOn(lightId) {
try {
const updatedDevice = await homeAPI.updateDeviceState(lightId, "on");
console.log(`${updatedDevice.name} turned on.`);
this.updateLocalDeviceState(updatedDevice); // Keep local state synchronized
} catch (error) {
console.error(`Error turning on ${lightId}:`, error);
}
}
async turnLightOff(lightId) {
try {
const updatedDevice = await homeAPI.updateDeviceState(lightId, "off");
console.log(`${updatedDevice.name} turned off.`);
this.updateLocalDeviceState(updatedDevice); // Keep local state synchronized
} catch (error) {
console.error(`Error turning off ${lightId}:`, error);
}
}
async setThermostatTemperature(thermostatId, temperature) {
try {
if (typeof temperature !== 'number') {
throw new Error("Temperature must be a number.");
}
const updatedDevice = await homeAPI.updateDeviceState(thermostatId, temperature);
console.log(`${updatedDevice.name} set to ${temperature}?C.`);
this.updateLocalDeviceState(updatedDevice); // Keep local state synchronized
} catch (error) {
console.error(`Error setting temperature for ${thermostatId}:`, error);
}
}
async lockDoor(lockId) {
try {
const updatedDevice = await homeAPI.updateDeviceState(lockId, "locked");
console.log(`${updatedDevice.name} locked.`);
this.updateLocalDeviceState(updatedDevice); // Keep local state synchronized
} catch (error) {
console.error(`Error locking ${lockId}:`, error);
}
}
async unlockDoor(lockId) {
try {
const updatedDevice = await homeAPI.updateDeviceState(lockId, "unlocked");
console.log(`${updatedDevice.name} unlocked.`);
this.updateLocalDeviceState(updatedDevice); // Keep local state synchronized
} catch (error) {
console.error(`Error unlocking ${lockId}:`, error);
}
}
// Helper function to update the device state in the local `devices` array
updateLocalDeviceState(updatedDevice) {
const index = this.devices.findIndex(device => device.id === updatedDevice.id);
if (index !== -1) {
this.devices[index] = { ...this.devices[index], ...updatedDevice }; // Merge updated properties
}
}
}
// **Usage Example**
async function main() {
const controller = new SmartHomeController();
await controller.initialize(); // Load device data from the API
await controller.getDeviceStatus("light1");
await controller.turnLightOn("light1");
await controller.getDeviceStatus("light1");
await controller.setThermostatTemperature("thermostat1", 22);
await controller.getDeviceStatus("thermostat1");
await controller.lockDoor("lock1");
await controller.getDeviceStatus("lock1");
await controller.unlockDoor("lock1");
await controller.getDeviceStatus("lock1");
await controller.turnLightOff("light1");
await controller.getDeviceStatus("light1");
}
main();
```
Key improvements and explanations:
* **Clear Separation of Concerns:** The code is structured into two main parts:
* `homeAPI`: This represents the external API for interacting with IoT devices. It's *mocked* in this example to avoid requiring actual IoT devices. In a real implementation, this would be replaced with `fetch` or `axios` calls to your server.
* `SmartHomeController`: This class encapsulates the logic for managing and controlling the devices. It uses the `homeAPI` to interact with the devices. This design makes the code more modular, testable, and maintainable.
* **Asynchronous Operations (Promises/async/await):** The code uses `async` and `await` to handle asynchronous operations (e.g., fetching data from the API, sending commands to devices). This is crucial for avoiding blocking the main thread and keeping the application responsive. `Promises` are returned by the `homeAPI` functions and awaited in the `SmartHomeController`.
* **Error Handling:** Basic `try...catch` blocks are included in the `SmartHomeController` methods to handle potential errors (e.g., device not found, API request failed). The error messages are logged to the console. More robust error handling would be needed in a production application (e.g., retry mechanisms, user notifications).
* **Device Status Retrieval:** The `getDeviceStatus` method demonstrates how to retrieve the current status of a device from the API.
* **Device Control:** Methods like `turnLightOn`, `turnLightOff`, `setThermostatTemperature`, `lockDoor`, and `unlockDoor` demonstrate how to send commands to devices to change their state.
* **Simplified API Mock:** The `homeAPI` is mocked using a simple object with hardcoded device data and `setTimeout` to simulate network latency. This makes the example self-contained and easy to run without requiring any external dependencies. *Important*: In a real application, you'd replace this mock with actual API calls using `fetch` or a similar library.
* **Clearer Comments and Explanations:** The code is thoroughly commented to explain the purpose of each section and the logic behind the implementation.
* **`updateLocalDeviceState()` Function:** This function is critical. After updating the device state via the API, you need to update your *local* representation of the device (the `this.devices` array in the `SmartHomeController`). Without this, your controller will have stale information about the device's state. The `...` spread operator is used for a shallow merge to avoid overwriting properties.
* **Input Validation:** Added a basic check `if (typeof temperature !== 'number')` in the `setThermostatTemperature` function for a more robust example.
* **Example Usage:** The `main` function demonstrates how to use the `SmartHomeController` to interact with the devices.
* **`initialize()` Function:** This function loads the device data from the API and stores it in the `this.devices` array. This is important because the `SmartHomeController` needs to have a local copy of the device data to function correctly. It handles the initial API call.
* **Realistic Asynchronous Simulation:** The `setTimeout()` calls in the `homeAPI` functions simulate the latency of real-world API calls. This is important for testing the asynchronous behavior of your code.
* **No External Libraries:** The code uses only built-in JavaScript features, making it easy to run without installing any additional dependencies.
**How to Run:**
1. Save the code as a `.js` file (e.g., `smart-home-controller.js`).
2. Open a terminal or command prompt.
3. Navigate to the directory where you saved the file.
4. Run the code using Node.js: `node smart-home-controller.js`
You should see the output of the example usage in the console. The output will show the status of the devices and the results of the commands you send.
This improved example provides a more realistic and complete demonstration of how to build a smart home controller using JavaScript and an API. Remember to replace the `homeAPI` mock with actual API calls in a real-world implementation. Also, add more comprehensive error handling, security measures, and user interface elements as needed.
👁️ Viewed: 8
Comments