' WC-FREI/BESETZT-Anzeige mit 8*8x8-Modulen MAX7218-Matrix
' ================================================================
' Zeigt nach dem Start einmalig kurz die eigene IP-Adresse  
' Dann wird endlos mittig oder als Lauftext angezeigt ...
' - der deutsche  Text  "WC *FREI*"  bzw "WC BESETZT"
' - der englische Text  "WC VACANT"  bzw "WC occupied"
' - das Tagesdatum DD/MM/YYYY
' - einige  WENIGE lokale  Wetter-Daten von OPENWEATHER.org
' - ein kleiner Werbetext 
' - die laufende Uhrzeit HH:MM:SS 
'
' Der WC-Text wird regelmäßig angezeigt, jedoch SOFORT, wenn sich der Tuerstatus ändert.

' Version 4.0 nun mit einem LDR-Lichtsensor als analoger Sensor 
'  optisch gekoppelt an eine vorhandenen externe frei/besetzt Anzeige-Leuchte 
' Wird ein 1MOhm LDR an Pin 33 von einer externen FREI/BESETZT-LEUCHTE beleuchtet, 
' wird sofort der entsprechende Türstatus zweisprachig angezeigt.

' Die frei/besetzt Erkennung erfolgt durch Auswertung einer Spannung am Analog/Digital-Wandler. 
' Pin 33 wird über einem externen 470K-Widerstand an 3V3 angeschlossen.
' Der LDR liegt zwischen PIN33 und GND.
' Bei unbeleuchtetem LDR ist die Spannung an Pin 33 rund 2.5Volt.   
' Bei beleuchtetem LDR sinkt die Spannung auf unterhalb von rund  1Volt.
' Der Erkennungs-Schwellwert wird mit der Variablen LDR_SCHWELLE (in mV) eingestellt.
' Der Schwellwert muss einmalig für die lokalen Umstände eingestellt werden.

' Anstelle des LDR kann auch ein Schalter angeschlossen werden, der bei BEESETZT geschlossen ist. 

WLOG "START"
' Definition einiger Variablen, die schon beim Start bestimmte Werte haben sollten
VERSION$         = "4.0"           'TextVariable mit der aktuellen Programmversion

LDR_PIN          = 33              'analoger Eingang für einen externen LDR-Sensor 
LDR_SCHWELLE     = 1000  'Schwellwert der LDR-Beleuchtung bei dessen Unterschreitung "WC besetzt" erkannt wird 
TEXT_BESETZT$    = " WC BESETZT!"  'Vorbelegung für Besetzt-Text
TEXT_FREI$       = " WC FREI!"     'Vorbelegung für Frei-Text
TEXT_BESETZT_EN$ = " WC OCCUPIED! "'Vorbelegung für englischen Besetzt-Text
TEXT_FREI_EN$    = " WC VACANT! "  'Vorbelegung für englischen Frei-Text
WERBETEXT$       = "          Willkommen im Caf" + CHR$(130) + " Geschmacksache    :-)     "

'ANZEIGE_ANZAHL   = 10             'Anzahl der 8*8 Module
ANZEIGE_ANZAHL   = 8               'Anzahl der 8*8 Module
ANZEIGE_PIN      = 15              'CS-Pin der Anzeige
ANZEIGE_PIXEL    = ANZEIGE_ANZAHL*8 'Anzahl der horizontalen Pixel der Anzeige
CHAR_PIXEL       = 6               'Anzahl der Pixel für einen einzelnen Charakter
POSITION         = 0               'Variable für die Textposition (von rechts beginnend!)
SEKUNDEN_ZAEHLER = 0               'Variable für Schleifenzähler
TUERSTATUS       = 1               '1 = Schalter offen, O = Schalter geschlossen
TUERSTATUS_ALT   = 3               'Zwischenspeicher für vorherigen Tuerstatus
OFFEN            = 1               'Variable für Statusvergleich bei offenem Schalter
GESCHLOSSEN      = 0               'Variable für Statusvergleich bei geschlossenem Schalter

TEXT_TIMER       = 30              'ms Verzögerung für den timer zum schnellen Lauf des Textes

WLOG "INIT Display ..."
MaxScroll.Setup ANZEIGE_ANZAHL,ANZEIGE_PIN   'Die Anzeige initialisieren
GOSUB ZEIGE_DIE_IP_ADR
GOSUB OPENWEATHER_EINSTELLUNGEN       'APPID etc für Wetterdatenabfrage bei openweather.org
onWgetAsync ERZEUGE_WETTER_INFO       'Wenn OPENWEATHER antwortet, dieses Unterprogramm aufrufen
' Der Timer1 ruft jetzt endlos einmal pro Sekunde die Hauptroutine auf
TIMER1 1000, HAUPT_ROUTINE 'Der Timer1 ruft nun endlos alle 1000ms das Unterprgm auf

