Wie können in der OpenHAB Basic-UI Zahlen, Datum und Uhrzeit eingegeben und diesen an Items übergeben werden? Damit dies alles funktioniert kommen HTML5, CSS und JavaScript Bibliotheken zum Einsatz.
In dem SchreibWas2 Formular sind fünf Felder:
a) Per Datepicker ein Datum auswählen
b) Per Zeitfeld eine gültige Uhrzeit eingeben
c) Range Slider eine Zahl zwischen 0 - 50 auswählen (wird von den verschiedenen Browser und Apps teils unterschiedlich dargestellt)
d) Manuelle Eingabe von Zahlen 10-99 oder mit Spin-Feld
e) Ein [Send] Knopf mit Formvalidation mit dem die Eingabewerte mit Hilfe der OH REST API an die Item übergeben werden
schreibwas2.items[/]
Code: Alles auswählen
// Items für Schreibwas2
DateTime SchreibWas2Datum "Datum [%1$td.%1$tm.%1$tY]" <none>
DateTime SchreibWas2Zeit "Zeit [%1$tI:%1$tM]" <none>
Number SchreibWas2Range "Range [%.0f]" <none>
Number SchreibWas2Zahl "Zahl [%.0f]" <none>
Die eigentliche Darstellung ist in eine Webview ausgelagert. Also in eine .html Datei, die von OH innerhalb eines iFrame in der Sitemap dargestellt wird.
schreibwas2.html
Code: Alles auswählen
<html>
<head>
<link rel="stylesheet" href="lib/bootstrap-4.1.1/bootstrap.min.css">
<style type="text/css">
.label-space { margin: 5px 5px 5px 5px !important; }
.form-color { background-color: #fff3cd; margin: 5px 5px 5px 5px; padding: 5px 5px 5px 5px;}
</style>
</head>
<body class="form-color" ng-app="schreibwas2App" ng-controller="schreibwas2Ctrl" >
<fieldset ><label>Schreibwas II Formular</label>
<div class="form-group">
<label for="datum" class="label-space">Datum</label><input type="date" id="datum" title="Datum für den nächsten Backup" ng-model="schreibwas2.datum" name="datum" >
</div>
<div class="form-group">
<label for="zeit" class="label-space">Zeit</label><input type="time" id="zeit" title="Uhrzeit für den nächsten Backup" ng-model="schreibwas2.zeit" name="zeit" >
</div>
<div class="form-group">
<label class="label-space" for="typ">Temperatur (0-50)</label><span>{{schreibwas2.range}}</span><input title="Temperatur zwischen 0 und 50 Grad einstellen" type="range" class="form-control" ng-model="schreibwas2.range" value="{{schreibwas2.range}}" min="0" max="50" step="1" id="range" name="range" list="tickmarks">
<datalist id="tickmarks">
<option>0</option>
<option>10</option>
<option>20</option>
<option>30</option>
<option>40</option>
<option>50</option>
</datalist>
</div>
<div class="form-group">
<label for="zahl" class="label-space">Zahl (10-99)</label><input type="number" id="zeit" title="Zahleneingabe (10-99)" ng-model="schreibwas2.zahl" name="zahl" min="10" max="99" step="1" >
</div>
</fieldset>
<button type="button" class="btn btn-primary" ng-click="send()">Senden</button>
<script type="text/javascript" src="lib/angular-1.7.8/angular.min.js"></script>
<script type="text/javascript" src="lib/moment-2.27.0/moment.min.js"></script>
<script type="text/javascript" src="lib/moment-2.27.0/locales.min.js"></script>
<script type="text/javascript" src="app/schreibwas2.js"></script>
</body>
</html>
CSS und JavcaScript
Alle benötigten JavaScript und CSS Libraries siehe lib.zip
Verzeichnis: html/lib/bootstrap-4.1.1
CSS Libraries
bootstrap css 4.1.1
ACHTUNG: Derzeit meldet mein Firefox mit diesem LINK ein Zertifikat Error: Fehlercode: SSL_ERROR_BAD_CERT_DOMAIN (Download also auf eigene Gefahr)
https://cdn.usebootstrap.com/bootstrap/ ... ap.min.css
JavaScript Library
AngularJS 1.7.8 (alte 1.x Version, läuft aber Problemlos bei mir. Ab Angular Version 2.x ist alles anders)
Verzeichnis: html/lib/angular-1.7.8
moment-2.27.0 eine JavaScript die sicht um die Darstellung von Datum und Zeitfelder (mit localiation 'de') kümmern.
Im /html Verzeichnis kommt nun das Script schreibwas2.html. Das schreibwas.html Script wird später über ein WebView in der Sitemap geladen
Im /html/app Verzeichnis kommt nun das Script schreibwas.js. Das schreibwas.js JavaScript steuert mit Hilfe von AngularJS die Anzeige in schreibwas.html.
Hier muss die IP Adresse angepaßt werden.
schreibwas2.js
Code: Alles auswählen
/**
* AngularJS App
* schreibwas2.js
* 01.08.2020
*/
var app = angular.module( 'schreibwas2App', [] );
/* AngularJS Controller */
app.controller(
"schreibwas2Ctrl",
function( $scope, $http ) {
/* Angular Formular Felder */
$scope.schreibwas2 = { datum: '', zeit: '', range: 0, zahl: 10};
/* Liste meiner ScheibWas Items - @todo automatisieren */
$scope.items = [
{ item: 'datum', oh_item: 'SchreibWas2Datum'},
{ item: 'zeit', oh_item: 'SchreibWas2Zeit'},
{ item: 'range', oh_item: 'SchreibWas2Range'},
{ item: 'zahl', oh_item: 'SchreibWas2Zahl'}
];
// AngularJS REST API PUT
// fetch api scheint mit PUT, POST mit OH2 nicht zu funktionieren
// https://infinityknow.com/angularjs-restful-web-service-get-and-post-api/
$scope.restApi = function(oh_item, newValue) {
$http({
method : 'PUT',
url : 'http://192.168.x.xxx:8080/rest/items/'+oh_item+'/state',
data : newValue, // text/plain Datenformat
headers : {
'Content-Type' : 'text/plain'
}
}).then(function(response) {
// First function handles success
console.log('success:', oh_item);
}, function(response) {
// Second function handles error
console.log('error:');
console.log(response);
});
};
// moment 2.27.0
// Datetime YYYY-MM-DDTHH:MM:SS => YYYY-MM-DD
// https://momentjs.com/docs/#/displaying/
$scope.getFormattedDate= function(stateValue) {
var formattedDate = moment(stateValue).format('YYYY-MM-DD');
// console.log(formattedDate);
return formattedDate;
};
// moment 2.27.0
// Datetime YYYY-MM-DDTHH:MM:SS => HH:mm
// https://momentjs.com/docs/#/displaying/
$scope.getFormattedTime= function(stateValue) {
moment.locale('de');
var formattedTime = moment(stateValue).format('HH:mm');
// console.log(formattedTime);
return formattedTime;
};
// Datenübergabe an REST API für alle Formularfelder
$scope.send = function() {
console.log( $scope.getFormattedDate($scope.schreibwas2.datum));
console.log( $scope.getFormattedTime($scope.schreibwas2.zeit));
console.log( $scope.schreibwas2.range);
console.log( $scope.schreibwas2.zahl);
if ($scope.schreibwas2.datum) {
$scope.restApi($scope.items[0].oh_item, $scope.getFormattedDate($scope.schreibwas2.datum));
}
if ($scope.schreibwas2.zeit) {
$scope.restApi($scope.items[1].oh_item, $scope.getFormattedTime($scope.schreibwas2.zeit));
}
$scope.restApi($scope.items[2].oh_item, $scope.schreibwas2.range);
$scope.restApi($scope.items[3].oh_item, $scope.schreibwas2.zahl);
};
});
Zum Schluß die Sitemap. Hier muss die IP des Openhab Server angepaßt werden
.sitemap
Code: Alles auswählen
Frame label="SchreibWas II" icon="none" {
Default item=SchreibWas2Datum
Default item=SchreibWas2Zeit
Default item=SchreibWas2Range
Default item=SchreibWas2Zahl
Webview url="http://192.168.x.xxx:8080/static/schreibwas2.html" icon="none" height=12
}
Viel Spaß damit..
Danke und Grüße
Thomas