Nützliches für den VW Caddy

Zum Thema Auto hab ich schon lange nichts mehr geschrieben – seit ich meinen Audi verkauft habe und mit Firmen-PKW unterwegs bin wurde diese Kategorie von mir etwas vernachlässigt.

Nachdem ich die letzten fünfeinhalb Jahre mit einem Skoda Rapid Spaceback unterwegs war (ein grundsolides Fahrzeug, das uns viele tausend Kilometer u.a. in die Toskana oder nach Frankreich begleitet hat) fahre ich nun einen VW Caddy Edition 35 TDI 4Motion.

Hier möchte ich gesammelt über nützliches Zubehör usw. berichten.
Gleich nach Abholung habe ich den Caddy mit einer Kofferraumwanne ausgestattet. So bleibt der Kofferaum schön sauber und kann bei Bedarf einfach gereinigt werden. Auch rutscht etwaiges Ladegut nicht mehr so leicht herum.

Weiters habe ich wieder die bewährten Kopfstützenhaken „Snakey“ eingebaut. Ich hatte die Teile schon in meinen letzten Fahrzeugen und möchte sie nicht mehr missen.

Zu guter Letzt wurde noch das Abbiegelicht freigeschaltet. Das ist leider nicht serienmäßig, lässt sich aber mit VCDS leicht freischalten:

  1. STG 09 (Bordnetz) auswählen
  2. STG Lange Codierung -> Funktion 07
  3. Byte 14
  4. Bit 7 Abbiegelicht/Kurvenlicht über Nebelscheinwerfer (NSW) – aktivieren

Einzug eines 3D-Druckers

Schon lange fasziniert mich die Technik des 3D-Drucks. Ersatzteile oder Prototypen zuhause ausdrucken zu können stelle ich mir ziemlich spannend vor. Deshalb habe ich mich nun entschlossen, mir auch so einen 3D-Drucker zuzulegen.

Nach einiger Recherche ist es ein PRUSA i3 MK3S geworden. Er bietet in Gegensatz zu seinen Mitbewerbern u.a. folgende Vorteile:
– beheiztes Druckbett mit Federstahlauflage
– automatische Gitterbettnivelierung
– großes Druckvolumen von 25 x 21 x 21cm
– Optischer Filament-Sensor und Stromausfall-Erkennung

Der wichtigste Vorteil für mich ist aber die Aufrüstbarkeit: Wenn es eine neue (verbesserte) Version des Drucker gibt wird auch ein Upgrade-Kit für meinen Drucker angeboten.

Nach dem Zusammenbau des Bausatzes war es soweit und ich konnte den ersten Probedruck machen:

Printserver mit Rasperry Pi erstellen

Die meisten neuen Drucker hängen per LAN oder WLAN im Heimnetz und können so von mehreren Computern genutzt werden. Unser Drucker – ein HP Deskjet 2050 – ist jedoch einer von der alten Sorte welche nur per USB verbunden sind. Mit Hilfe eines Raspberry Pi jedoch kann man diesen Umstand leicht ändern:

Als Grundlage dient ein RaspberryPi mit installiertem Raspian. Als erstes aktualisieren wir das Betriebssystem auf den letzten Stand:

sudo apt-get update 
sudo apt-get upgrade 

Als nächstes installieren wir CUPS, die Software welche den Drucker verwaltet:

sudo apt-get install cups

Danach muss der User pi zur Gruppe lpadmin hinzugefügt werden:

sudo usermod -a -G lpadmin pi

Damit CUPS vom Netzwerk überall erreichbar ist führen wir folgendes aus:

sudo cupsctl --remote-any
sudo /etc/init.d/cups restart

Nun sollte CUPS über die IP-Adresse des Raspberrys erreichbar sein:
(Hier natürlich eure IP-Adresse eingeben)

http://192.168.1.105:631

Cups wurde in erster Linie für Apples macOS und Unix-Betriebssysteme entwickelt. Damit auch Windows damit umgehen kann benötigen wir noch Samba:

sudo apt-get install samba

Nach der Installation die Konfigurationsdatei öffnen

sudo nano /etc/samba/smb.conf

und wie folgt ändern:

# CUPS printing.  

