Sonntag, 10. März 2019

Xiaomi Yeelight Lightstrip API für Dritt-Apps öffnen

Unsere Wohnung zählt insgesamt sechs Xiaomi Yeelight Lightstrips, die ich mir über AliExpress für je umgerechnet 25 CHF/Stück bestellt habe. Verglichen mit den „westlichen“ Angeboten wie bspw. dem Philips Hue Lightstrips+ Basispaket für 75 CHF ein Schnäppchen.

Natürlich gibt es zwei Nachteile: Die Dinger können nicht nativ in Apple Homekit integriert und damit gesteuert werden. Und man benötigt Adapterstecker, um die Netzteile mit chinesischen/amerikanischen Steckern in Schweizer Steckdosen zu betreiben. Tolerierbar (die Adapterstecker kriegt man ebenfalls für 50 Rappen/Stück auf AliExpress).

Kombiniert mit den Mi Jia Bewegungssensoren erhellen die LED-Streifen bei Bewegungen den Eingangsbereich (hinter der IKEA ELVARLI-Garderobe angebracht, damit die Wand schön angestrahlt wird), das Schlafzimmer, das Büro, das Badzimmer sowie das Reduit. Ein YeeLight ist hinter dem freistehenden, zweiten Kühlschrank in der Stube angebracht und wechselt seine Farben, wenn die Kühlschrank-Temperatur zu hoch ist (d.h. wenn jemand die Kühlschranktüre nicht sauber geschlossen hat). Das misst ein Mi Jia Temperatursensor im Kühlschrank.

Damit man die Streifen nicht nur über die Mi Jia respektive die Yeelight Smartphone-Apps steuern kann, sondern über eine API, muss man die LAN-Steuerung für jeden Lightstrip einzeln aktivieren:

  1. Yeelight App starten
  2. Gewünschten Lightstrip antippen
  3. Unten rechts den Eject-Button klicken
  4. Unten rechts LAN Control auswählen
  5. Den Schieberegler aktivieren
  6. Fertig

Quelle: Helping Yeti find your Yeelight: how to enable LAN control of your Yeelight devices

Ab sofort kann man die Lightstrips mit Drittsoftware steuern, oder sich mit Python-Modulen wie der YeeLight library etwas zusammenscripten.

Aktivierung in Bildern

image-8299

image-8300

image-8301

image-8302

Tags: , , , , , , ,
Labels: Home Automation

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 10. März 2019

pip: pycurl: Could not run curl-config: [Errno 2] No such file or directory

Damit pip das Paket pycurl installieren kann, müssen auf dem Debian-System folgende Pakete installiert sein:

# apt-get install libcurl4-openssl-dev libssl-dev

Quelle: “Could not run curl-config: [Errno 2] No such file or directory” when installing pycurl

Sonst liest man folgende Fehlermeldungen:

...
Collecting pycurl
Downloading https://files.pythonhosted.org/packages/e8/e4/0dbb8735407189f00b33d84122b9be52c790c7c3b25286826f4e1bdb7bde/pycurl-7.43.0.2.tar.gz (214kB)
100% |████████████████████████████████| 215kB 15.2MB/s 
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/tmp/pip-install-dv_5N3/pycurl/setup.py", line 913, in <module>
    ext = get_extension(sys.argv, split_extension_source=split_extension_source)
  File "/tmp/pip-install-dv_5N3/pycurl/setup.py", line 582, in get_extension
    ext_config = ExtensionConfiguration(argv)
  File "/tmp/pip-install-dv_5N3/pycurl/setup.py", line 99, in __init__
    self.configure()
  File "/tmp/pip-install-dv_5N3/pycurl/setup.py", line 227, in configure_unix
    raise ConfigurationError(msg)
__main__.ConfigurationError: Could not run curl-config: [Errno 2] No such file or directory

Tags: , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 10. März 2019

pip: pygobject: Failed building wheel for pygobject

Damit pip das Paket pygobject installieren kann, müssen auf dem Debian-System folgende Pakete installiert sein:

# apt-get install libglib2.0-dev libgirepository1.0-dev

Sonst liest man folgende Fehlermeldungen:

