LaCrosse Temperatursensor Time Intervall (Fhem)
Wem die 8 Sekunden zu viel sind und/oder wem die Logs zu groß werden, kann die Zeiten mit
attr event-min-interval temperature:60,battery:3600,state:300,humidity:60
verändern. Zeit entspricht Sekunden. Z.B. wird nun die Battery nur noch jede Stunde ausgegeben.
Jeelink / FHEM / TX- (LaCrosse) - keine Verbindung
Sollte nach wiederholtem Paring das Gerät nicht gefunden werden - hilft: set jeelink reset Dadurch sollten auch deleted Devices wieder hinzugefügt werden können.
TX-35-DTH mit JeeLink und FHEM verbinden
Der JeeLink kann unter The JeeLabs Shop bestellt werden. Die Lieferung dauert ca. 1-2 Wochen. Das anlernen des JeeLink funktioniert unter Linux recht einfach, da die Treiber schon vorhanden sind. Einfach den JeeLink anschließen und mit dmesg | tail -50 schauen ob er angelernt wurde und auf welchem Port. Dann diesen Port
stty 57600 raw -echo </dev/ttyUSB0
cat </dev/ttyUSB0
verbinden und es sollte eine Ausgabe erscheinen. Sollte ein bash: /dev/ttyUSB0: Permission denied kommen, helfen die folgenden beiden Befehle:
sudo adduser yourusername dialout
sudo chmod a+rw /dev/ttyUSB0
Danach sollte die Fehlermeldung nicht mehr auftauchen. Damit man nun den JeeLink mit dem TX-35 verbinden kann, muss dieser geflashed werden - dazu gibt es zwei Möglichkeiten. Zum einen mit der Arduino IDE und den LaCrosse und JeeLink Sketches. Dieser Weg hat bei mir aber leider nicht funktioniert. Alternative kann man sich einfach FHEM installieren. Neben fhem sollte man noch das Package avrdude installieren um den JeeLink flashen zu können: sudo apt-get install avrdude fhem Nach der Installation ruft man http://fhem-host:8083/fhem (fhem durch den eigenen hostname ersetzten) auf. Dort gibt man dann folgendes in die Commando Zeile ein:
define jeeLink JeeLink /dev/ttyUSB1@57600
ttyUSB1 und 57600 gegebenenfalls anpassen - falls bei dmesg andere Werte ausgegeben wurden.
set jeeLink flash LaCrosse
Danach sollte der JeeLink in FHEM vorhanden sein. Mit attr jeeLink initCommands 30t 0a v wird der Toggle Modus aktiviert und die LED deaktiviert (0a v). Das Pairing kann nun mit einer Zeit von 60 Sekunden gestartet werden: set jeeLink LaCrossePairForSec 60 Nach dem herausnehmen und wiedereinlegen der Batterien sollte der TX-35-DTH erkannt werden. Die Werte werden in einer Log Datei unter /opt/fhem/log/NameDesGeraetes-2017.log gespeichert.
Raspberry Pi mit einer Wetterstation ws1080/wh1080 verbinden
Es gibt viele Blogs mit Anleitungen wie man eine Wetterstation vom Typ ws1080/wh1080/ws3000 etc. mit einem Raspberry pi verbindet. Ich habe meinen Anleitung nun als Ansible Playbook unter https://github.com/lightszentip/ansible-playbook-weather1080 veröffentlicht. Somit kann schnell und einfach zwischen dem Raspberry pi 2 und Raspberry pi 3 gewechselt werden und auch eine Neuinstallation ist nicht mehr Aufwendig. Der Vorteil von Ansible ist das man diese Anleitung schnell und einfach an die verschiedenen Wetterstationen anpassen kann. Zudem ist ein Script enthalten um die Daten von der WH1080/Ws1080 in eine mysql Datenbank zu speichern. Damit hat man die Daten in einem einfachen Format und kann diese an anderen Stellen leicht und einfach wieder verwenden. Es muss dafür nicht eine Software mit manueller Eingabe verwendet werden um die Daten aus der Wetterstation auszulesen.
Use password with ansible - security
Mit ansible-vault createsecrethostgroupOne kann man sein Passwort verschlüsseln: createsecrethostgroupOne = Name der Variable für das Passwort um es später im Script oder der config zu nutzen. Wenn man create secrethostgroupOne oder edit secrethostgroupOne aufruft muss man ein vault Passwort festlegen. Danach wird ein Editor geöffnet wo man folgendes eingibt:
ansible_sudo_pass: deinsudiopassword
Dann im Script:
vars_files:
-secrethostgroupOne
angeben. Damit beim ausführen des Playbooks auch das Passwort beachtet wird, muss man eine Datei vault.txt anlegen (gleiche Ebene wie das playbook) und dort das vault Passwort eintragen. Danach kann man dann mit dem Zusatz:
–vault-password-file=vault.txt
das eingeben des sudo Passwortes einfach überspringen .
SSH Key an alle hosts in ansible/hosts kopieren
Wenn man Ansible verwendet, benötigt man den lokalen ssh public key auf allen in der hosts Datei eingetragen Knoten - außer man verwendet das ansible_ssh_pass. Damit man aber nicht für jeden Knoten einzeln ssh-copy-id aufrufen muss, hilft das folgenden Pyhton Script: Die komplette Datei findet ihr unter https://gist.github.com/lightszentip/881593f03a7e3d1b107e3be889547941 Das Script baut auf der Datei von Jiri Tyr hostfile.py auf, welches eine hosts Datei parsed. Der Aufruf sieht wie folgt aus:
python hostfile.py –filename pathtofilehosts –keypath pathtoid_rsa.pub
Falls man es auf eine Gruppe einschränken möchte, kann man auch noch –group Groupname mitgeben (dieser ist aber optional). Als Beispiel:
python hostfile.py –filename /etc/ansible/hosts –keypath ~/.ssh/id_rsa.pub –group database
Wie ihr den ssh key generiert, seht ihr unter adding-your-ssh-key-to-the-ssh-agent und den public key vom private key gibt es mit
ssh-keygen -y -f ~/.ssh/id-database_rsa > ~/.ssh/id-database_rsa.pub
Das ganze könnt ihr dann mit
ansible all -m ping
testen.
Mysql root Passwort zurücksetzen
Solltest du dein Passwort für den User root vergessen haben, kannst du das mit https://dev.mysql.com/doc/refman/5.7/en/resetting-permissions.html zurücksetzen. Sollte das nicht funktionieren - kannst du die folgende Alternative verwenden:
Öffne die Datei mysql.cnf und füge unter [mysqld]
skip-grant-tables
ein
- Starte danach mysql
Logge dich mit
mysql -u root mysql
ein
Dann
FLUSH PRIVILEGES;
und den Passwort Befehl aus resetting-permission eingeben (je nachdem welche Version von mysql man hat)
ALTER USER ‘root‘@’localhost’ IDENTIFIED BY ‘MyNewPass’;
or
SET PASSWORD FOR ‘root‘@’localhost’ = PASSWORD(‘MyNewPass’);und danach
update user set plugin="mysql_native_password"; # THIS LINE FLUSH PRIVILEGES;
sollte das nicht gehen - kann man auch noch
update user set authentication_string=PASSWORD("") where User='root';
versuchen.
- Danach skip-grant-tables wieder aus der mysql.cnf entfernen und mysql neustarten.
Firebase FCM Push Notification Backend
Mit Firebase Cloud Messaging, kurz FCM, kann man Notifications auf IOS und Android versenden. Im folgenden Beitrag geht es um das Versenden der Nachrichten im Backend mit PHP. Um mit PHP Nachrichten an FCM zu schicken kann die Library
“paragraph1/php-fcm”: “^0.7.0”
verwendet werden. Damit man Daten aus der Firebase Database verwenden kann, verwendet man zusätzlich noch die Library:
“kreait/firebase-php”: “^2.0”,
Damit ergibt sich das folgende composer File:
{
“require”: {
“kreait/firebase-php”: “^2.0”,
“paragraph1/php-fcm”: “^0.7.0”
}
}
Um mit Firebase zu arbeiten erstellen wir eine backend.php Datei:
<?php
require ‘vendor/autoload.php’;
use paragraph1\phpFCM\Client;
use paragraph1\phpFCM\Message;
use paragraph1\phpFCM\Recipient\Device;
use paragraph1\phpFCM\Recipient\Topic;
use paragraph1\phpFCM\Notification;
$firebase = Firebase::fromServiceAccount(__DIR__.’/secret/firebaseappname-firebase-adminsdk-uuid.json’);
$apiKey = ‘ffcmApiKey-findetmanunterProjekteinstellungenCloudMessaging’;
$client = new Client();
$client->setApiKey($apiKey);
$client->injectHttpClient(new \GuzzleHttp\Client());
Mit der Variable $firebase kann nun auf die Datenbank zugegriffen werden und mit $client können Nachrichten versendet werden. Die json Datei und den apiKey findet man in der https://console.firebase.google.com/. Dort unter Deine App >> Projekteinstellungen >> Cloud Messaging ist der API Key und unter Deine App >> Projekteinstellungen >> Dienstkonten kann man sich einen privaten Schlüssel generieren lassen. Diesen dann entweder im gleichen Ordner wie die backend.php ablegen oder wie im Beispiel im Ordner secret. Wichtig ist das die Datei keinen entsprechende Zugriffsrechte hat, damit niemand diese über den Webserver auslesen kann. Das folgende Beispiel liest Elemente aus der Tabelle ‘Todos’ aus. Weitere Informationen wie ihr mit firebase-php arbeiten könnt, findet ihr unter: https://github.com/kreait/firebase-php
<?php
require ‘backend.php’;
$todos = $database->getReference(‘todos’)->orderByKey()->getSnapshot()->getValue();
foreach ($todos as $key => $value) {
echo $key.’ - ‘.$value[‘title’].’ (‘.$value[‘description’].’)\n’;
}
Verschicken kann man dann eine solche ‘Aufgabe’ mit:
<?php
$note = new Notification($title, $message’);
$note->setIcon(‘notification_icon_resource_name’)->setSound(“default”)->setBadge(1);
$message = new Message();
$message->addRecipient(new Topic(‘todos’));
$message->setNotification($note)->setPriority(“high”)->setTimeToLive(223200);
$response = $client->send($message);
In dem Beispiel wird die Nachricht nur an die Clients verteilt, welche sich auf das Topic ‘todos’ subscribte haben. Hier kann man aber auch z.B. devices auswählen oder an alle verschicken. Mehr dazu unter: https://github.com/Paragraph1/php-fcm Ob das Senden an FCM erfolgreich war kann man mit
$response->getStatusCode()
prüfen. Dabei sagt das Ergebnis aber nur aus ob die Nachricht an FCM übermittelt wurde, aber nicht ob die Clients diese erfolgreich erhalten haben.
Jenkins Pipeline - War File deployen
Mit dem folgende Script kann man eine war Datei mit Jenkins Pipeline auf einem Tomcat deployen. Für das deployen mit curl auf einem tomcat wird ein User mit der Rolle manager-script benötigt.
node {
def devHost = ‘localhost’
// Mark the code checkout ‘stage’….
stage(‘Checkout’) {
checkout changelog: false, poll: true, scm: [$class: ‘GitSCM’, branches: [[name: ‘/branchname’]], doGenerateSubmoduleConfigurations: false,
extensions: [[$class: ‘CloneOption’, depth: 2, noTags: true, reference: ‘’, shallow: true, timeout: 15]], submoduleCfg: [],
userRemoteConfigs: [[credentialsId: ‘credentialsId’, url: ‘giturl’, name: ‘origin’, refspec: ‘+refs/heads/branchname:refs/remotes/origin/branchname’]]]
}
// Mark the code build ‘stage’….
stage(‘Deploy’) {
sh “mvn clean package”
deploy(“target/.war”, devHost, “/serverpath”)
}
stage(‘Archive’) {
archive ‘target/.war,target/**/\failsafe*/,target//*surefire*/**’
}
}
// Deploy file to tomcat
def deploy(file, host, context) {
sh “curl -v -u username:password -T ${file} ‘http://${host}:8080/manager/text/deploy?path=${context}&update=true’”
}
Checkout: Beim checkout wird nur eine Schatten Kopie mit einer Tiefe von 2 vom Ziel Branch heruntergeladen. Das reduziert die Zeit für den checkout. Bei einem
checkout scm
werden hingegen alle branches und auch die History des aktuellen Branches komplett heruntergeladen. Dies wird an dieser Stelle aber nicht benötigt. Deploy Stage: Nach dem bauen wird mittels curl einfach die war Datei auf dem Tomcat deployed. Was noch fehlt ist eine Prüfung ob das deployen erfolgreich war und das Neustarten des Tomcats falls nicht. Die Prüfung kann man mit curl oder wget machen und das Neustarten mit Hilfe einer ssh Verbindung auf den Tomcat.
Ionic2 (rc3) mit firebase und google+facebook login
Inzwischen ist Ionic 2 in der RC3 Version vorhanden. Aufgrund von Änderungen zwischen RC0, RC2 und RC3 sowie einigen Änderungen bei firebase und angularfire2, sind leider die meisten Beispiele im Internet nicht mit RC3 kompatibel.
Ionic Projekt
Solltet ihr bisher ionic noch nicht installiert haben, könnt ihr das mit dem folgenden Befehl machen: sudo npm install -g ionic cordova Falls ihr noch kein npm und node installiert habt, am besten die aktuelle Version installieren. Danach könnt ihr wie folgt starten: ionic start NamederAnwendung blank –v2 Danach dann noch ios (falls ihr auf mac arbeitet) und android hinzufügen:
ionic platform add ios && ionic platform add android
Nun könnt ihr die app mit dem folgenden Befehl unter android testen. Es empfiehlt sich das Testen immer im Emulator oder auf einem echten Device vorzunehmen, da für das login bei facebook und google cordova Plugins verwendet werden - welche untern “ionic serve” nicht beachtet werden:
ionic run android
Hinweis: Falls in der package.json > “@ionic/app-scripts”: “0.0.45”, steht. Bitte den Hinweis am Ende der Seite beachten - Firebase is not defined.
Firebase
Unter https://console.firebase.google.com/ erstellt ihr euch eine neue Anwendung. Am besten den geichen Namen wie der Name für die App. Danach unter Authentication >> Anmeldemethoden bei Google und Facebook auf editieren klicken und die Anmeldemethoden aktivieren. Für Facebook benötigt ihr die appId und appSecret, da wir aber noch keine Facebook App erstellt haben - dort aktuell nur einen Platzhalter eintragen. Danach unter Einstellungen/Projekteinstellungen gehen (findet man beim klick auf das Zahnrad oben links) und auf “Firebase zu meiner WebApp hinzufügen” klicken. Danach erscheinen die Keys für eure Firebase Einstellungen:
const firebaseConfig = {
apiKey: “Key”,
authDomain: “authdomain.firebaseapp.com”,
databaseURL: “https://autdomain.firebaseio.com",
storageBucket: “storage.foo.com”,
};
Diese werden in eine Temporäre Textdaten kopiert, da sie später benötigt werden. Die messageId Variable wird nicht benötigt - wer Firebase Messaging verwenden möchte, kann das mit Ionic2 Push machen.
Zuerst unter https://developers.facebook.com/apps eine neue App erstellen. Danach dann in der App unter “Produkt hinzufügen” auf “Facebook Login” klicken. Bei “Gültige OAuth Redirect URIs” die Url welche ihr unter von https://console.firebase.google.com/ >> Authentication >> Anmeldemethoden >> Facebook findet eintragen. Danach unter Einstellungen für eure Facebook App gehen und auf “Platfform hinzufügen” klicken. Daher erkläre ich im folgenden wie man mit ionic2 und firebase einen Google Login/SignIn und Facebook Login/SignIn realisieren kann: Bei “Google Play Package-Name” tragt ihr die id aus eurer config.xml im root Ordner eures Ionic Projektes ein.
Den Schlüssel Hash bekommt ihr mit dem folgenden Befehl auf euer Command Line: Linux: keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base6 Win: keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64 Den Schlüssel am besten in die Zwischenablage kopieren bzw. eine Textdatei - da diese bei Google wieder benötigt wird. Danach SingleSignOn aktivieren und speichern. Dann die AppId und den App-Geheimcode unter https://console.firebase.google.com/ >> Authentication >> Anmeldemethoden >> Facebook eintragen und speichern.
Wieder auf https://console.firebase.google.com/ >> Projekteinstellungen gehen und auf “Firebase zu meiner Android App hinzufügen” klicken. Dort dann wie schon bei Facebook den Paketname (id) und den Hash eintragen und speichern. Danach geht ihr auf https://console.developers.google.com/ und wählt dort euer Projekt von Firebase aus (Projektname ist der gleiche) und geht auf “Zugangsdaten”. Dort findet ihr unter “OAuth-2.0-Client-IDs” die ClientID. Solltet ihr mehrere Zertifikate verwenden z.B. wenn ihr die App im Appstore hochladen wollt - werdet ihr dort für jeden Schlüssel eine eigene ClientId finden.
Cordova Plugins installieren
Nun werden die folgenden Plugins benötigt:
ionic plugin add cordova-plugin-facebook4 –save –variable APP_ID=”123456789” –variable APP_NAME=”myApplication”
cordova plugin add https://github.com/EddyVerbruggen/cordova-plugin-googleplus –save –variable REVERSED_CLIENT_ID=googleClientId
Package.json
Die beiden folgenden Dependencies müssen nun noch hinzugefügt werden:
“angularfire2”: “^2.0.0-beta.6”,
“firebase”: “^3.6.2”,
Das kann per npm install firebase oder auch durch das editieren der package.json und npm install vorgenomen werden.
app.module.ts
Dort nun folgendes einfügen:
import { AngularFireModule, AuthProviders, AuthMethods } from ‘angularfire2’;
export const firebaseConfig = {
apiKey: “apiKey”,
authDomain: “authDomain”,
databaseURL: “https://foo.firebaseio.com",
storageBucket: “foo.appspot.com”,
};
const myFirebaseAuthConfig = {
provider: AuthProviders.Password,
method: AuthMethods.Password
}
….
imports: [
IonicModule.forRoot(MyApp),
AngularFireModule.initializeApp(firebaseConfig, myFirebaseAuthConfig)
],
Login Code
Für die folgenden Scripts wurden die folgenden Imports verwenden:
import {AngularFire, AuthMethods, AuthProviders, FirebaseAuthState} from ‘angularfire2’;
import {Observable} from “rxjs”;
import {Facebook} from “ionic-native”;
import {GooglePlus} from ‘ionic-native’;
import {Platform} from “ionic-angular”;
und als Konstruktor
constructor(private af: AngularFire, private platform: Platform) { }
loginWithGoogle() {
return Observable.create(observer => {
this.af.auth.subscribe((data: FirebaseAuthState) => {
this.af.auth.unsubscribe()
console.log(“in auth subscribe”, data)
this.platform.ready().then(() => {
GooglePlus.login({
‘webClientId’ : ‘YOURTWEBCLIENTID’ }) .then((userData) => {
var provider = firebase.auth.GoogleAuthProvider.credential(userData.idToken);
firebase.auth().signInWithCredential(provider)
.then((firebaseData) => {
console.log("Firebase success: " + JSON.stringify(firebaseData));
observer.next();
})
.catch((error) => {
console.log("Firebase failure: " + JSON.stringify(error));
});
})
.catch((error) => {
console.log("Firebase failure: " + JSON.stringify(error));
});
})
})
});
}
Die “YOURWEBCLIENTID” findet ihr unter Firebase >> Authentication >> Anmeldemethoden >> Google >> Web SDK Configuration. Wer das den User dann noch speichern möchte, kann das mit:
this.af.database.list(‘usertabelleInFirebase’).update(success.uid, {
email: success.email,
provider: ‘google’,
picture: success.photoURL
});
Dann wird der Benutzer in der Firebase Datenbank gespeichert.
loginWithFacebook() {
return Observable.create(observer => {
this.af.auth.subscribe((data: FirebaseAuthState) => {
this.af.auth.unsubscribe()
Facebook.login([‘public_profile’, ‘email’]).then(facebookData => {
let provider = firebase.auth.FacebookAuthProvider.credential(facebookData.authResponse.accessToken);
firebase.auth().signInWithCredential(provider).then(firebaseData => {
console.log(firebaseData);
observer.next();
});
}, error => {
observer.error(error);
})
.catch((error) => {
console.log(“Firebase failure: “ + JSON.stringify(error));
});;
});
}
Probleme mit Duplicate Identifier und Firebase
Falls ihr Probleme wie unter https://github.com/angular/angularfire2/issues/663 bekommt, könnt ihr auch als Starter App das Beispiel unter https://github.com/ionic2blueprints/firebase-chat verwenden. Dies hat bei mir Problem los funktioniert.
Release und Debug Zertifikat
Für Google und Facebook müssen beim releasen der App die beiden Cordova Plugins entfernt und neu hinzugefügt werden, mit der jeweilig richtigen ClientId. Dazu kann z.B. das Script https://github.com/lightszentip/ionic-release-build-script erweitert werden. Alternativ kann die ClientId für google auch direkt in der config.xml geändert werden unter
Firebase is not defined
Bei der Verwendung von “@ionic/app-scripts”: “0.0.46” oder höher, muss firebase anders eingebunden werden. Eine Möglichkeit ist das in der index.html zu tun:
oder die folgende Anleitung befolgen: https://github.com/angular/angularfire2/blob/master/docs/aot-rollup-cli-setup.md. Alternativ kann man auch auf “@ionic/app-scripts”: “0.0.45” zurück.
Weiterführende Links
https://ionicthemes.com/tutorials/about/ionic2-google-login http://vpt-deeplearner.tech/2016/10/17/ionic-2-googleplus-authentication-using-firebase-and-angularfire-on-android-device/ https://github.com/EddyVerbruggen/cordova-plugin-googleplus/blob/master/README.md https://github.com/rodrigoreal/ionic2-angularfire-login http://blog.ionic.io/google-oauth-changes/ https://github.com/angular/angularfire2/blob/master/docs/Auth-with-Ionic2.md