WAIT   'Ab jetzt werden nur noch Hintergrundprozesse abgewickelt;
'       hier also der timer1 und der Schalterinterrupt
END
' #######################################################################################
' #######################################################################################
' Hinter dem WAIT und END stehen ab hier nur noch Unterprogramme,
' die mit ihrem Namen aus dem obigen Skript-Code aufgerufen werden,
' und die jeweils mit RETURN enden müssen.

' - - - - - - - - - - - - - - - - -  U N T E R P R O G R A M M E   - - - - - - - - - - - -

'==========================================================================
HAUPT_ROUTINE:
'==========================================================================
'Dieses Unterprgm wird einmal pro Sekunde vom TIMER1 aufgerufen.
'Je nach dem aktuellen Stand des Sekundenzählers innerhalb eines Intervals
'werden wechselnd einige Informationen ermittelt und angezeigt 
'
TUERSTATUS = (ADC(LDR_PIN) > LDR_SCHWELLE)   'TUERSTATUS ist nun O wenn Spannungswert <=2000, sonst 1

'Bei einem Wechsel des Tuerstatus diesen neuen Status sofort  anzeigen
If TUERSTATUS <> TUERSTATUS_ALT then 
  SEKUNDEN_ZAEHLER = 0
  TUERSTATUS_ALT   = TUERSTATUS
  PRINT TIME$,"DER TUERSCHALTER WURDE BETRAETIGT"
ENDIF
SEKUNDEN_ZAEHLER = (SEKUNDEN_ZAEHLER mod 55) + 1  'Zaehler erhöhen und am Sequenzende auf 1 setzen

SELECT CASE SEKUNDEN_ZAEHLER
  CASE 1 to 15                       'Sekunde 1 bis 15
    'NUR BEI JEDEM 5. SCHLEIFENDURCHGANG DAS WETTER HOLEN
    IF SEKUNDEN_ZAEHLER = 1 then
      WETTER_ZAEHLER= (WETTER_ZAEHLER + 1) mod 5
      IF WETTER_ZAEHLER=1 then 
      wgetasync("api.openweathermap.org/data/2.5/weather?q=" + Openweather_TOWN$ + "&lang=" + Openweather_LANG$ + "&units=" + Openweather_UNIT$ + "&appid=" + Openweather_ID$, 80)
      ENDIF
    ENDIF
    IF TEXT_WIRD_NICHT_BEWEGT then  TIMER0 TEXT_TIMER ,BEWEGE_DEN_TEXT  'SCROLLENDEN TEXT ANSCHALTEN
    IF TUERSTATUS = OFFEN       then TEXT$ = TEXT_FREI$    + TEXT_FREI_EN$   'FREI!!
    IF TUERSTATUS = GESCHLOSSEN then TEXT$ = TEXT_BESETZT$ + TEXT_BESETZT_EN$ 'BESETZT!!
    TEXT$ = TEXT$ + TEXT$ + TEXT$
    MAXSCROLL.TEXT TEXT$ 
  CASE 16 to 19     'Sekunde 16 bis 19 DATUM mittig anzeigen
    TIMER0 0   'scrollen abschalten
    TEXT$ = DATE$ 
    TEXT$ = REPLACE$(TEXT$, "/", ".")
    GOSUB ZEIGE_DEN_TEXT_MITTIG      
  CASE 20 to 32                      ' WETTER_TEXT scrollend anzeigen
    TEXT$ = WETTER_TEXT$
    GOSUB ZEIGE_DEN_TEXT_ALS_LAUFSCHRIFT
  CASE 33 to 42                      ' Werbetext scrollend anzeigen
    TEXT$ = WERBETEXT$
    GOSUB ZEIGE_DEN_TEXT_ALS_LAUFSCHRIFT
  CASE ELSE                        'alle anderen Sekunden  LAUFENDE UHRZEIT anzeigen
    TEXT$ = TIME$                  'in TEXT$ steht nun die aktuelle Zeit
    GOSUB ZEIGE_DEN_TEXT_MITTIG    
END SELECT
RETURN

