Hi all,
an update to the google map example, featuring cleaned up code & daily history:
Items:
String ItemMQTT { mqtt="<[broker:owntracks/jkmtnngq/android:state:default]" }
String ItemPatrikLocationHistory
String PatrikLocationString "Patrik [%s]" <place>
Location ItemPatrikLocation "Patrik" <location>
Location ItemLocationHome
Number ItemPatrikLocationAccuracy
Number ItemPatrikNatelBattery "Natel Patrik [%d %%]" <battery> (GroupPersistrrd4jMinute,GroupBattery)
DateTime ItemPatrikLastPositionUpdate "Patrik - letztes Update [%1$tH:%1$tM, %1$td.%1$tm.%1$ty]" <location>
Switch ItemPatrikAtHome "Patrik" <home>
String ItemGoogleMapAPIKey
Rules:
rule InitializeSystem
when
System started
then
ItemLocationHome.postUpdate(new PointType("47.501104543961,8.3445922192264"))
ItemGoogleMapAPIKey.postUpdate("Your API Key")
end
rule PatrikLocationHistoryReset
when
Time is midnight
then
ItemPatrikLocationHistory.postUpdate("")
end
rule "LocationPatrikChanged"
when
Item ItemPatrikLocation changed
then
val _apiKey = ItemGoogleMapAPIKey.state
val _position = ItemPatrikLocation.state as PointType
val _url = "https://maps.googleapis.com/maps/api/geocode/json?latlng="
+ _position.latitude + ","
+ _position.longitude
+ "&sensor=true&key=" + _apiKey
val _geocodeJSON = sendHttpGetRequest(_url)
val _address = transform("JSONPATH", "$.results[0].formatted_address", _geocodeJSON)
PatrikLocationString.postUpdate(_address)
end
rule MQTT
when
Item ItemMQTT changed
then
val _mqtt = (ItemMQTT.state as StringType).toString
println("MQTT: " + _mqtt)
val _messageType = transform("JSONPATH", "$._type", _mqtt)
val _id = transform("JSONPATH", "$.tid", _mqtt)
val _battery = transform("JSONPATH", "$.batt", _mqtt)
if (_messageType == "location") {
val _latitude = transform("JSONPATH", "$.lat", _mqtt)
val _longitude = transform("JSONPATH", "$.lon", _mqtt)
val _accuracy = transform("JSONPATH", "$.acc", _mqtt)
if (_id == "PG") {
val _positionString = _latitude + "," + _longitude
val _position = new PointType(_positionString)
val _distance = -1
val _distanceFromHome = -1
println(_positionString)
println(_position)
println(ItemLocationHome)
println(ItemPatrikLocation)
println(ItemPatrikLocation.state)
if (ItemPatrikLocation.state != NULL) {
println("Calculating distance ...")
_distance = _position.distanceFrom(ItemPatrikLocation.state).intValue
_distanceFromHome = _position.distanceFrom(ItemLocationHome.state).intValue
if (_distanceFromHome < 100) {
ItemPatrikAtHome.postUpdate(ON)
} else {
ItemPatrikAtHome.postUpdate(OFF)
}
}
println(_distance)
println(_distanceFromHome)
if ((_distance > 100) || (_distance < 0)) {
println("Updating location ...")
val _locationHistory = ""
val _location = new PointType(_positionString)
if (ItemPatrikLocationHistory.state != NULL) {
_locationHistory = ItemPatrikLocationHistory.state + _positionString + ";"
}
ItemPatrikLocation.postUpdate(_location)
ItemPatrikLocationAccuracy.postUpdate(new DecimalType(_accuracy).intValue)
ItemPatrikLocationHistory.postUpdate(_locationHistory)
}
ItemPatrikLastPositionUpdate.postUpdate(new DateTimeType())
ItemPatrikNatelBattery.postUpdate(_battery)
}
}
end
Javascript (openHAB.js):
// ***
// * Required definitions:
// * - var baseURL = "../";
// *
// ***
// * Required API
// * - Google jQuery: https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// ***
function _GetData(itemUrl) {
var itemValue = null;
$.ajax({
contentType: 'text/plain',
url: itemUrl,
data: {},
async: false,
success: function(data) {
if (data != "NULL") {
itemValue = data;
}
}
});
return itemValue;
}
// JSON to CSV Converter
function _ConvertToCSV(objArray) {
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '';
for (var i = 0; i < array.data.length; i++) {
var line = '';
for (var index in array.data[i]) {
if (line !== '') line += ',';
line += array.data[i][index];
}
str += line + '\r\n';
}
return str;
}
function GetOpenHABItem(item) {
var itemUrl = baseURL.concat("rest/items/").concat(item).concat("/state/");
var itemValue = null;
return _GetData(itemUrl);
}
function GetOpenHABItemIntValue(item) {
return Math.round(GetOpenHabItem(item));
}
function GetOpenHABItemHistoryJSON(item, days = 1, service = "rrd4j") {
var jsonData = null;
// var numberOfMilliseconds = 86400 * 1000 * days;
var startTimeObject = (new Date()).addDays(days * -1);
// var endTimeObject = new Date();
var _month = startTimeObject.getMonth() + 1;
var _starttime = startTimeObject.getFullYear() + "-" + _month + "-" + startTimeObject.getDate() + "T" + startTimeObject.getHours() + ":" + startTimeObject.getMinutes() + ":" + startTimeObject.getSeconds();
// var _endtime = endTimeObject.getFullYear() + "-" + endTimeObject.getMonth() + "-" + endTimeObject.getDate() + "T" + endTimeObject.getHours() + ":" + endTimeObject.getMinutes() + ":" + endTimeObject.getSeconds();
var itemUrl = baseURL.concat("rest/persistence/items/").concat(item);
itemUrl = itemUrl.concat("?serviceId=" + service);
if (days != 1) { itemUrl = itemUrl.concat("&starttime=" + _starttime); }
// itemUrl = itemUrl.concat("&endtime=" + _endtime);
jsonData = _GetData(encodeURI(itemUrl));
return jsonData;
}
function GetOpenItemHABHistoryCSV(item, days = 1, service = "rrd4j") {
var jsonData = GetOpenHABItemHistoryJSON(item, days, service);
return _ConvertToCSV(jsonData);
}
function GetParameter(parameterName) {
var result = null,
tmp = [];
location.search.substr(1).split("&")
.forEach(function(item) {
tmp = item.split("=");
if (tmp[0] === parameterName) {
result = decodeURIComponent(tmp[1]);
}
});
return result;
}
function DOMSetElementHeight(elementId, height) {
var pageElement = document.getElementById(elementId);
pageElement.style.height = height + "px";
}
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map.
*/
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type="text/javascript" src="../javascript/openHAB.js"></script>
</head>
<body>
<div id="map"></div>
<script>
var baseURL = "../../";
var iconHome = "https://maps.google.com/mapfiles/kml/pal2/icon10.png";
var iconKarin = "https://maps.google.com/mapfiles/ms/icons/blue-dot.png";
var iconPatrik = "https://maps.google.com/mapfiles/ms/icons/green-dot.png";
var iconKarinHistory = "https://maps.google.com/mapfiles/kml/paddle/blu-circle-lv.png";
var iconPatrikHistory = "https://maps.google.com/mapfiles/kml/paddle/grn-circle-lv.png";
var map;
function setMarker(location, markerIcon, zIndex = null, label = null) {
var marker;
if (location != null) {
var lat = parseFloat(location.split(',')[0]);
var lng = parseFloat(location.split(',')[1]);
if (!isNaN(lat) && !isNaN(lng)) {
var markerLocation = new google.maps.LatLng(lat, lng);
marker = new google.maps.Marker({
position: markerLocation,
optimized: false, // Needs to be set to false, else zIndex does not work.
zIndex: zIndex,
icon: {
labelOrigin: new google.maps.Point(14, 42),
url: markerIcon,
},
label: label,
map: map
});
bounds.extend(markerLocation);
}
}
return marker;
}
function showHistory(history, markerIcon) {
var marker;
if (history != null) {
history.split(";").forEach(function(element) {
if (element != "") {
marker = setMarker(element, markerIcon, 1);
}
});
}
return marker;
}
function initializeMap() {
var location = GetOpenHABItem("ItemLocationHome");
var locationHome = new google.maps.LatLng(
parseFloat(location.split(',')[0]),
parseFloat(location.split(',')[1]));
map = new google.maps.Map(document.getElementById('map'), {
center: locationHome,
mapTypeId: google.maps.MapTypeId.TERRAIN,
zoom: 10
});
bounds = new google.maps.LatLngBounds(locationHome, locationHome);
// enable traffic layer
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
showHistory(GetOpenHABItem("ItemPatrikLocationHistory"), iconPatrikHistory);
showHistory(GetOpenHABItem("ItemKarinLocationHistory"), iconKarinHistory);
setMarker(GetOpenHABItem("ItemPatrikLocation"), iconPatrik, 100, "Patrik");
setMarker(GetOpenHABItem("ItemKarinLocation"), iconKarin, 100, "Karin");
setMarker(location, iconHome, 50);
map.fitBounds(bounds);
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=[GoogleAPIKey]&callback=initializeMap" async defer></script>
</body>
</html>
Sitemap:
Webview url="/static/Map/GoogleMap.html" height=11
Hope is it of use as example/inspiration :-).
Notes:
- You need to add your API key to .html
- The .html is for two people - but easy to modify for just one or more ā¦
- openHAB.js needs to be placed subfolder ājavascriptā, the .html in āMapā.
with kind regards,
Patrik