#include "signal_Slot.h"
// =================================
// CURRENT LIMITATION EXAMPLE
// =================================
/*
Problem: Want to turn on heating ONLY when:
- Temperature is low AND
- Motion is detected AND
- Time is between 6 PM - 8 AM
With current system, each signal triggers independently:
- "temperature_low" ā always activates heating
- "motion_detected" ā always turns on lights
- No way to combine conditions
*/
// =================================
// SOLUTION 1: STATE-BASED SLOTS
// =================================
// Global state tracking
struct SystemState {
bool tempLow = false;
bool motionDetected = false;
bool nightTime = false;
bool highHumidity = false;
bool lightLow = false;
unsigned long lastMotionTime = 0;
} systemState;
SignalSlot eventSystem;
// State update slots (these update state and check conditions)
void updateTempLowState() {
systemState.tempLow = true;
Serial.println("š”ļø State: Temperature is LOW");
checkSmartHeatingConditions(); // Check if we should activate heating
}
void updateTempNormalState() {
systemState.tempLow = false;
Serial.println("š”ļø State: Temperature is NORMAL");
checkSmartHeatingConditions(); // Might need to turn off heating
}
void updateMotionState() {
systemState.motionDetected = true;
systemState.lastMotionTime = millis();
Serial.println("š¤ State: Motion DETECTED");
checkSmartHeatingConditions(); // Smart heating
checkSmartLightingConditions(); // Smart lighting
checkSmartSecurityConditions(); // Smart security
}
void updateHumidityState() {
systemState.highHumidity = true;
Serial.println("š§ State: Humidity is HIGH");
checkSmartVentilationConditions();
}
void updateLightState() {
systemState.lightLow = true;
Serial.println("āļø State: Light is LOW");
checkSmartLightingConditions();
}
// =================================
// MULTI-CONDITION LOGIC FUNCTIONS
// =================================
// Smart Heating: Only activate if temp low + motion detected + night time
void checkSmartHeatingConditions() {
bool shouldActivateHeating = systemState.tempLow &&
systemState.motionDetected &&
systemState.nightTime;
if (shouldActivateHeating) {
Serial.println("š„ SMART HEATING: All conditions met - Activating!");
Serial.println(" ā Temperature low");
Serial.println(" ā Motion detected");
Serial.println(" ā Night time");
// digitalWrite(HEATER_PIN, HIGH);
} else {
Serial.println("š„ SMART HEATING: Conditions not met - Staying off");
if (!systemState.tempLow) Serial.println(" ā Temperature OK");
if (!systemState.motionDetected) Serial.println(" ā No motion");
if (!systemState.nightTime) Serial.println(" ā Daytime");
// digitalWrite(HEATER_PIN, LOW);
}
}
// Smart Lighting: Motion + (Low light OR Night time)
void checkSmartLightingConditions() {
bool shouldTurnOnLights = systemState.motionDetected &&
(systemState.lightLow || systemState.nightTime);
if (shouldTurnOnLights) {
Serial.println("š” SMART LIGHTING: Turning ON lights");
Serial.println(" ā Motion detected");
Serial.println(" ā " + String(systemState.lightLow ? "Low light" : "Night time"));
// digitalWrite(LIGHTS_PIN, HIGH);
} else {
Serial.println("š” SMART LIGHTING: Lights staying OFF");
// digitalWrite(LIGHTS_PIN, LOW);
}
}
// Smart Ventilation: High humidity + Motion (someone is home) + Temp high
void checkSmartVentilationConditions() {
bool recentMotion = (millis() - systemState.lastMotionTime) < 300000; // 5 minutes
bool shouldActivateVent = systemState.highHumidity && recentMotion;
if (shouldActivateVent) {
Serial.println("š¬ļø SMART VENTILATION: Activating fan");
Serial.println(" ā High humidity");
Serial.println(" ā Recent motion (someone home)");
// digitalWrite(FAN_PIN, HIGH);
} else {
Serial.println("š¬ļø SMART VENTILATION: Fan staying off");
}
}
// Smart Security: Motion + Night time + No recent authorized access
void checkSmartSecurityConditions() {
bool shouldTriggerAlert = systemState.motionDetected &&
systemState.nightTime;
if (shouldTriggerAlert) {
Serial.println("šØ SMART SECURITY: ALERT - Motion during night!");
Serial.println(" ā ļø Starting recording");
Serial.println(" ā ļø Sending notification");
// Start camera, send alert, etc.
}
}
// =================================
// SOLUTION 2: ENHANCED SIGNALSLOT CLASS
// =================================
class EnhancedSignalSlot {
private:
struct MultiConditionSlot {
String conditions[5]; // Up to 5 conditions (signals)
int conditionCount;
bool conditionStates[5]; // Track which conditions are met
bool requireAll; // true = AND logic, false = OR logic
void (*callback)(); // Function to call when conditions met
String name; // For debugging
};
MultiConditionSlot multiSlots[10]; // Support up to 10 multi-condition slots
int multiSlotCount = 0;
SignalSlot* baseSystem; // Pointer to your original system
public:
EnhancedSignalSlot(SignalSlot* base) : baseSystem(base), multiSlotCount(0) {}
// Add a multi-condition slot
bool addMultiConditionSlot(const String& name,
const String conditions[],
int condCount,
bool requireAll,
void (*callback)()) {
if (multiSlotCount >= 10 || condCount > 5) return false;
MultiConditionSlot& slot = multiSlots[multiSlotCount];
slot.name = name;
slot.conditionCount = condCount;
slot.requireAll = requireAll;
slot.callback = callback;
// Copy conditions and initialize states
for (int i = 0; i < condCount; i++) {
slot.conditions[i] = conditions[i];
slot.conditionStates[i] = false;
}
multiSlotCount++;
Serial.println("ā
Added multi-condition slot: " + name);
return true;
}
// Call this whenever any signal is emitted
void checkMultiConditions(const String& signalName) {
for (int i = 0; i < multiSlotCount; i++) {
MultiConditionSlot& slot = multiSlots[i];
// Update condition states
for (int j = 0; j < slot.conditionCount; j++) {
if (slot.conditions[j] == signalName) {
slot.conditionStates[j] = true;
break;
}
}
// Check if conditions are met
bool conditionsMet = false;
if (slot.requireAll) {
// AND logic - all conditions must be true
conditionsMet = true;
for (int j = 0; j < slot.conditionCount; j++) {
if (!slot.conditionStates[j]) {
conditionsMet = false;
break;
}
}
} else {
// OR logic - any condition true
conditionsMet = false;
for (int j = 0; j < slot.conditionCount; j++) {
if (slot.conditionStates[j]) {
conditionsMet = true;
break;
}
}
}
if (conditionsMet) {
Serial.println("šÆ Multi-condition met for: " + slot.name);
slot.callback();
// Reset states after triggering (optional behavior)
for (int j = 0; j < slot.conditionCount; j++) {
slot.conditionStates[j] = false;
}
}
}
}
// Reset specific condition states
void resetCondition(const String& signalName) {
for (int i = 0; i < multiSlotCount; i++) {
MultiConditionSlot& slot = multiSlots[i];
for (int j = 0; j < slot.conditionCount; j++) {
if (slot.conditions[j] == signalName) {
slot.conditionStates[j] = false;
}
}
}
}
};
// Enhanced system instance
EnhancedSignalSlot enhancedSystem(&eventSystem);
// =================================
// MULTI-CONDITION SLOT FUNCTIONS
// =================================
void smartHeatingActivate() {
Serial.println("š„šÆ ENHANCED: Smart heating activated!");
Serial.println(" (Temperature low + Motion + Night time)");
}
void emergencyVentilation() {
Serial.println("š¬ļøā ļø ENHANCED: Emergency ventilation!");
Serial.println(" (High humidity + High temp + Motion)");
}
void securityLockdown() {
Serial.println("ššØ ENHANCED: Security lockdown initiated!");
Serial.println(" (Motion + Night + No auth + High temp)");
}
void comfortMode() {
Serial.println("šš ENHANCED: Comfort mode activated!");
Serial.println(" (Motion OR Light change OR Temp change)");
}
// =================================
// TIMER-BASED STATE UPDATES
// =================================
void updateTimeBasedStates() {
// Simulate time-based conditions
int hour = (millis() / 10000) % 24; // Simulate hours
systemState.nightTime = (hour < 8 || hour > 18);
// Motion detection timeout
if (millis() - systemState.lastMotionTime > 30000) { // 30 seconds
systemState.motionDetected = false;
}
}
// =================================
// EXAMPLE USAGE FUNCTIONS
// =================================
void demonstrateCurrentSystem() {
Serial.println("\n=== DEMONSTRATING CURRENT SYSTEM ===");
// Connect simple single-signal slots
eventSystem.connect("temperature_low", updateTempLowState);
eventSystem.connect("temperature_normal", updateTempNormalState);
eventSystem.connect("motion_detected", updateMotionState);
eventSystem.connect("humidity_high", updateHumidityState);
eventSystem.connect("light_low", updateLightState);
}
void demonstrateEnhancedSystem() {
Serial.println("\n=== DEMONSTRATING ENHANCED SYSTEM ===");
// Set up multi-condition slots
String heatingConditions[] = {"temperature_low", "motion_detected", "night_time"};
enhancedSystem.addMultiConditionSlot("SmartHeating", heatingConditions, 3, true, smartHeatingActivate);
String ventConditions[] = {"humidity_high", "temperature_high", "motion_detected"};
enhancedSystem.addMultiConditionSlot("EmergencyVent", ventConditions, 3, true, emergencyVentilation);
String comfortConditions[] = {"motion_detected", "light_changed", "temperature_changed"};
enhancedSystem.addMultiConditionSlot("ComfortMode", comfortConditions, 3, false, comfortMode);
// Connect to base system to intercept all signals
eventSystem.connect("wildcard", []() {
// This gets called for every signal - we use it to check multi-conditions
// In real implementation, you'd pass the actual signal name
});
}
// =================================
// SETUP AND MAIN FUNCTIONS
// =================================
void setup() {
Serial.begin(115200);
Serial.println("š§ ========== MULTI-SIGNAL SLOT DEMO ==========");
demonstrateCurrentSystem();
demonstrateEnhancedSystem();
Serial.println("\nā
Setup complete - starting demonstrations...");
}
void loop() {
updateTimeBasedStates();
// Simulate sensor readings and events
static unsigned long lastDemo = 0;
if (millis() - lastDemo > 8000) {
Serial.println("\nš” === SENSOR SIMULATION CYCLE ===");
// Simulate various sensor events
eventSystem.emit("temperature_low");
delay(1000);
enhancedSystem.checkMultiConditions("temperature_low");
delay(1000);
eventSystem.emit("motion_detected");
enhancedSystem.checkMultiConditions("motion_detected");
delay(1000);
if (systemState.nightTime) {
eventSystem.emit("night_time");
enhancedSystem.checkMultiConditions("night_time");
}
lastDemo = millis();
}
delay(100);
}
// =================================
// WHEN MULTI-SIGNAL SLOTS ARE WORTH IT
// =================================
/*
ā
WORTH USING WHEN:
1. SAFETY-CRITICAL SYSTEMS:
- Gas leak + No motion detected + Ventilation failure
- Fire detected + High temp + Smoke detected
- Security breach + Night time + No authorized access
2. ENERGY EFFICIENCY:
- Heating: Temp low + Motion detected + Time period
- Cooling: Temp high + Occupancy + Daylight hours
- Lighting: Motion + Low light + Time of day
3. COMPLEX AUTOMATION:
- Smart irrigation: Soil dry + No rain forecast + Plant type
- HVAC optimization: Weather + Occupancy + Energy rates + Time
- Security modes: Location + Time + Access patterns + Threat level
4. USER COMFORT:
- Morning routine: Time + Motion + Weather + Calendar events
- Sleep mode: Time + No motion + Lights off + Temperature set
ā NOT WORTH THE COMPLEXITY WHEN:
1. Simple on/off control
2. Independent systems that don't need coordination
3. Real-time critical responses (too much logic adds delay)
4. Systems where false positives are worse than false negatives
š” BEST PRACTICE:
Start with simple single-signal slots, then add multi-condition logic
only where the behavior genuinely needs multiple inputs to make
intelligent decisions.
*/