[printers]

comment = All Printers browseable = no path = /var/spool/samba printable = yes guest ok = yes read only = yes create mask = 0700 # Windows clients look for this share name as a source of downloadable # printer drivers

[print$]

comment = Printer Drivers path = /var/lib/samba/printers browseable = yes read only = no guest ok = no

Zum Schluss wird Samba noch neu gestartet:

sudo /etc/init.d/samba restart

Die meisten Drucker können nun schon im Interface hinzugefügt werden – nicht aber HP-Drucker. Damit diese erkannt werden muss noch hplip installiert werden – das ist ein freies und quelloffenes Softwarepaket mit Teibern für HP-Drucker:

sudo apt-get install hplip 

Nun kann der Drucker im Interface hinzugefügt werden:

Nun sollte der Drucker im Netzwerk als freigegebener Drucker auftauchen!

Nachtrag:
Damit die Aufträge in der Weboberfläche auch korrekt dargestellt werden (nicht nur als „Unbekannt“ bzw. „Zurückbehalten“) muss die Konfigurationsdatei unter Verwaltung – Konfigurationsdatei bearbeiten wie folgt geändert werden:

JobPrivateValues none

CCU2 als Lan-Gateway nutzen

Ein kleiner Tip für alle, die ihre Homematic-CCU2 durch die CCu3 oder einen RaspberryPi ersetzt haben: Bevor die alte CCu2 im Regal verstaubt kann sie mit wenig Aufwand in ein Lan-Gateway umgewandelt werden.

Auf Github findet sich dazu folgende Anleitung, diese Codes einfach mit SSH ausführen:

# Dateisystem read/write mounten
mount -o remount,rw /

# Dateien herunterladen und Rechte anpassen
mkdir -p /usr/local/addons/
mv /firmware/fwmap /firmware/fwmap.orig
wget --no-check-certificate -q -O /firmware/fwmap https://raw.githubusercontent.com/jp112sdl/CCU2GW/master/fwmap
wget --no-check-certificate -q -O /usr/local/addons/hmlangw https://raw.githubusercontent.com/jp112sdl/CCU2GW/master/hmlangw
wget --no-check-certificate -q -O /etc/init.d/S61hmlangw https://raw.githubusercontent.com/jp112sdl/CCU2GW/master/S61hmlangw
chmod 755 /usr/local/addons/hmlangw
chmod 755 /etc/init.d/S61hmlangw

# Laufende Dienste stoppen
/etc/init.d/S70ReGaHss stop
/etc/init.d/S62HMServer stop
/etc/init.d/S61rfd stop
/etc/init.d/S60multimacd stop

# Funkmodul Firmware auf 1.4.1 updaten
eq3configcmd update-coprocessor -p /dev/mxs_auart_raw.0 -c -u -d /firmware

# Init-Skripte verschieben
export INITDIR=/etc/init.d/
export UNUSED_INITDIR=/etc/init.d_unused/
mkdir -p ${UNUSED_INITDIR}
mv ${INITDIR}S49hs485d ${UNUSED_INITDIR}
mv ${INITDIR}S50lighttpd ${UNUSED_INITDIR}
mv ${INITDIR}S50eq3configd ${UNUSED_INITDIR}
[[ -e ${INITDIR}S55cuxd ]] && mv ${INITDIR}S55cuxd ${UNUSED_INITDIR}
mv ${INITDIR}S58LGWFirmwareUpdate ${UNUSED_INITDIR}
mv ${INITDIR}S59SetLGWKey ${UNUSED_INITDIR}
mv ${INITDIR}S60hs485d ${UNUSED_INITDIR}
mv ${INITDIR}S60multimacd ${UNUSED_INITDIR}
mv ${INITDIR}S61rfd ${UNUSED_INITDIR}
mv ${INITDIR}S62HMServer ${UNUSED_INITDIR}
mv ${INITDIR}S70ReGaHss ${UNUSED_INITDIR}
mv /bin/hss_led /bin/hss_led_unused

mv /usr/local/etc/config/rc.d /usr/local/etc/config/rc.d_unused

mv /opt/mh/startup.sh /opt/mh/startup.sh_unused

