/*
*** Beleuchtung eines Mehrparteinen-Wohnhauses mit TV Flimmern
*** Räume werden zufällig beleuchtet, es gibt eine Treppenhausbeleuchtung mit dem typischen Leuchtstoffröhren-Einschaltflackern, oder eine Simulation, die dem TV-Flackern ähnelt
***
*** Ansteuerung eines LED-Strang  mit WS2812B mit Attiny85 oder Attiny45
*** CPU Clock mindestens auf 8Mhz stellen!
**/

#include <Adafruit_NeoPixel.h>

// Which pin on the Arduino is connected to the NeoPixels?
const int neoPixelPin = 4;

// Number of Neopixel LEDs in the Ring
#define LED_COUNT 24

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, neoPixelPin, NEO_GRB + NEO_KHZ800);

// see strandTest_240124_colorWipe.ino for argument definitions



// constants won't change. Used here to set a pin number :
const int ledPin3 =  3;      // the number of the LED pin
const int PIN_PIR_SENSOR_INPUT = A0; //the number of the PIR PIN **********************
const int switchPin = 2;

// Variables will change :
int ledState3 = LOW;
int neoPixelState = LOW;             // A variable to track whether the Neopixel is currently showing color (ON) or not showing color (OFF)
int pirState = LOW;     //State of the PIR input to the Attiny
bool pirWasTriggered = false;  // A bool variable (True/False) to track whether the PIR went HIGH and the Attiny registered that the PIR went HIGH
bool switchIsClosed = false;

unsigned long previousMillis3 = 0;        // will store last time LED was updated
unsigned long previousMillis4 = 0;

const long interval3 = 500;
const long interval4 = 10000;            // interval LED4 stays on after a trigger from PIR


void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // Initialisierung des Zufallsgenerators
  randomSeed(analogRead(0));

  // Initialisierung der LED-Kette
  pixels.begin();
  // Alle LEDs abschalten
  for (byte i = 0; i < ANZAHL_RAEUME; i++) {
    pixels.setPixelColor(i, pixels.Color(255, 0, 0));
    Room[i] = LICHT_AUS;
  }
  // LEDs ansteuern
  pixels.show();

  delay(15000);
}

void loop() {
  // LEDs ansteuern
  pixels.show();
  // Fernsehsimulation aufrufen und Treppenhausbeleuchtung prüfen
  tvFlimmern();

  // Prüfen, ob der Zeitintervall um ist
  if (Counter == TIMER_MAX) {
    Counter = 0;
    // Raum auslosen
    byte r = random(ANZAHL_RAEUME);
    // Wenn das Treppenhaus ermittelt wurde, die LLeuchtstoffröhren-Simulation für den Raum aufrufen und den Timer starten
    if (r == TREPPENHAUS) {
      TreppenhausBeleuchtung();
    }
    else {
      // prüfen, ob das Licht im Raum aus ist
      if (Room[r] == LICHT_AUS) {
        // falls ja, einmal würfeln
        byte w = random(6);
        // bei 0-3 geht nur das Licht an
        if (w <= 3) {
          pixels.setPixelColor(r, pixels.Color(ROOM_BRIGHTNESS, ROOM_BRIGHTNESS, ROOM_BRIGHTNESS));   //Leuchstärke der lED Farben festlegen
          Room[r] = LICHT_AN;
        }
        // bei 4-5 geht der Fernseher an
        else {
          Room[r] = TV_AN;
        }
      }
      // ist in dem Raum bereits eine Beleuchtung an, dann diese ausschalten
      else{
        pixels.setPixelColor(r, pixels.Color( 0, 0, 0));
        Room[r] = LICHT_AUS;
      }
    }
  }
  // warten
  delay(PAUSE);
  // Zeitzähler hochzählen
  Counter++;
}

void tvFlimmern() {
  for (byte r = 0; r < ANZAHL_RAEUME; r++) {
    // Dort, wo ein Fernseher laufen soll, für Flimmern sorgen
    if (Room[r] == TV_AN) {
      pixels.setPixelColor(r, pixels.Color(random(TV_BRIGHTNESS), random(TV_BRIGHTNESS), random(TV_BRIGHTNESS)));
    }
    // Timer im Treppenhaus prüfen und ggfs runterzählen
    // wenn die Zeit abgelaufen ist, Licht ausschalten
    if(r == TREPPENHAUS ){
      // wenn die Zeit angelaufen ist, Licht abschalten
     if((Zeit==0)&&(Room[r]==LICHT_AN)){
      pixels.setPixelColor(r, pixels.Color( 0, 0, 0));
      Room[r]=LICHT_AUS;
      }
    // Sonst Timer runterzählen
      else{
        Zeit--;
      }
    }
  }
  // LEDs ansteuern
  pixels.show();    
}

