esphome:
  name: xmas

esp32:
  board: sparkfun_esp32s2_thing_plus_c
  framework:
    type: arduino

external_components:
  # use all components from a local folder
  - source:
      type: local
      path: my_components
      
# Enable logging
logger:

# Enable Home Assistant API
api:
  password: ""
  # make the reboot timeout longer, so it's not constantly rebooting
  # if there's no HA server. It can respond just fine to MQTT messages,
  # after all.
  reboot_timeout: 120min
  
ota:
  password: "..."

wifi:
  ssid: "..."
  password: "..."
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Xmas Fallback Hotspot"
    password: "..."

mqtt:
  broker: ...
  username: ...
  password: ...
  topic_prefix: esphome/xmas
  birth_message:
    topic: esphome/xmas/online
    payload: '{ "value": 1 }'
  will_message:
    topic: esphome/xmas/online
    payload: '{ "value": 0 }'

captive_portal:

output:

  - platform: ac_dimmer
    id: dimmer1
    gate_pin: GPIO26
    zero_cross_pin:
      number: GPIO34
      allow_other_uses: true
      mode:
        input: true
      inverted: yes

  - platform: ac_dimmer
    id: dimmer2
    gate_pin: GPIO25
    zero_cross_pin:
      number: GPIO34
      allow_other_uses: true
      mode:
        input: true
      inverted: yes

  - platform: ac_dimmer
    id: dimmer3
    gate_pin: GPIO18
    zero_cross_pin:
      number: GPIO34
      allow_other_uses: true
      mode:
        input: true
      inverted: yes

  - platform: ac_dimmer
    id: dimmer4
    gate_pin: GPIO23
    zero_cross_pin:
      number: GPIO34
      allow_other_uses: true
      mode:
        input: true
      inverted: yes

light:

  - platform: output_array
    restore_mode: RESTORE_DEFAULT_OFF
    name: array
    default_transition_length: 5s
    output:
      - dimmer1
      - dimmer2
      - dimmer3
      - dimmer4
    effects:
      - addressable_lambda:
          name: "Glow"
          update_interval: 16ms
          lambda: |-
          
            #define N 4
            #define min_time 1500
            #define max_time 2500
            #define min_brightness 0.3f
            #define max_brightness 1.f
            #define rand(x0, x1) ((x0)+((x1)-(x0))*(random(1000000) / 1000000.f))
            #define BRIGHTNESS() ((min_brightness)+((max_brightness)-(min_brightness))*powf(random(1000000) / 1000000.f, 0.5))
            static unsigned long start_time[N], finish_time[N];
            static float start_brightness[N], finish_brightness[N];
            unsigned long t = millis();
            int i;
            assert(it.size() == N);
            if (initial_run) {
                for (i = 0; i < N; ++i) {
                    start_time[i] = t;
                    finish_time[i] = t + (unsigned long)rand(min_time, max_time);
                    start_brightness[i] = BRIGHTNESS();
                    finish_brightness[i] = BRIGHTNESS();
                }
            }
            
            for (i = 0; i < N; ++i) {
                if ((t < start_time[i]) || (t > finish_time[i])) {
                    start_time[i] = t;
                    finish_time[i] = t + (unsigned long)rand(min_time, max_time);
                    start_brightness[i] = finish_brightness[i];
                    finish_brightness[i] = BRIGHTNESS();
                }
                float x = (t - start_time[i])
                    / (float)(finish_time[i] - start_time[i]);
                x = 3*x*x - 2*x*x*x; // smoothstep
                float br = start_brightness[i] + x *
                    (finish_brightness[i] - start_brightness[i]);
                if (br < 0) br = 0;
                if (br > 1) br = 1;
                uint8_t w = (uint8_t)(255*br);
                it[i] = Color(w,w,w,w);
            }
            