# optional:
# Seriennummer-Datei anlegen (nur notwendig wenn eine andere Seriennummer als CCU2GW0001 gewünscht wird)
# XXXXXXXXXX ändern in 10-stellige Seriennummer
echo XXXXXXXXXX > /usr/local/addons/serialnumber.txt

# Neustart durchführen
sync
reboot

Im Anschluss ist die CCU2 als Lan-Gateway mit der Standard-Seriennummer CCU2GW0001 erreichbar.

Zisternen-Füllstand mit Ultraschall & Raspberry messen – Teil 2

Nachdem ich wie in Teil 1 beschrieben den Ultraschallsensor zusammengebaut habe ging es nun an den Einbau in unsere Zisterne – und damit fingen die Probleme an:

Eigentlich sah der Plan vor, den Sensor in der Zisterne zu befestigen und die Datenleitung durch die bestehende Verrohrung in den Technikraum zu legen. Hier wäre bereits ein RaspberryPi im Einsatz, der auch diese Aufgabe mit übernommen hätte. Leider konnte ich das Kabel nicht durch das Leerrohr führen, weil es bereits zu voll war… (Merke: Immer ein Leerrohr mehr als geplant mitlegen. man weiß nie wofür man es mal braucht…)

Zum Glück hatte ich noch einen alten RaspberyPi (Model 1 B) übrig. Wenn das Kabel nicht zum Pi kann, muss eben der Pi zum Sensor. Als erstes habe ich ein neues Gehäuse aus einer Frischhaltedose gebaut, in dem der Sensor und der Pi Platz fanden:

Der Sensor wurde danach in der Zisterne befestigt.

Das nächste Problem war, das der Sensor aufgrund der div. Leitungen im Domschacht gestört wurde. Dieses Problem habe ich mit einem darunter befestigten PVC-Rohr gelöst. Damit kann der Schall nun ungehindert bis zur Wasseroberfläche vordringen.

Der Pi ist nun per Wlan mit meinem Netzwerk verbunden. Als Software nutze ich PiusIt. Neben der grafischen Darstellung & Archivierung bietet sie auch die Möglichkeit, den aktuellen Wasserstand an die Homematic weiterzugeben.

Zisternen-Füllstand mit Ultraschall & Raspberry messen – Teil 1

Wir haben in unserem Garten einen Erdtank eingegraben, der uns 2650L Regenwasser für die Gartenbewässerung zur Verfügung stellt. Bis heuer haben wir darin mit einem HM-Sen-Wa-Od Füllstandssensor von Homematic den Wasserstand gemessen – leider hat dieser plötzlich das Zeitliche gesegnet. Also musste was neues her – und ich habe mich für eine Messung mittels Ultraschall entschieden.

Ultraschall-Sensoren für den Raspberry Pi gibt es bereits um wenige Euro, ich habe diesen bestellt: https://amzn.to/2KQfsz7

Den Sensor habe ich einfach in eine wasserdichte Verteilerdose mit Heißkleber eingeklebt:

Nach dem zusammenlöten der Teile wurde ein erster Test durchgeführt – er funktioniert!

Teil 2 gibt es hier

Gesamte Amazon-Ausgaben anzeigen

Aktuell ist es leider nur bei amazon.com möglich den gesamten Bestellverlauf inklusive Gesamtsumme darzustellen. Findige Programmierer haben aber einen javascript-parser geschrieben der das Ganze auch auf amazon.de ermöglicht. Einfach eine Verknüpfung mit dem folgendem Inhalt erstellen, anschließend auf amazon.de einloggen und draufklicken (Wichtig: Der Link funktioniert nur unter Chrome bzw. Firefox, es müssen Pop-Ups für amazon.de erlaubt werden!):

