' 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 für "WC *FREI*"  oder "WC BESETZT"
' - der englische Text für "WC OPEN"    oder "WC in use"
' - das Tagesdatum DD/MM/YYYY
' - einige lokale  Wetter-Daten von OPENWEATHER.org
' - ein Werbetext 
' - die laufende Uhrzeit HH:MM:SS 
'
'   Wird ein externer Türschalter an Pin 33 geöffnet oder geschlossen, 
'    wird sofort der entsprechende Türstatus zweisprachig angezeigt.
'   Der Pin 33 ist mit PULLUP bereits auf 3V3 hochgezogen. 
'   Der geschlossene Schalter zieht den Pin auf GND.
'   Bei  einer längeren Leitungen (>5m) zum Schalter sollte der Pin 33
'   jedoch vorsorglich mit einem zusätzlichen 1k-Widerstand gegen 3V3 gezogen werden.

WLOG "START"
' Definition einiger Variablen, die schon beim Start bestimmte Werte haben sollten
VERSION$         = "3.2"           'TextVariable mit der aktuellen Programmversion
'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
SCHALTER_PIN     = 33              'Variable mit dem Pin an dem ein Schalter gegen GND hängt
TUERSTATUS       = 1               ' 1 = Schalter offen, O = Schalter geschlossen
OFFEN            = 1               'Variable für Statusvergleich bei offenem Schalter
GESCHLOSSEN      = 0               'Variable für Statusvergleich bei geschlossenem Schalter
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
TEXT_TIMER       = 30              'ms Verzögerung für den timer zum Oszillieren des Textes

PIN.MODE SCHALTER_PIN, INPUT, PULLUP 'Einen Pin als Eingang für den Schalter definieren
'                           Zieht den offenen PIN als INPUT-Pin mit einem Widerstand auf 3V3-Pegel
'                           Der geschlossene Schalter zieht den Pin dann auf GND = 0 Volt Pegel

'PIN.MODE SCHALTER_PIN, INPUT, PULLDOWN 'Wenn diese Zeile nicht auskommentiert ist, 
'                             simuliert dies einen bereits geschlossenen Schalter an GND
'                             schaltet also testweise den BESETZT-Text an

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

'Wenn der Schalter an SCHALTER_PIN öffnet oder schließt, wird ein Unterprogramm aufgerufen
INTERRUPT SCHALTER_PIN, SCHALTER_AENDERUNG_ERKANNT   

' 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 
'
SEKUNDEN_ZAEHLER = (SEKUNDEN_ZAEHLER mod 50) + 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
    TUERSTATUS    = PIN(SCHALTER_PIN)     'TUERSTATUS ist nun 0 oder 1, je nach Schalterzustand
    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 28                      ' WETTER_TEXT scrollend anzeigen
    TEXT$ = WETTER_TEXT$
    GOSUB ZEIGE_DEN_TEXT_ALS_LAUFSCHRIFT
  CASE 29 to 40                      ' Werbung scrollend anzeigen
    TEXT$ = "        Willkommen im Caf"+ CHR$(130) + " Geschmacksache    :-)     "
    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 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$  + 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

'==========================================================================
SCHALTER_AENDERUNG_ERKANNT:
'==========================================================================
print TIME$,"DER TUERSCHALTER WURDE BETRAETIGT"
SEKUNDEN_ZAEHLER = 0   ' Erzwingt die unmittelbare Anzeige des TUERSTATUS 
RETURN

'==========================================================================
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 -----