Systemauswahl Solarrollos

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Antworten
FrankH1
Beiträge: 28
Registriert: 22. Sep 2020 17:03

Systemauswahl Solarrollos

Beitrag von FrankH1 »

Das Projekt: 3 nebeneinander liegende Fenster mit normalen handbetriebenen Rollläden auf automatische / solarbetriebene umrüsten, inclusive Einbindung ins SmartHome (Openhab) – Budget deutlich unter 300 € pro Fenster
Ich habe einige Zeit auf der Suche nach bezahlbaren Fertiglösungen verbracht. Der Vorteil wäre natürlich die fertige Lösung (Solarpanel, Ladeelektronik, Akku, Steuerung). Leider sind die meisten Systeme relativ teuer, haben teilweise Akkus die alle paar Jahre teuer zu tauschen sind und haben proprietäre Funksysteme. Also dann doch komplettes Eigendesign des Systems, hat auch den Vorteil dass die Bastelei bei Erfolg Spaß macht. Dieser Beitrag soll einige Hinweise geben – ich habe allerdings nicht die 100% Lösung anzubieten….
Als erstes der Auswahl der Rollladenmotoren. Bei 12 V ist die Auswahl nicht allzu groß. Die wenigen Motoren mit Funk haben proprietäre Protokolle – schlecht für die Integration in OpenHab. Also ein einfacher 12V Motor und alle Elektronik/Steuerung in die Aktoren. Meine Wahl fiel auf 3T. Die Motoren haben 36W – Strombedarf also ~ 3A pro Motor. Um die Belastung des Akkus zu begrenzen soll ein gleichzeitiges Fahren verhindert werden, das geht mit entsprechender Programmierung und Hinweis an die Hausfrau für die seltenen manuellen Betätigungen.
Das Konzept für die Steuerung. Es gibt einige Aktoren, welche per Wifi oder Zigbee ansprechbar sind. Ich wollte kein weiteres System ZWave oder Homematic oder….einbinden. Der Nachteil aller 12V Aktoren ist ein relativ hoher Ruhestrombedarf. Es bewegt sich in der Regel um 20-40mA, das wären dann bei 24h schnell 500-1000 mAh pro Tag nur für die Steuerung – unakzeptabel. Also fiel die Wahl auf etwas ESP8266 basierendes, da sollte mit deep sleep ein besserer Wert erzielbar sein. Ziel war unter 100 mAh pro Tag zu bleiben.
Die Wahl des Akkus. Klein sollte er sein, wenig Alterung, kein Memoryeffekt, wenig Platz, ungefährlich. Meine Wahl fiel auf LiFePo4. 4 Zellen bringen ~ 13 V. Ich wollte die Akkus zuerst außen anbringen, habe mich dann aber für die Fensterbank innen entschieden. Der Grund – auch in immer wärmerer Umgebung sind einige Wochen Dauerfrost nicht auszuschließen – da wird das Laden der Akkus dann eher schwierig. Die Kapazität habe ich mit einigen Reserven gewählt. 2 * Fahren pro Tag a 30sec gibt ~ 50mAH, zusätzlich max 100 mAh für die Steuerung. 1 Woche bis 10 Tage ohne laden sollte das System überstehen. Ich habe mich dann für Akkus mit 3,3 Ah entschieden. Um die Sache kurz zu machen – seit einem knappen Jahr betreibe ich alle 3 Rollos an einem Akkupack – es waren also genug Reserven dabei. Selbstverständlich musste ein Load Balancer/Batteriemanagement-System dabei sein – ohne sollte man LiFePo Akkus nicht in Reihe schalten und betreiben. Die 4 Akkus sind mit dem BMS im Schrumpfschlauch und liegen auf dem Fensterbrett.
Das Solarpanel ist außen auf der Fensterbank leicht geneigt. Das garantiert einen optimalen Einfallswinkel im Winter bei tiefstehender Sonne. Im Sommer kommt sowieso eher zu viel Sonne. Ich hatte ursprünglich ein 10W Panel (18V Nennspannung), allerdings ist das System im November in 2 grauen Wochen an die Grenzen gestoßen, Habe daher schaltbar noch ein 5 W Panel danebengeschraubt – das läuft jetzt perfekt. Die Panels sind per Diode entkoppelt so dass sie sich nicht gegenseitig belasten. Im Winter 15 W und ab Frühjahr 10 W. Gefühlt müssten auch 5 W im Sommer reichen, allerdings will ich jetzt tagsüber verschatten, so dass das Rollo doppelt so oft fährt.
Ich hatte noch einen Solarladeregler beschafft – allerdings nach erster Messung auch hier ein Ruhestrom von 16 mA – unakzeptabel. Also muss das BMS die Arbeit erledigen. Abschalten bei Tiefentladung, Überlast, vollem Akku etc. Macht es auch zuverlässig. Um die Regelung etwas zu vereinfachen habe ich über eine Möglichkeit der Spannungsreduktion bei voller Sonne nachgedacht. Also etwas was bei Schwachlicht keinen Effekt hat, aber bei voller Sonne die Überspannung schluckt. Die Lösung – die gute alte Glühbirne (6V;2,4W) . Bei wenig Strom Widerstand gegen 0, kein Spannungsabfall. Bei hoher Spannung=hoher Ladestrom leuchtet sie vor sich hin und schluckt 3-4V. Das BMS hat den Job allerdings letzten Sommer auch ohne das Birnchen erledigt, aber das sollte die Arbeit erleichtern.
Die Steuerelektronik – Da 2 Fenster unmittelbar nebeneinander sind macht ein D1 mini die Steuerung für beide; jedes Fenster braucht 2 Ausgänge zur Motorsteuerung plus mindestens 1 Eingang zur lokalen Bedienung (D1 mit Tasmota)
Also zusammengefasst zur Hardware:
3 * 12V Motoren; 4 LiFePo4 Akkus mit BMS als Akkupack, 2 Solarpanels (10+5W); 2 D1 Mini mit Tasmota, 1*4-Kanal Relais und 1*2-Kanal Relais, Kleinkram – bewegt sich gesamt unter 450 €
Die Programmierung des D1 Mini mit Tasmota; als Rollershutter konfiguriert, Verbindung zu OpenHab über MQTT
Die Programmierung in OpenHab (Beispielhaft für das Doppel-Fenster)
- Things