javascript:void(function(){!function(){function e(t,r){if(null==t)return null;if(t.className==r)return t;for(var n=0;n<t.childNodes.length;n++){var a=e(t.childNodes[n],r);if(a)return a}return null}function t(e,r){if(null==e)return null;if(e.className==r)return[e];for(var n=[],a=0;a<e.childNodes.length;a++)n=n.concat(t(e.childNodes[a],r));return n}function r(r,n,a){var o=r.getElementsByClassName("order-info"),l=r.getElementsByClassName("a-box-group a-spacing-base");if(m[n].pages[a].done=!0,o.length!=l.length)return void console.log("Syntax Error "+n+"/"+a);for(var s=0;s<o.length;s++){var i={price:"0,00",date:"?",link:"",names:[],prices:[],products:0,recip:""},g=e(o[s],"a-column a-span2");if(g){var c=g.getElementsByClassName("a-color-secondary value");c.length>0?i.price=g.getElementsByClassName("a-color-secondary value")[0].innerHTML.replace(/EUR/,"").replace(/Summe/,"").replace(/.*coins/i,"0,00").trim():i.price="0,00"}else console.log("No price found "+n+"/"+a);var d=e(o[s],"a-column a-span6 recipient a-span-last");if(d){var h=d.getElementsByClassName("trigger-text");h.length>0?i.recip=d.getElementsByClassName("trigger-text")[0].innerHTML.trim():i.recip="?"}else console.log("No recipient found "+n+"/"+a);var p=e(o[s],"a-color-secondary value");p?i.date=p.innerHTML.trim():console.log("No date found "+n+"/"+a);var u=o[s].getElementsByTagName("a")[1];u?i.link=u.href:console.log("No link found "+n+"/"+a);var f=t(l[s],"a-fixed-left-grid-col a-col-right");if(f.length>0){for(var v=[],y=[],N=0;N<f.length;N++){var T=f[N].getElementsByTagName("A");T.length>0?v.push(f[N].getElementsByTagName("A")[0].innerHTML.trim()):v.push(f[N].getElementsByTagName("DIV")[0].innerHTML.trim());var E=e(f[N],"a-size-small a-color-price");E&&y.push(E.textContent.trim())}i.names=v,i.prices=y,i.products=v.length}else console.log("No names found "+n+"/"+a);m[n].pages[a].entries.push(i)}}function n(r,n,a){for(var l=r.getElementsByClassName("a-box-group a-spacing-base"),s=0;s<l.length;s++){var i="",g="",c="",d=l[s].getElementsByClassName("order-info");if(1==d.length){var h=d[0].getElementsByClassName("a-col-right");if(1==h.length){var p=h[0].getElementsByClassName("a-color-secondary value");p.length>0?i=p[0].textContent.trim():console.log("No order number found "+n+"/"+a)}else console.log("No order number found "+n+"/"+a);var u=e(l[s],"a-column a-span2");if(u){var m=u.getElementsByClassName("a-color-secondary value");g=m.length>0?u.getElementsByClassName("a-color-secondary value")[0].innerHTML.replace(/EUR/,"").replace(/Summe/,"").replace(/.*coins/i,"0,00").trim():"0,00"}else console.log("No price found "+n+"/"+a);var v=e(l[s],"a-color-secondary value");v?c=v.innerHTML.trim():console.log("No date found "+n+"/"+a)}for(var y=l[s].getElementsByClassName("a-box shipment"),N=0;N<y.length;N++){var T={orderNumber:i,orderPrice:g,orderDate:c,date:"?",names:[],prices:[],price:0,products:0},E=e(y[N],"a-row shipment-top-row"),v=e(E,"a-size-medium a-color-base a-text-bold");v?T.date=v.innerHTML.trim():console.log("No shipment date found "+n+"/"+a);var b=t(y[N],"a-fixed-left-grid-col a-col-right");if(b.length>0){for(var B=[],x=[],I=0,w=0,C=!1,L=0;L<b.length;L++){var M=b[L].getElementsByTagName("A");M.length>0?B.push(b[L].getElementsByTagName("A")[0].innerHTML.trim()):B.push(b[L].getElementsByTagName("DIV")[0].innerHTML.trim());var H=e(b[L].parentElement,"item-view-qty");H?(H=parseInt(H.textContent.trim()),isNaN(H)&&(H=1)):H=1;var k=e(b[L],"a-size-small a-color-price");if(k){var P=k.textContent.trim();x.push(P);var z=P.replace(/EUR/,"").replace(/Summe/,"").replace(/.*coins/i,"0,00").trim().replace(/\./,"").split(","),A=100*parseInt(z[0])+parseInt(z[1]);isNaN(A)?C=!0:I+=A*H}w+=H}T.names=B,T.prices=x,T.products=w,1==y.length?T.price=g:(T.price=o(I/100),C&&(T.price="*"+T.price))}else console.log("No item names in shpiment found "+n+"/"+a);f.push(T)}}}function a(){for(var e="",t=0;t<m.length;t++){e+=m[t].year+":",0==m[t].pages.length&&(e+=" waiting...");for(var r=0;r<m[t].pages.length;r++)e+=" "+(m[t].pages[r].done?"X":".");e+="\n"}document.body.innerHTML="<pre>"+e+"</pre>"}function o(e){for(var t=(e.toFixed(2)+"").split("."),r=t[0],n="",a=0;a<r.length-1;a++)n+=r.charAt(a),(r.length-a)%3==1&&(n+=".");return n+=r.charAt(r.length-1),n+","+t[1]}function l(e){return'<tr><td align="right">'+e.name+'</td><td align="right">'+o(e.cent/100)+'</td><td align="right">'+e.orders+'</td><td align="right">'+e.products+'</td><td align="right">'+o(e.cent/100/e.products)+'</td><td align="right">'+o(e.cent/100/e.month)+"</td></tr>"}function s(e){for(var t='<ul style="margin:0; padding:0 0 0 2em">',r=0;r<e.names.length;r++)t+="<li>"+e.names[r]+" | "+e.prices[r]+"</li>";return t+="</ul>",'<tr><td align="center" valign="top"><a href="'+e.link+'">Link</a></td><td align="right" valign="top">'+e.date+'</td><td align="center" valign="top">'+e.products+'</td><td align="right" valign="top">'+e.price+'</td><td align="left" valign="top">'+e.recip+'</td><td align="left" valign="top">'+t+"</td></tr>"}function i(e){for(var t="",r=0;r<e.names.length;r++)t+=e.names[r]+" | "+e.prices[r]+" # ";return'<tr><td align="center" valign="top">'+e.orderNumber+'</td><td align="right" valign="top">'+e.orderDate+'</td><td align="center" valign="top">'+e.orderPrice+'</td><td align="right" valign="top">'+e.date+'</td><td align="left" valign="top">'+e.products+'</td><td align="left" valign="top">'+e.price+'</td><td align="left" valign="top">'+t+"</td></tr>"}function g(){for(var e=new Date,t=""+(1900+e.getYear()),r=e.getMonth()+1,n=[],a=[],o={name:"Insg.",cent:0,orders:0,products:0,month:0},g=0;g<m.length;g++){for(var c=m[g].year.substr(5),d={name:c,cent:0,orders:0,products:0,month:c==t?r:12},h=0;h<m[g].pages.length;h++)for(var p=0;p<m[g].pages[h].entries.length;p++){var u=m[g].pages[h].entries[p],v=u.price.replace(/\./,"").split(","),y=100*parseInt(v[0])+parseInt(v[1]);d.cent+=y,d.products+=u.products,d.orders++,n.push(u)}o.cent+=d.cent,o.products+=d.products,o.orders+=d.orders,o.month+=d.month,a.push(d)}var N="<h2>Uebersicht</h2>";N+='<table cellspacing="0" cellpadding="4" border="1"><tr><th>Jahr</th><th>Euro</th><th>Bestell.</th><th>Produkte</th><th>Euro/Prod.</th><th>Euro/Monat</th></tr>',N+=l(o);for(var g=0;g<a.length;g++)N+=l(a[g]);N+="</table>",N+="<h2>Einzel-Bestellungen</h2>",N+='<table cellspacing="0" cellpadding="4" border="1"><tr><th>Link</th><th>Datum</th><th>Produkte</th><th>Preis</th><th>Versandadresse</th><th>Produktbeschreibungen</th></tr>';for(var g=0;g<n.length;g++)N+=s(n[g]);N+="</table>",N+="<h2>Lieferungen</h2>",N+='<table cellspacing="0" cellpadding="4" border="1"><tr><th>Bestellnummer</th><th>Bestelldatum</th><th>Bestellsumme</th><th>Lieferdatum</th><th>Anzahl Produkte</th><th>Summe / Abbuchung</th><th>Produkte | Preis</th></tr>';for(var g=0;g<f.length;g++)N+=i(f[g]);N+="</table>",document.body.innerHTML=N}function c(e){e.currentTarget.onlyOnce||(e.currentTarget.onlyOnce=!0,r(e.currentTarget.document,e.currentTarget.yearIndex,e.currentTarget.pageIndex),n(e.currentTarget.document,e.currentTarget.yearIndex,e.currentTarget.pageIndex),e.currentTarget.close())}function d(e){if(!e.currentTarget.onlyOnce){e.currentTarget.onlyOnce=!0;for(var t=e.currentTarget.document,a=t.getElementsByTagName("a"),o=0,l=0;l<a.length;l++)a[l].href.match(/startIndex=(\d+)/)&&(o=Math.max(o,parseInt(RegExp.$1)));for(var s=e.currentTarget.yearIndex,l=0;o>=l;l+=10)m[s].pages.push({done:!1,entries:[]});r(t,s,0),n(t,s,0);for(var i="https://www.amazon.de/gp/css/order-history/gp/css/order-history/ref=oss_pagination?ie=UTF8&orderFilter="+m[s].year+"&search=&startIndex=",g=1,l=10;o>=l;l+=10){var d=window.open(i+l);d.yearIndex=s,d.pageIndex=g,d.addEventListener("load",c,!0),g++}e.currentTarget.close()}}function h(e){if(!e.currentTarget.onlyOnce){e.currentTarget.onlyOnce=!0;for(var t=e.currentTarget.document,r=t.getElementsByClassName("time-period-chooser a-spacing-none")[0],n=t.getElementsByName("orderFilter")[0],a=0;a<n.options.length;a++){var o=/year-(\d\d\d\d)/;o.exec(n.options[a].value)&&m.push({year:n.options[a].value,pages:[]})}for(var l="https://www.amazon.de/gp/css/order-history?",a=0;a<r.elements.length;a++){var s=r.elements[a];s!=n&&(l+=encodeURIComponent(s.name)+"="+encodeURIComponent(s.value)+"&")}l+="orderFilter=";for(var a=0;a<m.length;a++){var i=window.open(l+m[a].year);i.yearIndex=a,i.addEventListener("load",d,!0)}u=setInterval(p,1e3),e.currentTarget.close()}}function p(){a();for(var e=0;e<m.length;e++){if(0==m[e].pages.length)return;for(var t=0;t<m[e].pages.length;t++)if(!m[e].pages[t].done)return}clearInterval(u),g()}var u,m=[],f=[],v=window.open("https://www.amazon.de/gp/css/order-history/ref=ya_orders_css");v.addEventListener("load",h,!0)}();})();

 

 

