OH 2.5.5
SchreibWas II - Using HTML5 Input-Type in OpenHAB Basic-UI - good or not?
(translated from germany with a little help from deepl.com)
Projectidea:
How can numbers, date and time be entered in the OpenHAB Basic UI and passed to items? HTML, CSS and JavaScript libraries are used to make this all work.
In this SchreibWas2 Form are five fields:
a) Datepicker
b) Time
c) Range Slider
d) Manual input of numbers 10-99 or with spin field
e) A [Send] button with form validation to pass the input values to the item using the OH REST API
schreibwas2.items
// 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>
The actual presentation is outsourced to a web view. This means into a .html file, which is displayed by OH within an iFrame in the sitemap.
schreibwas2.html
<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>
As can be seen in the .html file, both CSS and JavaScript libraries (angular, moment) are included.
CSS und JavcaScript
All required JavaScript and CSS libraries see lib.zip
Directory: html/lib/bootstrap-4.1.1
CSS Libraries
bootstrap css 4.1.1
ATTENTION: Currently my Firefox reports a certificate Error: Error code with this LINK: SSL_ERROR_BAD_CERT_DOMAIN (Download at your own risk)
https://cdn.usebootstrap.com/bootstrap/4.1.1/css/bootstrap.min.css
JavaScript Library
AngularJS 1.7.8
Directory: html/lib/angular-1.7.8
moment-2.27.0 a JavaScript that takes care of the display of date and time fields (with localiation ‘de’).
The /html directory now contains the script schreibwas2.html. The schreibwas.html script will be loaded later via a web view in the sitemap
The /html/app directory now contains the script schreibwas.js. The schreibwas.js JavaScript controls the display in schreibwas.html using AngularJS.
The IP address must be adjusted here.
schreibwas2.js
/**
* 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);
};
});
Finally the sitemap. The IP of the Openhab server must be adjusted here
.sitemap
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
}
Is this a good idea or not
?
Enjoy it.
Thank you and best wishes
Thomas
P.S. Sorry I can only upload one image and no .zip
Maybe download here:
https://openhabforum.de/viewtopic.php?f=25&t=3835