void TreppenhausBeleuchtung() {
  // Einschaltflackern nur, wenn im Treppenhaus kein Licht brennt
  if (Room[TREPPENHAUS] == LICHT_AUS) {
    // dreimal blinken
    for (byte i = 0; i < 3; i++) {
      pixels.setPixelColor(TREPPENHAUS, pixels.Color(ROOM_BRIGHTNESS, ROOM_BRIGHTNESS, ROOM_BRIGHTNESS));
      pixels.show();
      delay(LS_ROEHRE);
      pixels.setPixelColor(TREPPENHAUS, pixels.Color(0, 0, 0));
      pixels.show();
      delay(LS_ROEHRE);
    }
    // Licht einschalten und Timer starten
    pixels.setPixelColor(TREPPENHAUS, pixels.Color(ROOM_BRIGHTNESS, ROOM_BRIGHTNESS, ROOM_BRIGHTNESS));
    Room[TREPPENHAUS] = LICHT_AN;
    Zeit = MSEKUNDEN+random(RAND_TEIL);
  }
  // LEDs ansteuern
  pixels.show();
}


/*
#include <Adafruit_NeoPixel.h>

int number = 30; // number of NeoPixels in string
int spacing = 20; // space between NeoPixels (20 is best)
int mcu = 100; // places mcu at DIN end of NeoPixel string. (number * spacing) is "far" end

#include <Adafruit_NeoPixel.h>
#define PIN            4          // Arduino PWM pin
#define NUMPIXELS     14          // NeoPixel ring size
#define pixDELAY      50          // Delay for pixel persistence
int i = 0;                        // A counter

Adafruit_NeoPixel pix(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  pix.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  pix.clear(); // Set pixel colors to 'off'
}

void loop() {
  collide();
  // redgrnfade();
}

void collide()
{
  // RED pixel follows the counter (at the bottom of this function)
  int RED = i;
  pix.setPixelColor (RED, 255, 000, 000);

  // GREEN pixel starts at 1/4 (.25) position on the ring
  int GRN = int(trunc(NUMPIXELS * .25)) - i;
  if (GRN < 0)
    GRN = NUMPIXELS + GRN;
  pix.setPixelColor (GRN, 000, 255, 000);

  // BLUE pixels starts at 1/2 (.5) position on the ring
  int BLU = int(trunc(NUMPIXELS * .5)) + i;
  if (BLU > NUMPIXELS - 1)
    BLU = BLU - NUMPIXELS;
  pix.setPixelColor (BLU, 000, 000, 255);

  // YELLOW pixel starts at 3/4 (.75) position on the ring
  int YEL = int(trunc(NUMPIXELS * .75)) - i;
  if (YEL < 0)
    YEL = abs(NUMPIXELS + YEL);
  pix.setPixelColor (YEL, 255, 255, 0);

  pix.show();
  delay(pixDELAY);

  // BLACK-out the colored pixels
  pix.setPixelColor (RED, 0, 0, 0);
  pix.setPixelColor (GRN, 0, 0, 0);
  pix.setPixelColor (BLU, 0, 0, 0);
  pix.setPixelColor (YEL, 0, 0, 0);

  pix.show(); // show the black-out

  if (i++ == NUMPIXELS - 1)
    i = 0;

  // remove comments to see the values sent to setPixelColor()
  // char buffer[40];
  // sprintf(buffer, "RED %5d | GRN %5d | BLU %5d | YEL %5d", RED, GRN, BLU, YEL);
  // Serial.println(buffer);
}

void redgrnfade()
{
#define pixPIN         4
#define pixCOUNT      NUMPIXELS
#define pixMIN        32
#define pixMAX       255
#define pixSPRK       32
#define pixDELAY       1

  random(analogRead(0));    // random seed

  for (int i = pixMIN; i < pixMAX; i+=10)
  {
    int j = pixMAX - i;
    pix.fill(pix.Color(i, 0, 0),  0, 4);
    pix.fill(pix.Color(0, j, 0),  4, 4);
    pix.fill(pix.Color(i, 0, 0),  8, 4);
    pix.fill(pix.Color(0, j, 0),  12, 4);
    pix.fill(pix.Color(i, 0, 0),  16, 4);
    pix.fill(pix.Color(0, j, 0),  20, 4);
    pix.fill(pix.Color(i, 0, 0),  24, 4);
    pix.fill(pix.Color(0, j, 0),  28, 4);

    if (random(pixSPRK) < 1)
      pix.setPixelColor(random(NUMPIXELS), pixMAX, pixMAX, pixMAX);

    pix.show();
    delay (pixDELAY);
  }

  for (int i = pixMAX; i > pixMIN; i-=10)
  {
    int j = pixMAX - i;
    pix.fill(pix.Color(i, 0, 0),  0, 4);
    pix.fill(pix.Color(0, j, 0),  4, 4);
    pix.fill(pix.Color(i, 0, 0),  8, 4);
    pix.fill(pix.Color(0, j, 0),  12, 4);
    pix.fill(pix.Color(i, 0, 0),  16, 4);
    pix.fill(pix.Color(0, j, 0),  20, 4);
    pix.fill(pix.Color(i, 0, 0),  24, 4);
    pix.fill(pix.Color(0, j, 0),  28, 4);

    if (random(pixSPRK) < 1)
      pix.setPixelColor(random(NUMPIXELS), pixMAX, pixMAX, pixMAX);

    pix.show();
    delay (pixDELAY);
  }
}
*/
ATTINY8520PU