Homematic-Lamellensteuerung

Vor kurzem bin ich auf eine einfache Lösung gestoßen, um die Lamellen unserer Raffstores per Tastendruck zu steuern.  Bis jetzt hatte ich das Ganze über eine Zeitverzögerung realisiert (Raffstore nach unten fahren – nach 70 Sekunden 0,5% nach oben -> Lamellen sind geöffnet). Das Funktioniert auch bestens, hat aber einen Schönheitsfehler: Startet man den Raffstore nämlich zB. von der Hälfte (weil man ihn vorher manuell halb geöffnet hat) dauert es trotzdem die vollen 70 Sekunden um die Lamellen wieder in den „Standardzustand“ zu versetzen. Die Lösung ist so einfach wie effektiv:

Als erstes wird unter „Direkte Verknüpfungen“ die jeweile „AB“-Verknüpfung des Tasters bearbeitet:

Anschließend unter Profileinstellung auf „Experte“ umstellen. Jetzt noch unter „LONG_DRIVING_MODE“ „DRIVE_VIA_LOWER_END_POSITION“ und unter „LONG_OFF_LEVEL“ die gewünschte Endposition in Prozent (bei mir 0,5) eintippen und fertig!

Bei einem langen Tastendruck nach unten schließt sich der Raffstore nun immer komplett und öffnet sich danach wieder um die eingestellten 0,5 Prozent. Das funktioniert auch wenn der Raffstore schon komplett geschlossen ist!