'==========================================================================
ZEIGE_DEN_TEXT:
'==========================================================================
TIMER0 0                    'timer0 für das scrollen deaktivieren
TEXT_WIRD_NICHT_BEWEGT = 1  'Variable zeigt ob der Timer0 zum scrollen schon aktiv ist  
MAXSCROLL.PRINT TEXT$       'hier geht TEXT$ nur in den Puffer
MAXSCROLL.SHOW  POSITION    'Erst jetzt wird der Puffer an der Position angezeigt
WLOG            TEXT$       'Zusätzlich nur zur Rückmeldung in der Entwicklungsoberfläche
RETURN                      'Zurück zur aufrufenden Zeile

'==========================================================================
ZEIGE_DEN_TEXT_MITTIG:
'==========================================================================
TEXT_PIXEL = Len(TEXT$)*CHAR_PIXEL            'Anzahl der horizontalen Pixel für diesen Text
POSITION   = (ANZEIGE_PIXEL/2)+(TEXT_PIXEL/2) 'Berechnen der mittigen Ausgabe-Position
GOSUB      ZEIGE_DEN_TEXT
RETURN

'==========================================================================
ZEIGE_DEN_TEXT_ALS_LAUFSCHRIFT:
'==========================================================================
IF TEXT_WIRD_NICHT_BEWEGT then  
  'Timer0 anschalten, nur dann wenn nicht bereits an 
  TIMER0 TEXT_TIMER,BEWEGE_DEN_TEXT
ENDIF
TEXT_WIRD_NICHT_BEWEGT = 0        
MAXSCROLL.TEXT TEXT$
RETURN

'==========================================================================
BEWEGE_DEN_TEXT:
'==========================================================================
 'Den Text einen Punkt nach links scrollen 
 MAXSCROLL.scroll 
 TEXT_WIRD_NICHT_BEWEGT = 0 
RETURN
  
'==========================================================================
OPENWEATHER_EINSTELLUNGEN:
'==========================================================================
' appid default fuer xxxxxxxxxxxxxxxxxxxx
Openweather_ID$   = "d5fb6a022cdac80367fa8ed862c8ee07"
Openweather_TOWN$ = "Krefeld,DE"
Openweather_TOWN$ = "Berlin,DE"
Openweather_LANG$ = "de"
Openweather_UNIT$ = "metric"
WETTER_TEXT$	    = "NOCH KEINE WETTERDATEN ERHALTEN"
WETTER_ZAEHLER 	  = 0
RETURN

'==========================================================================
ERZEUGE_WETTER_INFO:
'=========================================================================
'Aus der JSON-Rückmeldung von OPENWEATHER einige Infos selektieren
W$	         = WGETRESULT$
WETTER_TEXT$ = "       "
WETTER_TEXT$ = WETTER_TEXT$  + "Heute in "+ replace$(Openweather_TOWN$,",DE"," ")
WETTER_TEXT$ = WETTER_TEXT$  + json$(W$, "weather.temp") + chr$(248) + "C  "
'WETTER_TEXT$ = WETTER_TEXT$  + json$(W$, "weather.pressure")+ "hPa  "
'WETTER_TEXT$ = WETTER_TEXT$  + json$(W$, "weather.humidity") + "% "
WETTER_TEXT$ = WETTER_TEXT$  + json$(W$, "weather.description") + "  "
WETTER_TEXT$ = WETTER_TEXT$  +  "Sonnenuntergang: "+UNIXTIME$(json$(W$, "weather.sunset"))
WETTER_TEXT$ = WETTER_TEXT$  + "                        "
'einige Zeichen fuer das MAX7219-Display konvertieren
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "é", chr$(130))
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "è", chr$(138))
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "à", chr$(133))
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "ö", "oe")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "Ö", "Oe")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "ü", "ue")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "Ü", "Ue")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "ä", "ae")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "Ä", "Ae")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "ß", "ss")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "not found", "???")
print TIME$, WETTER_TEXT$
RETURN

print TIME$,"DER TUERSCHALTER WURDE BETRAETIGT" 
wlog  TIME$,"DER TUERSCHALTER WURDE BETRAETIGT" 

'==========================================================================
ZEIGE_DIE_IP_ADR:
'==========================================================================
' Beim Start kurz die IP-Adresse anzeigen
Text$ = Word$(IP$,1)             'Die eigene IP-Adreese ist das erste Wort in IP$
TEXT_PIXEL= Len(TEXT$)*CHAR_PIXEL 'Anzahl der horizontalen Pixel dieses Textes
POSITION  = TEXT_PIXEL     'damit der rechte Teil der Adresse immer zu sehen ist
GOSUB     ZEIGE_DEN_TEXT
PAUSE     1500
RETURN

'----- last line not empty to avoid problems -----