Code: Alles auswählen

Thing mqtt:topic:Rollo_SZlm "Rollos Schlafzimmer" { 
		Channels: 
			Type rollershutter : Shutter_Percent_links  [ stateTopic="stat/SZ_mittelinks/SHUTTER1", commandTopic="cmnd/SZ_mittelinks/Shutterposition1" ]
			Type rollershutter : Shutter_Percent_mitte  [ stateTopic="stat/SZ_mittelinks/SHUTTER2", commandTopic="cmnd/SZ_mittelinks/Shutterposition2"]
			Type string : Control_links  			    [ commandTopic="cmnd/SZ_mittelinks/Shutterposition1"] 
			Type string : Control_mitte  			    [ commandTopic="cmnd/SZ_mittelinks/Shutterposition2"] 
			Type string : Statusl 						[ stateTopic="tele/SZ_mittelinks/LWT"] 
			Type string : Sleepl 						[ commandTopic="cmnd/SZ_mittelinks/deepsleeptime"]
			Type string : Sensorl  						[ stateTopic="tele/SZ_mittelinks/SENSOR"]
- Items in Openhab (Beispielhaft für ein Fenster)

Code: Alles auswählen

String Rollos_SZlinksundmitte_online        "Rollos_SZ links und mitte"                                {channel="mqtt:topic:Rollo_SZlm:Statusl" }
String Rollos_SZlinksundmitteSleep          "Rollos_SZ links und mitte Sleep"                          {channel="mqtt:topic:Rollo_SZlm:Sleepl"}
String Solar_SZ_Spannung                    "Solarpanel SZ Spannung"                                   {channel="mqtt:topic:Rollo_SZlm:Sensorl"}
Rollershutter Rollo_SZlinks                 "Rollo Schlafzimmer links"     (gRolloSZ)    
Rollershutter Rollo_SZlinks_Percent         "Rollo Schlafzimmer links"     (gRolloSZPercent)           {channel="mqtt:topic:Rollo_SZlm:Shutter_Percent_links"}
String Rollo_SZlinks_Control                "Rollo SZ links Control"       (gRolloSZControl)           {channel="mqtt:topic:Rollo_SZlm:Control_links"}

Mit den Rules sorge ich dann für unterschiedliche Deepsleeptime (Nachts durchschlafen, Tagsüber stündlich, bzw halbstündlich) und für ein versetztes Fahren der Rollos. Bei Bedarf kann ich das auch komplett posten, hier nur ein Auszug

Code: Alles auswählen

//Festlegung der lokaler Variablen und Startwerte
import java.math.BigDecimal

var SZlinkspos = 0.0
var SZlinkscommandretained = false
var SZlinksposretained = false 
var SZmittepos = 0.0
var SZmittecommandretained = false
var SZmitteposretained = false
var aktuelle_sleeptime_SZ_mittelinks = 60 // startvalue
var deepsleeptime = 3600
var links_arbeitet = false


rule "Standard deepsleep time"
when
    Time cron "0 /10 * * * ? *"      // alle 10 min
then
// Standardwert für die Nacht 6h sonst 1h
if (now.getHourOfDay <=5) {deepsleeptime = 21600} else {deepsleeptime = 3600} 
// Vorhalten der wakeupumstellung ab 7:50 bis 8:10 auf 30 min so dass Mini gegen 8:30 aufwacht (u.U auch um 8 aber da ist noch kein Kommando da)
if ((now.getHourOfDay == 7  && now.getMinuteOfHour >= 50 ) || (now.getHourOfDay == 8  && now.getMinuteOfHour <= 10 ) ) { deepsleeptime = 1800 } 
// Vorhalten der wakeupumstellung ab 21:50 bis 22:09 auf 15 min so dass Mini gegen 22:15 aufwacht (u.U auch um 22 aber da ist noch kein Kommando da)
//if ((now.getHourOfDay == 21 && now.getMinuteOfHour >= 50 ) || (now.getHourOfDay == 22  && now.getMinuteOfHour < 10 ) ) { deepsleeptime = 900 } 
end

// 21:50 Rollo runter Kommando in der Hoffnung dass sie gerade nicht aktiv sind
rule "Rollos runter"
when 
	Time cron "0 50 21 * * ? *"
then 
	if (Rollos_SZlinksundmitte_online.state == "Offline") { Rollo_SZlinks.sendCommand(DOWN) 	Rollo_SZmitte.sendCommand(DOWN) }
    if (Rollos_SZrechts_online.state == "Offline")		{ Rollo_SZrechts.sendCommand(DOWN)}
end


rule "Convert SZ links sensor readings (JSON) to corresponding Number"
when
    Item Solar_SZ_Spannung changed
then
    val Messwert = transform("JSONPATH", "$.ANALOG.A0", Solar_SZ_Spannung.state.toString) 			//Originalwert vom Mini als String !
	var Spannung = 0.0213 * (Float::parseFloat(String::format("%s",Messwert).replace(',','.')))	//Konvertiert in Zahl und skaliert auf V
	//wenn Batteriespannung höher wird die angenommen 
	if (Spannung > Solarbatterie_Spannung.state as Number){	Solarpanel_Spannung.postUpdate (Spannung)} else { Solarpanel_Spannung.postUpdate (Solarbatterie_Spannung.state as Number)}
	Spannung_Solar.postUpdate (Solarpanel_Spannung.state.toString.substring (0,5) + " / " + Solarbatterie_Spannung.state.toString.substring (0,5))
	//Anzeige für das icon
	var Spannung_anz = (Solarbatterie_Spannung.state as Number - 10.0) / 4.4 * 100	//Umwandlung in % Wert für die Spannung 14,4V = voll; 10 = leer)
	if (Spannung_anz  > 100) { Spannung_anz =  new BigDecimal(100)}
	if (Spannung_anz  < 0 ) { Spannung_anz = new BigDecimal(0) }
	Spannung_Solar_Anzeige.postUpdate ( Spannung_anz) 
end	

rule "Rollershutter SZ links GUI oder timer controlled action"  
when
	Item Rollo_SZlinks received command				
then
	if (receivedCommand == STOP) 		{ SZlinkscommandretained = true Rollo_SZlinks_Control.sendCommand("stop")}
	else if (receivedCommand == UP) 	{ SZlinksposretained = true SZlinkspos=100 Rollo_SZlinks_Percent.sendCommand(100)}
	else if (receivedCommand == DOWN) 	{ SZlinksposretained = true SZlinkspos=0 Rollo_SZlinks_Percent.sendCommand(0)}
	else {
		var float pos = (Rollo_SZlinks.state as DecimalType).floatValue
		SZlinksposretained = true
		SZlinkspos = 100-pos   //Positionswert invertieren! - 0 = Oben / 100 = Unten!
        Rollo_SZlinks_Percent.sendCommand(SZlinkspos)}
	// logInfo ("Rules","Daten: "+ SZlinkscommandretained + SZlinksposretained +  SZlinkspos)
end

rule "Rollershutter SZ Update Position"  
when
	Member of gRolloSZPercent changed
then
	val rolloname = triggeringItem.name.toString.left(triggeringItem.name.toString.length-8) //ermittelt den Namen des eigentlichen Rollo-Items
	var float pos = (triggeringItem.state as DecimalType).floatValue
	val rollo = gRolloSZ.members.findFirst[i | i.name == rolloname]
	//logInfo ("Rules","Variable "+rolloname +pos +rollo)
	if (rollo !== null) rollo.postUpdate(100.0-pos)//Positionswert invertieren! - 0 = Oben / 100 = Unten!
end

rule "Rollos SZ links und mitte bewegen"
when 
    Item Rollos_SZlinksundmitte_online changed to "Online"
then 
	if (rechts_arbeitet == true) {
		if (SZlinksposretained == true) { SZlinksposretained = false    createTimer(now.plusSeconds(35),[|Rollo_SZlinks_Percent.sendCommand(SZlinkspos)])}      
		if (SZmitteposretained == true) { SZmitteposretained = false    createTimer(now.plusSeconds(70),[|Rollo_SZmitte_Percent.sendCommand(SZmittepos)])}
	}
	else {
		if (SZlinksposretained == true) { SZlinksposretained = false 	links_arbeitet = true  createTimer(now.plusSeconds(5),[| Rollo_SZlinks_Percent.sendCommand(SZlinkspos)])}      //5 Sekunden Pause nach online damit der Mini sicher da ist
		if (SZmitteposretained == true) { SZmitteposretained = false   links_arbeitet = true  createTimer(now.plusSeconds(35),[| Rollo_SZmitte_Percent.sendCommand(SZmittepos)])}
		createTimer(now.plusSeconds(75), [| links_arbeitet = false ])
	}
	if (aktuelle_sleeptime_SZ_mittelinks != deepsleeptime) 
	{											//Sende deep sleep Kommando nur wenn sich der Wert geändert hat
		aktuelle_sleeptime_SZ_mittelinks = deepsleeptime
		createTimer(now.plusSeconds(110), [| Rollos_SZlinksundmitteSleep.sendCommand (deepsleeptime)]) //send wakeuptime for next period
		//logInfo ("Rules","deepsleep time links geändert auf  "+ deepsleeptime)
	}
end

Das wichtige ist lokale items vorzuhalten (da das physikalische item ja den größten Teil des Tages schläft und die MQTT Befehle nicht "retained" funktionieren. Die D1 bekommen dann wenn sie online gehen die entsprechenden Befehle (teilweise zeitversetzt). Die "Wachzeit" des D1 habe ich auf 2 min festgelegt.
Die Verschattung für den Sommer werde ich sehr einfach implementieren, basierend auf der Temperaturvorhersage.
Das größte Stromspar-Potential liegt sicher in der Auswahl des ESP. Es gibt kleine ESP-01, die wirklich nur microA im Deepsleep verbrauchen. Allerdings ist die Anzahl der GPIOs begrenzt und es wird schwierig mehrere Bausteine zu kontrollieren/synchronisieren – ein gleichzeitiges Wachsein ist eher Zufall. Es gibt sicher ESP im Format des D1 Mini, die deutlich weniger Strom im Deepsleep verbrauchen. Ich habe vom D1 schon den Wandlerschaltkreis für USB entfernt, das hat ein paar mA gebracht, aber eigentlich ist mir das immer noch zu viel. Ich wollte allerdings auch nicht viel Geld ausgeben und experimentieren sondern nur ein funktionierende Rollosteuerung und ein wenig Spaß beim Basteln. Anbei der Strombedarf und die Schaltung.
Kommentare sind willkommen - falls das ganze off-topic ist dann bitte entfernen!
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
OH 4.1.1 + Deconz auf Raspi 4B mit Conbee-II Stick,
Shellys, 8266 basierende Anwendungen (Tasmota),
Zigbee Sensoren und Lampen

Antworten