...
running build_ext
Package glib-2.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `glib-2.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'glib-2.0' found
Command '('pkg-config', '--print-errors', '--exists', 'glib-2.0 >= 2.38.0')' returned non-zero exit status 1

Try installing it with: 'sudo apt install libglib2.0-dev'

----------------------------------------
Failed building wheel for pygobject
Running setup.py clean for pygobject

Tags: , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 10. März 2019

Alle mit pip installierten Pakete aktualisieren

Leider gibt es beim Python-Paketmanager pip („Pip installs Packages“) keine Routine à la apt-get update && apt-get upgrade, um alle installierten Pakete zu aktualisieren.

Mit folgendem Befehl kommt man aber verdammt nah an diese Funktionalität dran:

# pip install -U $(pip freeze | awk '{split($0, a, "=="); print a[1]}')

Quelle: update all installed python packages with pip

Das habe ich gestern auf einem System gemacht, musste aber leider feststellen, dass pip selbst auf einem relative „einfachen“ System bei bestimmten Paketen ins Straucheln gerät. Es ist also viel Zeit und Handarbeit nötig, um sicher zu sein, dass alle Pakete aktualisiert wurden.

Tags: ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 10. März 2019

nmap die offenen Ports einer bestimmten IP anzeigen lassen

Alle Schaltjahre einmal kommt es vor, dass ich eine neue Blackbox in eines meiner Netzwerke hänge und wissen will, was die Hersteller alles für Netzwerk-Services auf dem Gerät betreiben und gegen das LAN freigeschaltet haben.

Solche Services kann man notabene auch gut verwenden, um eine bessere Überwachung mit monit einzurichten (statt einem simplen Ping prüft man beispielsweise, ob der HTTP-Server auch tatsächlich auf HTTP-Requests antwortet).

Am Besten verwendet man dazu nmap, mit folgendem Befehl, um zumal die privilegierte Port-Range abzugrasen:

# nmap -v -sV -O -sS -T5 10.1.2.3
Starting Nmap 7.40 ( https://nmap.org ) at 2019-03-10 12:07 CET
NSE: Loaded 40 scripts for scanning.
Initiating ARP Ping Scan at 12:07
Scanning 10.1.2.3 [1 port]
Completed ARP Ping Scan at 12:07, 0.22s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 12:07
Completed Parallel DNS resolution of 1 host. at 12:07, 0.02s elapsed
Initiating SYN Stealth Scan at 12:07
Scanning 10.1.2.3 [1000 ports]
Discovered open port 53/tcp on 10.1.2.3
Discovered open port 111/tcp on 10.1.2.3
Discovered open port 22/tcp on 10.1.2.3
Discovered open port 80/tcp on 10.1.2.3
Completed SYN Stealth Scan at 12:07, 2.48s elapsed (1000 total ports)
Initiating Service scan at 12:07
Scanning 4 services on 10.1.2.3
Completed Service scan at 12:07, 14.22s elapsed (4 services on 1 host)
Initiating OS detection (try #1) against 10.1.2.3
NSE: Script scanning 10.1.2.3.
Initiating NSE at 12:07
Completed NSE at 12:07, 2.09s elapsed
Initiating NSE at 12:07
Completed NSE at 12:07, 0.01s elapsed
Nmap scan report for 10.1.2.3
Host is up (0.0043s latency).
Not shown: 996 closed ports
PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 6.7p1 Debian 5+deb8u3 (protocol 2.0)
53/tcp  open  domain
80/tcp  open  ssl/http 0.4
111/tcp open  rpcbind  2-4 (RPC #100000)
MAC Address: 00:00:00:00:00:00 (PC Engines GmbH)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.6
Uptime guess: 3.768 days (since Wed Mar  6 17:41:57 2019)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=255 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 22.34 seconds
           Raw packets sent: 1149 (53.132KB) | Rcvd: 1141 (48.056KB)

Quelle: Nmap Cheat Sheet

Wer Zeit und Geduld hat, lässt gleich alle 65’000+ Ports scannen:

# nmap -v -p 1-65535 -sV -O -sS -T5 10.1.2.3

Tags: , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Montag, 11. Februar 2019

Apple, die AirPods 2, bitte. Jetzt!

Am 13. Dezember 2016 war es soweit: Dank eines selbstgestrickten Pingdom-Alarms, der um 15:08 Uhr — 8 Minuten nach Verkaufsstart — losging, gehörte ich vermutlich zu den ersten Schweizern, welche Apples kabellose Kopfhörer über deren Online-Shop bestellten. Am 20. Dezember 2016 trafen die Kopfhörer bei mir zu Hause ein — und ohne diese gehe ich seither selten bis nie aus dem Haus.

Aus meiner Sicht handelt es sich bei den AirPods um das vermutlich beste Produkt, welches Apple in den letzten etwas mehr als zwei Jahren herausgebracht hat. Geschlagen werden die Kopfhörer nur von Face ID (mit kleinen Schwächen). Anfänglich von vielen belächelt, sind die weissen Kopfhörer mittlerweile angeblich ein Statussymbol. Während ich im Dezember 2016 als Träger der Kopfhörer klar zu den Exoten im täglichen Pendlerverkehr gehörte, sind die „Stöpsel“ heute allgegenwärtig, vor allem im Grossraum Zürich.

Doch nun wäre es an der Zeit, dass Apple langsam mal die von der Gerüchteküche seit längerem vorausgesagten AirPods 2 veröffentlicht. Nicht, weil man die Dinger viel besser machen könnte (wobei — Apple, überrasch‘ mich!), sondern wegen einem viel trivialeren Problem:

Die Batterien meiner AirPods verfügen nur noch über einen Bruchteil der ursprünglichen Kapazität wenn voll geladen. Oder in Pendler-Distanzen ausgedrückt: Von der Abfahrt des 7:10 Uhr-Zugs von Bern nach Zürich, über Zürich HB, S-Bahn-Fahrt nach Zürich Hardbrücke, stirbt der rechte Kopfhörer jeweils irgendwann auf dem Fussmarsch von Zürich Hardbrücke zu meinem Arbeitgeber; oftmals auf der roten Passerelle über die Pfingstweidstrasse (also ca. um 8:25 Uhr). Der linke Kopfhörer schafft es jeweils höchstens noch bis zum Parking West, und dann ist auch dort Ende Feuer. Das ergibt eine Laufzeit von gut einer Stunde — und somit ein Bruchteil dessen, was frisch gekaufte AirPods liefern (gemäss Werbung halten die Dinger bis fünf Stunden).

Ich habe mir schon überlegt, die Batterien der Kopfhörer auszuwechseln. Das kostet gemäss Apples offizieller Seite knapp 55 Franken (oder insgesamt 110 Franken — bei einem Neupreis von 178.50). Doch damit zögere ich, weil gemäss der Gerüchteküche die neue Version vor der Türe steht. Am 21. März 2019 ist ja bekanntermassen der astronomische Frühlingsbeginn …

Tags: ,
Labels: Apple

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 10. Februar 2019

Mit dem Wechsel auf ACS stellt Raiffeisen auch die PDF-Generierung um

Der Kontoauszug für mein Genossenschaftskonto bei der Raiffeisen vom Januar 2019 sieht anders aus als der Auszug vom Dezember 2018. Ich gehe deshalb davon aus, dass nun auch meine Raiffeisen-Bank vom Dinosaurier Dialba weg zum Arizon Core System migriert wurde. Und Francisco sich somit allerspätestens jetzt wohl noch einen Ferrari gepostet hat.

Bei Dokumenten, die bei meinen Banken automatisiert erstellt werden, schaue ich mir mit Apple Preview gelegentlich auch die in das Dokument eingebetteten Meta-Informationen an. Oftmals lernt man so das eine oder andere über die Software, welche im Auftrag der Kernbankenlösung die PDFs generiert.

Dezember 2018 — Dialba

Als PDF-Generator wird „FOP 0.20.5“ eingesetzt und das PDF-Format in Version 1.3 ausgegeben (aktuell wären mittlerweile 1.7 respektive 2.0):

image-8274

Hierbei handelt es sich um eine quelloffene Software namens Apache Formatting Objects Processor, welche XML-Dateien mittels XSL zu PDFs umwandelt.

Januar 2019 — ACS

Als PDF-Generator wird „M/TEXT CS version 6.7.0.476“ über den „OMSAdapter“ eingesetzt und das PDF-Format in Version 1.4 ausgegeben:

image-8275

Der Hersteller des neuen PDF-Generators heisst gemäss Informationen von IBM unter Textmanagement und Dokumenterstellung mit M/TEXT CS 6.8 kühn & weyh Software GmbH aus Freiburg i. Br..

Tags: , , , , , , , , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 7. Februar 2019

How-To: Smalltalk mit Deutschen

Ein Körnchen Wahrheit mag das Video enthalten (und es ist wohl auch auf die Schweiz anwendbar):

Tags: , , , , ,
Labels: Gesellschaft

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 7. Februar 2019

Bald geht’s wieder los: US-Präsidentschaftskandidaten auf allen Kanälen

Wie passend, dass ein Anbieter von Stock Video-Footage die Werbevideos künftiger potentieller Kandidaten bereits jetzt persifliert:

PS: Der Kandidatendschungel der Demokraten ist erwartungsgemäss schon jetzt riesig. Es wird aber nicht lange dauern, bis die meisten mangels liquider Mittel rausgefault sind.

Tags: , , , , , ,
Labels: USA

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 3. Februar 2019

host löst einen lokalen Domain-Namen auf, wget und Python requests3 hingegen nicht

Vor einigen Tagen habe ich meinen Web-Server im lokalen LAN aufgeräumt und viele Services, welche über eine DynDNS-Adresse gegen das Internet zugänglich waren, deaktiviert. Ab sofort können diese Web-Services nur noch mit einer privaten FQDN à la service.server.location.domain.local aus dem LAN angesprochen werden.

Diese Anpassung führte dazu, dass mein Bluetooth-Scanner, welchen ich auf meinem Raspberry Pi betreibe, seine Scan-Resultate nicht mehr an den Web-Server übermitteln konnte. Ein Python-Script führt auf dem RPi alle 5 Minuten einen Bluetooth-Scan durch, übersetzt die Resultate ins JSON-Format und versendet die Daten dann mit requests3 per HTTP an den Web-Server.

Die Fehlermeldung, die das Script ab der Umstellung ausspuckte, lautete folgendermassen:

$ /usr/bin/python /usr/local/bin/bluelog/bluetooth-scan.py --output api
Traceback (most recent call last):
  File "/usr/local/bin/bluelog/bluetooth-scan.py", line 424, in <module>
    response = requests.post(url, json=macs, auth=HTTPDigestAuth('user','password'))
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 110, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 56, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 488, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 609, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 487, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='service.server.location.domain.local', port=80): Max retries exceeded with url: /index.php (Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x75e41b10>: Failed to establish a new connection: [Errno -2] Name or service not known',))

Auf dem RPi eingeloggt funktionierte die Namensauflösung mit dem host-Kommando aber problemlos:

$ host service.server.location.domain.local
service.server.location.domain.local has address 10.1.2.3

Doch als ich die Verbindung zum Web-Server mit wget überprüfen wollte schlug auch das fehl:

$ wget http://service.server.location.domain.local/index.php
--2019-02-02 15:56:22--  http://service.server.location.domain.local/index.php
Resolving service.server.location.domain.local (service.server.location.domain.local)... failed: Name or service not known.
wget: unable to resolve host address "service.server.location.domain.local"

Herumgooglen brachte nicht die gewünschte Lösung. Deshalb griff ich zur nächstbesten Lösung und rief wget mit strace auf. Im Trace dann der entscheidende Hinweis:

$ strace wget http://service.server.location.domain.local/index.php
...
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/avahi-daemon/socket"}, 110) = 0
fcntl64(3, F_GETFL)                     = 0x2 (flags O_RDWR)
fstat64(3, {st_mode=S_IFSOCK|0777, st_size=0, ...}) = 0
write(3, "RESOLVE-HOSTNAME-IPV4 service.serv."..., 55) = 55
read(3, "-15 Timeout reached\n", 4096)  = 20
close(3)                                = 0
...

Was zum Teufel hat der Avahi-Daemon mit /var/run/avahi-daemon/socket im strace zu suchen? Jetzt hatte ich ausreichend Infos, um Google noch einmal zu befragen. Und siehe da:

Is Avahi running or installed? Avahi uses .local domain for its usage and puts its config in /etc/nsswitch.conf. My experience with it, using a .local domain name for my internal use is that it can be a little flaky (for lack of a better technical term), and would show behavior similar to what you are seeing.

Quelle: [SOLVED] resolver weirdness – avahi and .local

Die Lösung war im selben Beitrag gepostet:

/etc/nsswitch.conf

Aus …

...
hosts:      files mdns4_minimal [NOTFOUND=return] dns
...

… wird folgender Eintrag:

...
hosts:          files dns mdns4_minimal
...

Und seither lösen sich auch die .local-Adressen reibungslos auf.

Tags: , , , , , , , , ,
Labels: Uncategorized

Keine Kommentare | neuen Kommentar verfassen