Giter Club home page Giter Club logo

openhab-grafana's Introduction

openhab-grafana

Build Status MIT Current Releases

This project provides a JavaScript library with examples to simplify embedding Grafana panels in openHAB 2 (OH) and its derivatives.

The library provides the following functionality:

  • Generation of Grafana embedded panel URL parameters based on the state of OH items (using REST and subscribing to Server-sent events (SSE))
  • Smart parameter resolution (more on that later)
  • Debug mode for debugging URL generation

This functionality solves the issue of having to create a Webview with a visibility=[..] configuration for user customizable Grafana panel parameters. The resulting sitemaps have less duplication and page load times decrease because a only single Webview has to be loaded.

Requirements

Library objects, their parameters and how they are resolved

The library consists of two kinds of objects:

  • OHSubscriber: resolves initial OH item values and listens for item value changes
  • GrafanaPanel: keeps track of the properties of a Grafana panel properties, the enclosing <iframe> tag and updates the <iframe> source URL when OH item values change.

A OHSubscriber instance is always created when the JavaScript of the library loaded. GrafanaPanel objects are created using JavaScript. The utility method addGrafanaPanel(uniqueId, grafanaPanelParameters) can be used to create and add a Grafana panel to the <body> of the HTML document.

Library objects require some parameters for their functionality. These parameters are resolved in the following order:

  1. JavaScript object constructor arguments
  2. query parameters of the HTML document, the URL of the document that is loaded in a OH Webview
  3. query parameters of the parent HTML document, the URL of OH itself
  4. the OHG_DEFAULTS defined in openhab-grafana.js

OHSubscriber parameters

The OHSubscriber typically resolves its parameters from the OH URL. These parameters can be manually added to the browser URL when showing the page outside of OH.

Parameter name Comment
w the subscription page, e.g. "0002"
sitemap the subscription sitemap, e.g. "default"

GrafanaPanel parameters

