#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // Pour utiliser la fonction sleep()
#define MAX_SPOTS 10
#define SURFACE 30.0
#define FLUX_MAX 24500.0
// Déclaration de la fonction menu avant utilisation
void menu();
// Structure pour un spot
typedef struct {
int id;
char dali_address[9]; // Adresse DALI en binaire
char level[10]; // Niveau d’éclairage
char data_byte[9]; // Octet de donnée en binaire
char stop_bits[3]; // Bits de stop en binaire
int is_on; // 1 = Allumé, 0 = Éteint
float flux_luminous; // Flux lumineux (lm)
float illuminance; // Éclairement (lux)
} Spot;
Spot spots[MAX_SPOTS];
int spot_count = 0;
int start_bit = 1; // Le bit de start de DALI (1 = normal, 0 = courant coupé)
// Convertit un entier en binaire
void int_to_binary(int num, char *binary, int bits) {
for (int i = bits - 1; i >= 0; i--) {
binary[i] = (num & 1) ? '1' : '0';
num >>= 1;
}
binary[bits] = '\0';
}
// Génère une adresse DALI (8 bits)
void generate_dali_address(char *address, int id) {
int_to_binary(id, address, 8);
}
// Calculer le flux lumineux et l'éclairement en lux
void calculate_flux_and_illuminance(Spot *spot, const char *level) {
float FL = 0.0;
if (strcmp(level, "faible") == 0) {
FL = 0.10 * FLUX_MAX; // 10% de FLmax
} else if (strcmp(level, "moyen") == 0) {
FL = 0.50 * FLUX_MAX; // 50% de FLmax
} else {
FL = FLUX_MAX; // 100% de FLmax
}
// Calcul de l'éclairement E = FL / S
spot->illuminance = FL / SURFACE;
spot->flux_luminous = FL;
// Calcul du REGc = 100 * FL / FLmax
int data_value = (int)(100 * FL / FLUX_MAX);
int_to_binary(data_value, spot->data_byte, 8);
strcpy(spot->stop_bits, "11"); // Allumé (11)
spot->is_on = 1;
strcpy(spot->level, level);
}
// Ajoute un spot
void add_spot() {
if (spot_count < MAX_SPOTS) {
Spot new_spot;
new_spot.id = spot_count + 1;
generate_dali_address(new_spot.dali_address, new_spot.id);
calculate_flux_and_illuminance(&new_spot, "moyen");
spots[spot_count] = new_spot;
spot_count++;
printf("🔹 Spot %d ajouté !\n", new_spot.id);
} else {
printf("⚠️ Capacité maximale atteinte.\n");
}
}
// Change la puissance d'un spot
void change_light_level() {
int id;
char level[10];
printf("\nChoisissez le spot à modifier (ID) : ");
scanf("%d", &id);
if (id < 1 || id > spot_count) {
printf("⚠️ Spot invalide !\n");
return;
}
printf("\nEntrez la puissance (faible, moyen, fort) : ");
scanf("%s", level);
calculate_flux_and_illuminance(&spots[id - 1], level);
printf("💡 Spot %d réglé à %s.\n", id, level);
}
// Éteindre un spot ou tous les spots avec différents délais
void turn_off_spots(int id) {
int choice;
printf("\nChoisissez la méthode pour éteindre le spot %d :\n", id);
printf("1️⃣ Éteindre immédiatement\n");
printf("2️⃣ Éteindre dans 5 secondes\n");
printf("3️⃣ Éteindre dans 10 secondes\n");
printf("📝 Votre choix : ");
scanf("%d", &choice);
if (id == 0) {
printf("🛑 Extinction de tous les spots...\n");
for (int i = 0; i < spot_count; i++) {
if (choice == 1) {
strcpy(spots[i].stop_bits, "00");
} else if (choice == 2) {
strcpy(spots[i].stop_bits, "01");
} else if (choice == 3) {
strcpy(spots[i].stop_bits, "10");
}
spots[i].is_on = 0;
}
printf("💡 Spot(s) éteint(s).\n");
} else {
printf("🛑 Extinction du Spot %d...\n", id);
if (choice == 1) {
strcpy(spots[id - 1].stop_bits, "00");
} else if (choice == 2) {
strcpy(spots[id - 1].stop_bits, "01");
} else if (choice == 3) {
strcpy(spots[id - 1].stop_bits, "10");
}
spots[id - 1].is_on = 0;
printf("💡 Spot %d éteint.\n", id);
}
if (choice == 2) {
sleep(5);
} else if (choice == 3) {
sleep(10);
}
}
// Rallumer un spot ou tous les spots
void turn_on_spots(int id) {
if (id == 0) {
printf("💡 Rallumage de tous les spots...\n");
for (int i = 0; i < spot_count; i++) {
strcpy(spots[i].stop_bits, "11");
spots[i].is_on = 1;
}
} else {
printf("💡 Rallumage du Spot %d...\n", id);
strcpy(spots[id - 1].stop_bits, "11");
spots[id - 1].is_on = 1;
}
}
// Arrêt forcé
void forced_shutdown() {
printf("\n🛑 Arrêt forcé activé !\n");
start_bit = 0;
for (int i = 0; i < spot_count; i++) {
spots[i].is_on = 0;
strcpy(spots[i].stop_bits, "00");
}
printf("💡 Tous les spots sont éteints, plus de courant disponible.\n");
}
// Remettre le courant
void restore_power() {
printf("\n🔋 Remise du courant activée.\n");
start_bit = 1;
printf("💡 Tous les spots sont allumés à nouveau.\n");
// Retour au menu principal après remise du courant
menu();
}
// Liste les spots (ID ajouté au début)
void list_spots() {
if (spot_count == 0) {
printf("⚠️ Aucun spot disponible.\n");
} else {
printf("\n📜 Liste des spots :\n");
printf("----------------------------------------------------------------------------------------\n");
printf("ID | Départ | Adresse | Niveau | Flux (lm) | Eclairement (lux) | Octet (Données) | Stop\n");
printf("----------------------------------------------------------------------------------------\n");
for (int i = 0; i < spot_count; i++) {
printf("%-2d | %-6d | %-2s | %-6s | %-8.2f | %-17.2f | %-15s | %-4s\n",
spots[i].id, start_bit, spots[i].dali_address, spots[i].level,
spots[i].flux_luminous, spots[i].illuminance,
spots[i].data_byte, spots[i].stop_bits);
}
printf("----------------------------------------------------------------------------------------\n");
}
}
// Retirer un spot
void remove_spot() {
int id;
printf("\nChoisissez l'ID du spot à retirer : ");
scanf("%d", &id);
if (id < 1 || id > spot_count) {
printf("⚠️ Spot invalide !\n");
return;
}
for (int i = id - 1; i < spot_count - 1; i++) {
spots[i] = spots[i + 1];
spots[i].id = i + 1; // Réindexe les spots
}
spot_count--;
printf("🔹 Spot %d retiré !\n", id);
}
// Menu forcé après l'arrêt forcé
void forced_menu() {
int choice;
while (1) {
printf("\n📌 Menu Arrêt forcé :\n");
printf("1️⃣ Liste des spots\n");
printf("2️⃣ Remettre le courant\n");
printf("3️⃣ Quitter\n");
printf("📝 Votre choix : ");
scanf("%d", &choice);
switch (choice) {
case 1: list_spots(); break;
case 2: restore_power(); break; // Remet le courant et revient au menu principal
case 3: return; // Quitte sans erreur
default: printf("⚠️ Choix invalide.\n");
}
}
}
// Menu principal
void menu() {
int choice, spot_id;
while (1) {
printf("\n📌 Menu :\n");
printf("1️⃣ Ajouter un spot\n");
printf("2️⃣ Liste des spots\n");
printf("3️⃣ Modifier la puissance d'un spot\n");
printf("4️⃣ Retirer un spot\n");
printf("5️⃣ Éteindre un spot / tous les spots\n");
printf("6️⃣ Rallumer un spot / tous les spots\n");
printf("7️⃣ Arrêt forcé\n");
printf("8️⃣ Quitter\n");
printf("📝 Votre choix : ");
scanf("%d", &choice);
switch (choice) {
case 1: add_spot(); break;
case 2: list_spots(); break;
case 3: change_light_level(); break;
case 4: remove_spot(); break;
case 5: printf("🎯 Entrez l'ID du spot (0 pour tous) : "); scanf("%d", &spot_id); turn_off_spots(spot_id); break;
case 6: printf("🎯 Entrez l'ID du spot (0 pour tous) : "); scanf("%d", &spot_id); turn_on_spots(spot_id); break;
case 7: forced_shutdown(); forced_menu(); break;
case 8: printf("Au revoir ! 👋\n"); return; // Quitter proprement avec un message
default: printf("⚠️ Choix invalide.\n");
}
}
}
int main() {
menu();
return 0;
}