| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- #include <esp-knx-ip.h>
- // WiFi config here
- const char* ssid = "ssid";
- const char* pass = "pass";
- // Common
- #define LED_PIN 13
- // For Basic and S20
- #define BTN1_PIN 0
- #define CH1_PIN 12
- // For 4CH
- #define BTN2_PIN 9
- #define CH2_PIN 5
- #define BTN3_PIN 10
- #define CH3_PIN 4
- #define BTN4_PIN 14
- #define CH4_PIN 15
- typedef enum __type_option
- {
- SONOFF_TYPE_NONE = 0,
- SONOFF_TYPE_BASIC = 1,
- SONOFF_TYPE_S20 = 2,
- SONOFF_TYPE_4CH = 3,
- SONOFF_TYPE_4CH_PRO = 4,
- } type_option_t;
- option_entry_t type_options[] = {
- {"Sonoff Basic", SONOFF_TYPE_BASIC},
- {"Sonoff S20", SONOFF_TYPE_S20},
- {"Sonoff 4CH", SONOFF_TYPE_4CH},
- {"Sonoff 4CH Pro", SONOFF_TYPE_4CH_PRO},
- {nullptr, 0}
- };
- config_id_t hostname_id;
- config_id_t type_id;
- typedef struct __sonoff_channel
- {
- int pin;
- int btn_pin;
- config_id_t status_ga_id;
- bool state;
- bool last_btn_state;
- } sonoff_channel_t;
- sonoff_channel_t channels[] = {
- {CH1_PIN, BTN1_PIN, 0, false, false},
- {CH2_PIN, BTN2_PIN, 0, false, false},
- {CH3_PIN, BTN3_PIN, 0, false, false},
- {CH4_PIN, BTN4_PIN, 0, false, false},
- };
- void setup()
- {
- pinMode(LED_PIN, OUTPUT);
- pinMode(BTN1_PIN, INPUT_PULLUP);
- pinMode(BTN2_PIN, INPUT_PULLUP);
- pinMode(BTN3_PIN, INPUT_PULLUP);
- pinMode(BTN4_PIN, INPUT_PULLUP);
- pinMode(CH1_PIN, OUTPUT);
- pinMode(CH2_PIN, OUTPUT);
- pinMode(CH3_PIN, OUTPUT);
- pinMode(CH4_PIN, OUTPUT);
- Serial.begin(115200);
- // Register the config options
- hostname_id = knx.config_register_string("Hostname", 20, String("sonoff"));
- type_id = knx.config_register_options("Type", type_options, SONOFF_TYPE_BASIC);
-
- channels[0].status_ga_id = knx.config_register_ga("Channel 1 Status GA");
- channels[1].status_ga_id = knx.config_register_ga("Channel 2 Status GA", is_4ch_or_4ch_pro);
- channels[2].status_ga_id = knx.config_register_ga("Channel 3 Status GA", is_4ch_or_4ch_pro);
- channels[3].status_ga_id = knx.config_register_ga("Channel 4 Status GA", is_4ch_or_4ch_pro);
- knx.callback_register("Channel 1", channel_cb, &channels[0]);
- knx.callback_register("Channel 2", channel_cb, &channels[1], is_4ch_or_4ch_pro);
- knx.callback_register("Channel 3", channel_cb, &channels[2], is_4ch_or_4ch_pro);
- knx.callback_register("Channel 4", channel_cb, &channels[3], is_4ch_or_4ch_pro);
- knx.feedback_register_bool("Channel 1 is on", &(channels[0].state));
- knx.feedback_register_action("Toogle channel 1", toggle_chan, &channels[0]);
- knx.feedback_register_bool("Channel 2 is on", &(channels[1].state), is_4ch_or_4ch_pro);
- knx.feedback_register_action("Toogle channel 2", toggle_chan, &channels[1], is_4ch_or_4ch_pro);
- knx.feedback_register_bool("Channel 3 is on", &(channels[2].state), is_4ch_or_4ch_pro);
- knx.feedback_register_action("Toogle channel 3", toggle_chan, &channels[2], is_4ch_or_4ch_pro);
- knx.feedback_register_bool("Channel 4 is on", &(channels[3].state), is_4ch_or_4ch_pro);
- knx.feedback_register_action("Toogle channel 4", toggle_chan, &channels[3], is_4ch_or_4ch_pro);
- knx.load();
- // Init WiFi
- WiFi.hostname(knx.config_get_string(hostname_id));
- WiFi.begin(ssid, pass);
- Serial.println("");
- Serial.print("[Connecting]");
- Serial.print(ssid);
- digitalWrite(LED_PIN, LOW);
- while (WiFi.status() != WL_CONNECTED) {
- digitalWrite(LED_PIN, HIGH);
- delay(500);
- Serial.print(".");
- digitalWrite(LED_PIN, LOW);
- }
- digitalWrite(LED_PIN, HIGH);
- // Start knx
- knx.start();
- Serial.println();
- Serial.println("Connected to wifi");
- Serial.println(WiFi.localIP());
- }
- void loop()
- {
- knx.loop();
- // Check local buttons
- check_button(&channels[0]);
- if (is_4ch_or_4ch_pro())
- {
- check_button(&channels[1]);
- check_button(&channels[2]);
- check_button(&channels[3]);
- }
- delay(50);
- }
- bool is_basic_or_s20()
- {
- uint8_t type = knx.config_get_options(type_id);
- return type == SONOFF_TYPE_BASIC || type == SONOFF_TYPE_S20;
- }
- bool is_4ch_or_4ch_pro()
- {
- uint8_t type = knx.config_get_options(type_id);
- return type == SONOFF_TYPE_4CH ||type == SONOFF_TYPE_4CH_PRO;
- }
- void check_button(sonoff_channel_t *chan)
- {
- bool state_now = digitalRead(chan->btn_pin) == HIGH ? true : false;
- if (state_now != chan->last_btn_state && state_now == LOW)
- {
- chan->state = !chan->state;
- digitalWrite(chan->pin, chan->state ? HIGH : LOW);
- knx.write_1bit(knx.config_get_ga(chan->status_ga_id), chan->state);
- }
- chan->last_btn_state = state_now;
- }
- void toggle_chan(void *arg)
- {
- sonoff_channel_t *chan = (sonoff_channel_t *)arg;
- chan->state = !chan->state;
- digitalWrite(chan->pin, chan->state ? HIGH : LOW);
- knx.write_1bit(knx.config_get_ga(chan->status_ga_id), chan->state);
- }
- void channel_cb(message_t const &msg, void *arg)
- {
- sonoff_channel_t *chan = (sonoff_channel_t *)arg;
- switch (msg.ct)
- {
- case KNX_CT_WRITE:
- chan->state = msg.data[0];
- Serial.println(chan->state ? "Toggle on" : "Toggle off");
- digitalWrite(chan->pin, chan->state ? HIGH : LOW);
- knx.write_1bit(knx.config_get_ga(chan->status_ga_id), chan->state);
- break;
- case KNX_CT_READ:
- knx.answer_1bit(msg.received_on, chan->state);
- }
- }
|