Parameter name Comment
frame the unique identifier of the <iframe> tag in which the panel is shown, e.g. "panel-123-frame" when the panel is created with addGrafanaPanel("123")
urlPrefix the prefix to use for generating Grafana panel URLs, e.g. "http://grafana:3000"
panelPath the panel path in Grafana panel URLs, e.g. "/dashboard-solo/db/"
renderPanelPath the rendered path in Grafana panel URLs, e.g. "/render/dashboard-solo/db/"
debug shows the generated URL instead of the panel when set to "true"
debugItem the name of the OH item used for resolving the debug value, e.g. "Combo2_Debug"
debugItemFunction the function for mapping the debugItem value to "true" or "false" (JavaScript only)
dashboard static definition of the Grafana dashboard name, e.g. "motion"
dashboardItem the name of the OH item used for resolving the dashboard Grafana URL value, e.g. "Combo2_Dashboard"
dashboardItemFunction the function for mapping the dashboardItem value to a Grafana URL value (JavaScript only)
from static definition of the from= Grafana URL value, e.g. "now-1w"
fromItem the name of the OH item used for resolving the from= value, e.g. "Combo2_From"
fromItemFunction the function for mapping the fromItem value to a Grafana URL value (JavaScript only)
to static definition of the to= Grafana URL value, e.g. "now"
toItem the name of the OH item used for resolving the to= value, e.g. "Combo2_To"
toItemFunction the function for mapping the toItem value to a Grafana URL value (JavaScript only)
panel static definition of the panelId= Grafana URL value, e.g. "5"
panelItem the name of the OH item used for resolving the panelId= value, e.g. "Combo2_Panel"
panelItemFunction the function for mapping the panelItem value to a Grafana URL value (JavaScript only)
theme static definition of the theme= Grafana URL value, e.g. "light"
themeItem the name of the OH item used for resolving the theme= value, e.g. "Combo2_Theme"
themeItemFunction the function for mapping the themeItem value to a Grafana URL value (JavaScript only)
render makes Grafana render an image of the panel, use "true" or "false", when set to "true" the width, height and refresh parameters are used
renderItem the name of the OH item used for resolving the render value, e.g. "Render2_Render"
renderItemFunction the function for mapping the renderItem value to "true" or "false" (JavaScript only)
width static definition of the width= Grafana URL value, e.g. "1000" (only used when render is "true", use width=auto to use the width of the frame
widthItem the name of the OH item used for resolving the width= value, e.g. "Render2_Width"
widthItemFunction the function for mapping the widthItem value to a number or "auto" (JavaScript only)
height static definition of the height= Grafana URL value, e.g. "300" (only used when render is "true", use height=auto to use the height of the frame
heightItem the name of the OH item used for resolving the height= value, e.g. "Render2_Height"
heightItemFunction the function for mapping the heightItem value to a number or "auto" (JavaScript only)
refresh static definition of the refresh interval for a rendered panel in milliseconds, e.g. "60000" for refreshing every minute, use "0" to disable
refreshItem the name of the OH item used for resolving the refresh value, e.g. "Render2_Refresh"
refreshItemFunction the function for mapping the refreshItem value to a number (JavaScript only)

Grafana time units

The Grafana documentation has an overview with the time units that can be used with the from= and to= URL values.

Demo

A demo is included that has some examples on how to use the library. A Grafana installation is not required for the demo, because it uses the library in debug mode. In this mode it does not load Grafana panels. Instead it shows the generated panel URLs.

To run the demo:

  1. add the files in the example directory to the /conf/ directory of an existing openHAB 2 installation
  2. start the demo by opening the grafana sitemap, e.g. navigate to: http://localhost:8080/basicui/app?sitemap=grafana

Demo screenshots

Click on a thumbnail below to zoom in on a demo page.

Main menu
Main
Static panels Combining panels
Static Combo
Multiple panels Rendered panels
Multi Render

Static panels

These three panels are created using the same demo.html file:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-type" CONTENT="text/html; charset=utf-8">
    <link rel="stylesheet" type="text/css" href="panel-300px.css" />
    <script src="openhab-grafana.js"></script>
    <script src="openhab-grafana-user-defaults.js"></script>
</head>

<body>
</body>

<script>
    addGrafanaPanel();
</script>

</html>

This allows for reusing the same CSS and some Grafana defaults defined in openhab-grafana-user-defaults.js.

Because of these defaults, the urlPrefix is automatically added and the light Grafana theme is used even though they are not defined in the Webview URLs in grafana.sitemap. The URL of the Static 3 Webview in the sitemap also specifies theme=dark which overrides the light default.

By using the debug mode, the library only shows the generated URLs and not the actual pages. This mode can disabled by commenting the debug line in openhab-grafana-user-defaults.js. In debug mode clicking on a generated link loads the actual Grafana panel. When debug mode is disabled, it can be reenabled for a particular Webview by adding &debug=true its respective URL. It can also be reenabled by adding &debug=true to your browser URL, e.g.: http://localhost:8080/basicui/app?w=0000&sitemap=grafana&debug=true

Combining panels

On this page the Grafana URL panel parameters are generated by the library using the state of OH items. There are only two Webviews on this page. Without the library, for each parameter combination a Webview with a visibility=[..] expression needs to be added to the sitemap. For Combo 2 this would have resulted in 2*4*5*6*2 = 480 Webviews being added to the sitemap. It would also take a lot of time to load such a page.

Using OH items as Grafana panel URL parameters is done by adding their names to the URL of a Webview. For instance Combo 2 uses the following Webview definition:

Webview url="/static/demo-combo2.html?dashboardItem=Combo2_Dashboard&fromItem=Combo2_From&toItem=Combo2_To&panelItem=Combo2_Panel&themeItem=Combo2_Theme" height=9

The library retrieves the initial values of these items using a REST call. It also subscribes to sitemap events so it can update them when they are changed. A JavaScript function can be defined to map OH item values to Grafana panel parameter values.

This is straightforward and for instance done in demo-combo2.html using:

var fromToItemFunction = function(value) {
    switch (value) {
        case "NOW": 
            return "now";
        case "HOUR": 
            return "now-1h";
        case "DAY":
            return "now-1d";
        default: 
        case "WEEK":
            return "now-1w";
        case "MONTH":
            return "now-1M";
        case "YEAR":
            return "now-1y";
    }
}

var panelItemFunction = function(value) {
    switch (value) {
        case "HUMIDITY": 
            return "1";
        default: 
        case "TEMPERATURE":
            return "2";
    }
}

addGrafanaPanel("combination", {
    fromItemFunction: fromToItemFunction,
    toItemFunction: fromToItemFunction,
    panelItemFunction: panelItemFunction,
});

Combo 3 shows how to completely work without JavaScript functions for mapping item values to URL values. This can be done by using the Grafana URL values with double quotes " in the grafana.sitemap mappings. This also allows for reusing the same HTML page (demo.html) for a lot of Webviews.

Multiple panels

This page shows how a JavaScript for loop is used to show several panels of the same dashboard in the same Webview. The panel numbers are calculated and added in demo-multi1.html as follows:

for (var i = 1; i <= 10; i++) {
    addGrafanaPanel(i, {
        panel: i
    });
}

Generated panel tags all have a unique identifier that can be used for CSS styling. The identifiers are based on the first parameter of the addGrafanaPanel function. In this example the library generates:

  • panel-1-frame, panel-2-frame, ... for Grafana panel <iframe> tags
  • panel-1-container, panel-2-container, ... for the <div> tags enclosing the corresponding <iframe> tags

Rendered panels

This page shows how the library is used to generate URLs for rendered Grafana panels. Render 1 again uses demo.html and a static parameter definition for the Webview URL in grafana.sitemap:

Webview url="/static/demo.html?dashboard=wifireception&from=now-1w&to=now&panel=10&width=600&height=300&render=true&refresh=5000" height=9

A rendered panel image is used when the URL contains render=true. To let the library calculate the width and height of a panel use width=auto and height=auto. It will then use the width and height of the frame for the Grafana URL values. The refresh=5000 URL parameter makes the library reload the Grafana panel image every 5 seconds. Refresh can be disabled by omitting the value or by using refresh=0.

Render 2 shows how OH item values can be used for customizing the render, width, height and refresh parameters.

Reverse proxy configuration

When the Grafana panels do not properly update this is most likely caused by Same-origin policy violations. These can be resolved by for instance configuring a reverse proxy on the same host/port that proxies traffic to openHAB and Grafana.

With the Apache2 and Nginx examples below Grafana will be accessible on /grafana, htpasswd is used for access control and SSL certificates for encrypting the data. See also the openHAB Security Documentation for information on this subject.

Because Grafana runs on another port/URL with this reverse proxy setup don't forget to update the URL in openhab-grafana-user-defaults.js to something like the line below (where hostname is the IP/host you use in your browser):

OHG_DEFAULTS["urlPrefix"] = "https://hostname/grafana";

Grafana will also need to be reconfigured to use /grafana as root URL. This is done by updating the root_url in grafana.ini (in /etc/grafana) to the configuration below and then restarting Grafana.

# The full public facing url you use in browser, used for redirects and emails
# If you use reverse proxy and sub path specify full url (with sub path)
root_url = %(protocol)s://%(domain)s/grafana/

The following sections contain configuration examples for Apache2 and Nginx. After editing your configuration make sure to restart the Apache2 or Nginx to reload the configuration. You should then be able to access both openHAB and Grafana via HTTPS on the same port in your browser using the reverse proxy (port 443 instead of 8080).

If you still run into any issues with this you can:

  • Check your browser debug console (F12) for any errors
  • Check the Grafana log file for any errors (/var/log/grafana/grafana.log)
  • Restart openHAB, in the past there have been issues where newly added sitemap items were not properly updated in UIs
  • Read the comments in this issue which also contains some example error messages that are caused by Same-origin policy violations

Apache2

With Apache2 you can create an enabled site with the configuration below. In Debian based distributions (Ubuntu, openHABian, Raspbian) the enabled sites are usually stored in /etc/apache2/sites-enabled.

SSLStaplingCache shmcb:/tmp/stapling_cache(128000)

<VirtualHost _default_:443>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

    RequestHeader set X-Forwarded-Proto "https"

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SSLEngine on
    SSLCertificateFile      /etc/ssl-certs/domain.com/cert.pem
    SSLCertificateKeyFile   /etc/ssl-certs/domain.com/privkey.pem
    SSLCertificateChainFile /etc/ssl-certs/domain.com/chain.pem
    SSLUseStapling on

    RewriteEngine On

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
            SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory /usr/lib/cgi-bin>
            SSLOptions +StdEnvVars
    </Directory>

    <Location "/">
        AuthType Basic
        AuthName "Authentication"
        AuthUserFile "/etc/auth-basic/htpasswd"
        Require valid-user

        Order allow,deny
        Allow from all

        ProxyPass        http://localhost:8080/ retry=0 timeout=3600
        ProxyPassReverse http://localhost:8080/
    </Location>

    <Location "/grafana">
        AuthType Basic
        AuthName "Authentication"
        AuthUserFile "/etc/auth-basic/htpasswd"
        Require valid-user

        Order allow,deny
        Allow from all

        ProxyPass        http://localhost:3000 retry=0 timeout=3600
        ProxyPassReverse http://localhost:3000
    </Location>

    BrowserMatch "MSIE [2-6]" \
            nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0
    BrowserMatch "MSIE [7-9]" ssl-unclean-shutdown

</VirtualHost>

Nginx

With Nginx you can add a server to your server configuration file. In Debian based distributions (Ubuntu, openHABian, Raspbian) the enabled sites are usually stored in /etc/nginx/sites-enabled.

server {
    listen                          443 ssl;
    server_name                     _;

    ssl_certificate                 /etc/ssl-certs/domain.com/fullchain.pem;
    ssl_certificate_key             /etc/ssl-certs/domain.com/privkey.pem;

    auth_basic                      "Username and Password Required";
    auth_basic_user_file            /etc/auth-basic/htpasswd;

    location / {
        proxy_pass                            http://localhost:8080/;
        proxy_set_header Host                 $http_host;
        proxy_set_header X-Real-IP            $remote_addr;
        proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto    $scheme;
    }

    location /grafana/ {
        proxy_pass http://localhost:3000/;
    }
}

Development

The JavaScript files in the repository are ready to be used with openHAB. When modifying the library JavaScript code, use Gulp for linting the code with ESLint and to minify it after making changes.

Debian/Ubuntu

Node, NPM and Gulp can be installed using APT:

sudo apt install npm gulp

Open a shell and change the working directory (cd) to the root of the repository and execute:

npm install
gulp

Maven

Alternatively there is a POM file in the repository which can be used for downloading Node, NPM and to run Gulp when Java and Maven are installed. Open a shell and change the working directory (cd) to the root of the repository and execute:

mvn clean package

openhab-grafana's People

Contributors

dependabot[bot] avatar holgerhees avatar wborn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openhab-grafana's Issues

Back Button in Basic UI must be pressed several times before returning to previous page

Hi wborn,

due to openHAB release 2.5.0-1 i fresh installed openHABian.

Now I do notice a strange behaviour while navigating on Basic UI page including dynamic webview elements.
Nor the browser or the sitemap back button works instantly. Instead i have to press several times in order to return to the previous page. In fact the number of required presses correlates with the number of shown grafana panels + 1.

I tested it in Firefox and Chrome, in both the same thing.

Any ideas?

Thanks
Henning

Connection problem in Basic UI on pages with embedded grafana panels and NGINX in place

Hi wborn, Hi All,

after having problems with openHAB pages not reloading with parameter change, i installed a reverse proxy to solve the Same-origin policy issue. Now on IE, Chrome, Firefox and Android App, everything works fine.

The downside is that with the reverse proxy enabled, i receive approx. every minute a message in Basic UI saying "Offline: Waiting for connection".

I'm running everyhting inside a local network with openHABian on Pi3B. My versions are:
openHab 2.5.0 M1
grafana 5.1.4
nginx 1.10.3

Can you please have a look on my configs below? Might be that i have missed something or you have a clever idea which can help me. I'm stuck.

Thanks a lot
BR
Henning

NGINX:

#################################
# openHABian NGINX Confiuration #
#################################

## Redirection
server {
        listen                          80;
        server_name                     192.168.2.55;
        return 301                      https://$server_name$request_uri;
}

## Reverse Proxy to openHAB
server {
        listen                          443 ssl;
        server_name                     192.168.2.55;

        ## Secure Certificate Locations
        ssl_certificate                 /etc/ssl/certs/openhab.crt;
        ssl_certificate_key             /etc/ssl/certs/openhab.key;
        add_header                      Strict-Transport-Security "max-age=31536000; includeSubDomains";

        # Cross-Origin Resource Sharing.
        add_header 'Access-Control-Allow-Origin' 'http://localhost:8080/rest';
        add_header 'Access-Control-Allow_Credentials' 'true';
        add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';

        location / {
                proxy_pass                              http://localhost:8080/;
                # proxy_buffering                         off;  # openHAB supports non-buffering specifically for SSEs now
                proxy_set_header Host                   $http_host;
                proxy_set_header X-Real-IP              $remote_addr;
                proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto      $scheme;

                ## Password Protection
                auth_basic                              "Username and Password Required";
                auth_basic_user_file                    /etc/nginx/.htpasswd;
        }

        location /grafana/ {
                proxy_pass                              http://localhost:3000/;
        }
}

Grafana.ini:

##################### Grafana Configuration Example #####################
#
# Everything has defaults so you only need to uncomment things you want to
# change

# possible values : production, development
;app_mode = production

# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
;instance_name = ${HOSTNAME}

#################################### Paths ####################################
[paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
;data = /var/lib/grafana

# Directory where grafana can store logs
;logs = /var/log/grafana

# Directory where grafana will automatically scan and look for plugins
;plugins = /var/lib/grafana/plugins

# folder that contains provisioning config files that grafana will apply on startup and while running.
;provisioning = conf/provisioning

#################################### Server ####################################
[server]
# Protocol (http, https, socket)
#protocol = http

# The ip address to bind to, empty will bind to all interfaces
#http_addr = 192.168.2.55

# The http port  to use
# http_port = 3000

# The public facing domain name used to access grafana from a browser
#domain = 192.168.2.55

# Redirect to correct domain if host header does not match domain
# Prevents DNS rebinding attacks
;enforce_domain = false

# The full public facing url you use in browser, used for redirects and emails
# If you use reverse proxy and sub path specify full url (with sub path)
# NGINX reverse proxy host e.g. port config:
root_url = %(protocol)s://%(domain)s/grafana/
# Normal host e.g. port config:
#root_url = http://localhost/grafana/

# Log web requests
;router_logging = false

# the path relative working path
;static_root_path = public

# enable gzip
;enable_gzip = false

# https certs & key file
;cert_file =
;cert_key =

# Unix socket path
;socket =

#################################### Database ####################################
[database]
# You can configure the database connection by specifying type, host, name, user and password
# as separate properties or as on string using the url properties.

# Either "mysql", "postgres" or "sqlite3", it's your choice
;type = sqlite3
;host = 127.0.0.1:3306
;name = grafana
;user = root
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
;password =

# Use either URL or the previous fields to configure the database
# Example: mysql://user:secret@host:port/database
;url =

# For "postgres" only, either "disable", "require" or "verify-full"
;ssl_mode = disable

# For "sqlite3" only, path relative to data_path setting
;path = grafana.db

# Max idle conn setting default is 2
;max_idle_conn = 2

# Max conn setting default is 0 (mean not set)
;max_open_conn =

# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours)
;conn_max_lifetime = 14400

# Set to true to log the sql calls and execution times.
log_queries =

#################################### Session ####################################
[session]
# Either "memory", "file", "redis", "mysql", "postgres", default is "file"
;provider = file

# Provider config options
# memory: not have any config yet
# file: session dir path, is relative to grafana data_path
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana`
# mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
# postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
;provider_config = sessions

# Session cookie name
;cookie_name = grafana_sess

# If you use session in https only, default is false
;cookie_secure = false

# Session life time, default is 86400
;session_life_time = 86400

#################################### Data proxy ###########################
[dataproxy]

# This enables data proxy logging, default is false
;logging = false

#################################### Analytics ####################################
[analytics]
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
# No ip addresses are being tracked, only simple counters to track
# running instances, dashboard and error counts. It is very helpful to us.
# Change this option to false to disable reporting.
;reporting_enabled = true

# Set to false to disable all checks to https://grafana.net
# for new vesions (grafana itself and plugins), check is used
# in some UI views to notify that grafana or plugin update exists
# This option does not cause any auto updates, nor send any information
# only a GET request to http://grafana.com to get latest versions
;check_for_updates = true

# Google Analytics universal tracking code, only enabled if you specify an id here
;google_analytics_ua_id =

#################################### Security ####################################
[security]
# default admin user, created on startup
;admin_user = admin

# default admin password, can be changed before first start of grafana,  or in profile settings
;admin_password = admin

# used for signing
;secret_key = SW2YcwTIb9zpOOhoPsMm

# Auto-login remember days
;login_remember_days = 7
;cookie_username = grafana_user
;cookie_remember_name = grafana_remember

# disable gravatar profile images
;disable_gravatar = false

# data source proxy whitelist (ip_or_domain:port separated by spaces)
;data_source_proxy_whitelist =

# disable protection against brute force login attempts
;disable_brute_force_login_protection = false

#################################### Snapshots ###########################
[snapshots]
# snapshot sharing options
;external_enabled = true
;external_snapshot_url = https://snapshots-origin.raintank.io
;external_snapshot_name = Publish to snapshot.raintank.io

# remove expired snapshot
;snapshot_remove_expired = true

#################################### Dashboards History ##################
[dashboards]
# Number dashboard versions to keep (per dashboard). Default: 20, Minimum: 1
;versions_to_keep = 20

#################################### Users ###############################
[users]
# disable user signup / registration
allow_sign_up = false

# Allow non admin users to create organizations
;allow_org_create = true

# Set to true to automatically assign new users to the default organization (id 1)
;auto_assign_org = true

# Default role new users will be automatically assigned (if disabled above is set to true)
;auto_assign_org_role = Viewer

# Background text for the user field on the login page
;login_hint = email or username

# Default UI theme ("dark" or "light")
;default_theme = dark

# External user management, these options affect the organization users view
;external_manage_link_url =
;external_manage_link_name =
;external_manage_info =

# Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard.
;viewers_can_edit = false

[auth]
# Set to true to disable (hide) the login form, useful if you use OAuth, defaults to false
;disable_login_form = false

# Set to true to disable the signout link in the side menu. useful if you use auth.proxy, defaults to false
;disable_signout_menu = false

#################################### Anonymous Auth ##########################
[auth.anonymous]
# enable anonymous access
enabled = true

# specify organization name that should be used for unauthenticated users
;org_name = Main Org.

# specify role for unauthenticated users
;org_role = Viewer

#################################### Github Auth ##########################
[auth.github]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org
;auth_url = https://github.com/login/oauth/authorize
;token_url = https://github.com/login/oauth/access_token
;api_url = https://api.github.com/user
;team_ids =
;allowed_organizations =

#################################### Google Auth ##########################
[auth.google]
;enabled = false
;allow_sign_up = true
;client_id = some_client_id
;client_secret = some_client_secret
;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
;auth_url = https://accounts.google.com/o/oauth2/auth
;token_url = https://accounts.google.com/o/oauth2/token
;api_url = https://www.googleapis.com/oauth2/v1/userinfo
;allowed_domains =

#################################### Generic OAuth ##########################
[auth.generic_oauth]
;enabled = false
;name = OAuth
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org
;auth_url = https://foo.bar/login/oauth/authorize
;token_url = https://foo.bar/login/oauth/access_token
;api_url = https://foo.bar/user
;team_ids =
;allowed_organizations =

#################################### Grafana.com Auth ####################
[auth.grafana_com]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email
;allowed_organizations =

#################################### Auth Proxy ##########################
[auth.proxy]
;enabled = false
;header_name = X-WEBAUTH-USER
;header_property = username
;auto_sign_up = true
;ldap_sync_ttl = 60
;whitelist = 192.168.1.1, 192.168.2.1

#################################### Basic Auth ##########################
[auth.basic]
enabled = false

#################################### Auth LDAP ##########################
[auth.ldap]
;enabled = false
;config_file = /etc/grafana/ldap.toml
;allow_sign_up = true

#################################### SMTP / Emailing ##########################
[smtp]
;enabled = false
;host = localhost:25
;user =
# If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
;password =
;cert_file =
;key_file =
;skip_verify = false
;from_address = [email protected]
;from_name = Grafana
# EHLO identity in SMTP dialog (defaults to instance_name)
;ehlo_identity = dashboard.example.com

[emails]
;welcome_email_on_sign_up = false

#################################### Logging ##########################
[log]
# Either "console", "file", "syslog". Default is console and  file
# Use space to separate multiple modes, e.g. "console file"
;mode = console file

# Either "debug", "info", "warn", "error", "critical", default is "info"
;level = info

# optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug
;filters =

# For "console" mode only
[log.console]
;level =

# log line format, valid options are text, console and json
;format = console

# For "file" mode only
[log.file]
;level =

# log line format, valid options are text, console and json
;format = text

# This enables automated log rotate(switch of following options), default is true
;log_rotate = true

# Max line number of single file, default is 1000000
;max_lines = 1000000

# Max size shift of single file, default is 28 means 1 << 28, 256MB
;max_size_shift = 28

# Segment log daily, default is true
;daily_rotate = true

# Expired days of log file(delete after max days), default is 7
;max_days = 7

[log.syslog]
;level =

# log line format, valid options are text, console and json
;format = text

# Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
;network =
;address =

# Syslog facility. user, daemon and local0 through local7 are valid.
;facility =

# Syslog tag. By default, the process' argv[0] is used.
;tag =

#################################### Alerting ############################
[alerting]
# Disable alerting engine & UI features
;enabled = true
# Makes it possible to turn off alert rule execution but alerting UI is visible
;execute_alerts = true

#################################### Internal Grafana Metrics ##########################
# Metrics available at HTTP API Url /metrics
[metrics]
# Disable / Enable internal metrics
;enabled           = true

# Publish interval
;interval_seconds  = 10

# Send internal metrics to Graphite
[metrics.graphite]
# Enable by setting the address setting (ex localhost:2003)
;address =
;prefix = prod.grafana.%(instance_name)s.

#################################### Distributed tracing ############
[tracing.jaeger]
# Enable by setting the address sending traces to jaeger (ex localhost:6831)
;address = localhost:6831
# Tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2)
;always_included_tag = tag1:value1
# Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote
;sampler_type = const
# jaeger samplerconfig param
# for "const" sampler, 0 or 1 for always false/true respectively
# for "probabilistic" sampler, a probability between 0 and 1
# for "rateLimiting" sampler, the number of spans per second
# for "remote" sampler, param is the same as for "probabilistic"
# and indicates the initial sampling rate before the actual one
# is received from the mothership
;sampler_param = 1

#################################### Grafana.com integration  ##########################
# Url used to to import dashboards directly from Grafana.com
[grafana_com]
;url = https://grafana.com

#################################### External image storage ##########################
[external_image_storage]
# Used for uploading images to public servers so they can be included in slack/email messages.
# you can choose between (s3, webdav, gcs, azure_blob, local)
;provider =

[external_image_storage.s3]
;bucket =
;region =
;path =
;access_key =
;secret_key =

[external_image_storage.webdav]
;url =
;public_url =
;username =
;password =

[external_image_storage.gcs]
;key_file =
;bucket =
;path =

[external_image_storage.azure_blob]
;account_name =
;account_key =
;container_name =

[external_image_storage.local]
# does not require any configuration

openhab-grafana-user-defaults.js:

// the prefix that is used for each Grafana panel URL
OHG_DEFAULTS["urlPrefix"] = "https://192.168.2.55/grafana";

// use "false" so actual pages are loaded (or comment the line)
OHG_DEFAULTS["debug"] = "false";

// use "default" for the default openHAB sitemap (or comment the line)
OHG_DEFAULTS["sitemap"] = "home";

if (OHG_DEFAULTS["debug"] === "true") {
    console.log("Using OHG_DEFAULTS = " + JSON.stringify(OHG_DEFAULTS));
}

openHAB Sitemap URL:

Webview url="https://192.168.2.55/static/demo.html?dashboard=openhab2_roomba&fromItem=ROOMBA_HISTORY_START_TIME&toItem=ROOMBA_HISTORY_STOP_TIME&panel=2&theme=light&w=0301000311&sitemap=home" height=20 icon="none"

Charts are not shown on Openhab Android APP

Hi,
I'm using your code in my openhab installation. Works like a charm from the browser but not on Android app.
I tried to include in sitemap direct grafana link, and it work, so I think there is someting in your code that avoid charts to be shown on android app.

Can you helpme about this?

Kindly regarda
Marco

External (i.e. non-network local access)

Hi,
thanks for this work. Is there any way to make it work when not connected to the network the Smart Home device is in?

I have a raspberry pi running openhab and grafana. Openhab is accessible from outside the network behind authentication. Unfortunately, I cannot view any graphs provided by this script as the adresses, of course, make no sense if you are trying to view them from outside the local network.

Any suggestions? Or am I simply out of luck here?

Listener and Refresh problem with Safari and Chrome

Hello,

first I want to thank you for this really good piece of code. I want to use it in my open hab environment, but there is a problem with my browsers.

On the safari browser the buttons didn't work, i tried the examples with the combo fields. If i press the buttons for Panel and the timeline, nothing happens, no message of the change is sent to Openhab. If i try the same sitemap with Chrome the button press is sent to open hab immediately.

On chrome browser the buttons work, but the chart didn't reload, this works on safari, so if i push the button on chrome, the change works on the safari browser, if i have the same site open in both browsers.

Panel do not change until manual reloading of the page

Hi,
litte annoyng isssue. I have a Combo2 panel similar configuration.
On browser Chrome, when I change one of the parameter like from of panel, page/panel do not refresh automatically, but I have to refresh manually with reload button of the browser.
In Android App, instead, panel is reloaded if one of parameter change.
Is this normal behaviour or there is a way to avoid this?

Many Thanks

marco

[Error] SyntaxError: Can't create duplicate variable: 'typeMap'

I wanted to test the demo in my Openhab installation, but i am getting this error and don't know how to resolve it:
`
[Error] SyntaxError: Can't create duplicate variable: 'typeMap'

write (smarthome-grafana.js:214)

b (smarthome-grafana.js:214)

e (smarthome-grafana.js:53)

f (smarthome-grafana.js:62)

valueHandler (smarthome-grafana.js:159)

onload (smarthome-grafana.js:35)

`

Webview panel doesn't change on the Android app

Hi,

I've looked into the closed issues but that didn't fix my problem unfortunately.
I'm having some issues with your project with the Openhab Android app. On Chrome and Firefox (Laptop and phone) the desired panel loads when a combo is changed in Openhab. However, in the app the page needs to be reloaded manually to show the selected panel.

Software versions:

  • Nginx: 1.10.3
  • Openhab server: 2.3.0
  • Grafana server: 5.1.4
  • Openhab android app: 2.5.0
  • Openhab android beta app: 2.5.4-beta

I've tried the following:

  • Restarting app and phone
  • Clearing cache of apps
  • Restarting services Openhab, Grafana and nginx
  • Restarting the whole system

Note: I'm using port 80 for Pi-hole with lighttpd.

Settings of the app:

Local server URL
http://20.0.0.201:85

sitemap:

Switch item=temp_view 
    mappings=[HOUR="6h", DAY="Day", WEEK="Week", MONTH="Month", YEAR="Year"]
Webview height=9 
    url="/static/demo-combo2.html?dashboardItem=gf_dashboard&fromItem=temp_view&panelItem=gf_panel_temperature"

smarthome-grafana-user-defaults.js:

// the prefix that is used for each Grafana panel URL
SMARTHOME_GRAFANA_DEFAULTS["urlPrefix"] = "http://20.0.0.201:85/grafana";

// use "false" so actual pages are loaded (or comment the line)
SMARTHOME_GRAFANA_DEFAULTS["debug"] = "false";

// use "default" for the default Eclipse SmartHome sitemap (or comment the line)
SMARTHOME_GRAFANA_DEFAULTS["sitemap"] = "default";

if (SMARTHOME_GRAFANA_DEFAULTS["debug"] === "true") {
    console.log("Using SMARTHOME_GRAFANA_DEFAULTS = " + JSON.stringify(SMARTHOME_GRAFANA_DEFAULTS));
}

/etc/nginx/sites-available/default:

server {
	listen 85 default_server;
	listen [::]:85 default_server;
	root /var/www/html;
	index index.html index.htm index.nginx-debian.html;
	server_name _;
        location / {
        	proxy_pass                            http://localhost:8080/;
        	proxy_set_header Host                 $http_host;
        	proxy_set_header X-Real-IP            $remote_addr;
        	proxy_set_header X-Forwarded-For      $proxy_add_x_forwarded_for;
        	proxy_set_header X-Forwarded-Proto    $scheme;
    	}
    	location /grafana/ {
        	proxy_pass http://localhost:3500/;
    	}

Graph variables aren't supported

Grafana supports adding variables to queries for panel customization. These are added to the dashboard URL via the parameter var-variableName. When I add these parameters to the openhab-grafana sitemap item, they aren't forwarded to the dashboard URL.

An example is Luftdaten.info, where the variable node defines the node to plot the graph for.

Openhab + Grafana + Reverseproxy in Docker

Hi,

I'm really struggling to get the Grafana webview panels to work with Openhab and Grafana behind a reverse proxy in Docker.

I get the following errors (in the Firefox console):

SecurityError: Permission denied to get property "href" on cross-origin object smarthome-grafana.js:350

TypeError: smartHomeSubscriber is undefined

Docker-compose file:

version: '2'

services:
   reverseproxy:
     image: reverseproxy
     ports:
     # openhab
     - 5001:5001
     restart: always

   openhab:
     depends_on:
     - reverseproxy
     image: "openhab/openhab:2.4.0"
     restart: always
     ports:
     - "8080:8080"
     - "8443:8443"
     volumes:
     - "/etc/localtime:/etc/localtime:ro"
     - "/etc/timezone:/etc/timezone:ro"
     - "/opt/openhab/addons:/openhab/addons"
     - "/opt/openhab/conf:/openhab/conf"
     - "/opt/openhab/userdata:/openhab/userdata"
     environment:
       OPENHAB_HTTP_PORT: "8080"
       OPENHAB_HTTPS_PORT: "8443"
       EXTRA_JAVA_OPTS: "-Duser.timezone=Europe/Berlin"
       USER_ID: "999"
       GROUP_ID: "999"

   grafana:
     depends_on:
     - reverseproxy
     image: grafana/grafana:latest
     ports:
       - '3000:3000'
     volumes:
       - grafana-storage:/var/lib/grafana
       - grafana-conf:/etc/grafana
     environment:
       - GF_SECURITY_ADMIN_USER=${GRAFANA_USERNAME}
       - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
       - GF_AUTH_ANONYMOUS_ENABLED=true
       - GF_USERS_ALLOW_SIGN_UP=false
       - GF_SERVER_ROOT_URL=http://localhost/grafana/
       - GF_ALLOW_EMBEDDING=true
volumes:
  grafana-storage:
    driver: local
  grafana-conf:
    driver: local

nginx.conf:

worker_processes 1;

events { worker_connections 1024; }

http {

    sendfile on;

    upstream docker-openhab {
        server openhab:8080;
#       server 20.0.0.210:8080;
    }

    server {
        listen 5001;
        server_name     localhost;
        location / {
#           auth_basic           "Restricted Access!";
#           auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
            proxy_pass           http://docker-openhab;
#           proxy_pass           http://localhost:8080;
#           proxy_redirect       off;
            proxy_buffering      off;
            proxy_set_header     Host $http_host;
#           proxy_set_header     Host $host;
            proxy_set_header     X-Real-IP $remote_addr;
            proxy_set_header     X-Forwarded-For $proxy_add_x_forwarded_for;
#           proxy_set_header     X-Forwarded-Host $server_name;
            proxy_set_header     X-Forwarded-Proto $scheme;
#           add_header           X-Frame-Options  ALLOWALL;
#           add_header         X-Frame-Options SAMEORIGIN;
        }

        location /grafana/ {
            proxy_pass         http://20.0.0.210:3000/;
#           proxy_pass         http://docker-grafana/;
#           add_header         X-Frame-Options ALLOWALL;
#           add_header         X-Frame-Options SAMEORIGIN;
        }
    }
}

sitemap:

sitemap default label="test"
{
Webview height=9 icon=none 
url="http://20.0.0.210:5001/static/combo-300px.html?dashboardItem=gf_dashboard&fromItem=temp_view&panelItem=gf_panel_temperature&w=000000"
}
// the prefix that is used for each Grafana panel URL
SMARTHOME_GRAFANA_DEFAULTS["urlPrefix"] = "http://20.0.0.210:5001/grafana";

Openhab can be accessed at:
http://20.0.0.210:5001
Grafana at:
http://20.0.0.210:5001/grafana

Your help is much appreciated, thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.