.okta.com/oauth2/v1/userinfo
+;allowed_domains =
+;allowed_groups =
+;role_attribute_path =
+;role_attribute_strict = false
+
+#################################### 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
+;empty_scopes = false
+;email_attribute_name = email:primary
+;email_attribute_path =
+;login_attribute_path =
+;name_attribute_path =
+;id_token_attribute_name =
+;auth_url = https://foo.bar/login/oauth/authorize
+;token_url = https://foo.bar/login/oauth/access_token
+;api_url = https://foo.bar/user
+;teams_url =
+;allowed_domains =
+;team_ids =
+;allowed_organizations =
+;role_attribute_path =
+;role_attribute_strict = false
+;groups_attribute_path =
+;team_ids_attribute_path =
+;tls_skip_verify_insecure = false
+;tls_client_cert =
+;tls_client_key =
+;tls_client_ca =
+;use_pkce = false
+
+#################################### Basic Auth ##########################
+[auth.basic]
+;enabled = true
+
+#################################### Auth Proxy ##########################
+[auth.proxy]
+;enabled = false
+;header_name = X-WEBAUTH-USER
+;header_property = username
+;auto_sign_up = true
+;sync_ttl = 60
+;whitelist = 192.168.1.1, 192.168.2.1
+;headers = Email:X-User-Email, Name:X-User-Name
+# Read the auth proxy docs for details on what the setting below enables
+;enable_login_token = false
+
+#################################### Auth JWT ##########################
+[auth.jwt]
+;enabled = true
+;header_name = X-JWT-Assertion
+;email_claim = sub
+;username_claim = sub
+;jwk_set_url = https://foo.bar/.well-known/jwks.json
+;jwk_set_file = /path/to/jwks.json
+;cache_ttl = 60m
+;expected_claims = {"aud": ["foo", "bar"]}
+;key_file = /path/to/key/file
+
+#################################### Auth LDAP ##########################
+[auth.ldap]
+;enabled = false
+;config_file = /etc/grafana/ldap.toml
+;allow_sign_up = true
+
+# LDAP background sync (Enterprise only)
+# At 1 am every day
+;sync_cron = "0 0 1 * * *"
+;active_sync_enabled = true
+
+#################################### AWS ###########################
+[aws]
+# Enter a comma-separated list of allowed AWS authentication providers.
+# Options are: default (AWS SDK Default), keys (Access && secret key), credentials (Credentials field), ec2_iam_role (EC2 IAM Role)
+; allowed_auth_providers = default,keys,credentials
+
+# Allow AWS users to assume a role using temporary security credentials.
+# If true, assume role will be enabled for all AWS authentication providers that are specified in aws_auth_providers
+; assume_role_enabled = true
+
+#################################### Azure ###############################
+[azure]
+# Azure cloud environment where Grafana is hosted
+# Possible values are AzureCloud, AzureChinaCloud, AzureUSGovernment and AzureGermanCloud
+# Default value is AzureCloud (i.e. public cloud)
+;cloud = AzureCloud
+
+# Specifies whether Grafana hosted in Azure service with Managed Identity configured (e.g. Azure Virtual Machines instance)
+# If enabled, the managed identity can be used for authentication of Grafana in Azure services
+# Disabled by default, needs to be explicitly enabled
+;managed_identity_enabled = false
+
+# Client ID to use for user-assigned managed identity
+# Should be set for user-assigned identity and should be empty for system-assigned identity
+;managed_identity_client_id =
+
+#################################### SMTP / Emailing ##########################
+[smtp]
+;enabled = false
+;host = localhost:25
+;user =
+# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
+;password =
+;cert_file =
+;key_file =
+;skip_verify = false
+;from_address = admin@grafana.localhost
+;from_name = Grafana
+# EHLO identity in SMTP dialog (defaults to instance_name)
+;ehlo_identity = dashboard.example.com
+# SMTP startTLS policy (defaults to 'OpportunisticStartTLS')
+;startTLS_policy = NoStartTLS
+
+[emails]
+;welcome_email_on_sign_up = false
+;templates_pattern = emails/*.html, emails/*.txt
+;content_types = text/html
+
+#################################### 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 =
+
+[log.frontend]
+# Should Sentry javascript agent be initialized
+;enabled = false
+
+# Sentry DSN if you want to send events to Sentry.
+;sentry_dsn =
+
+# Custom HTTP endpoint to send events captured by the Sentry agent to. Default will log the events to stdout.
+;custom_endpoint = /log
+
+# Rate of events to be reported between 0 (none) and 1 (all), float
+;sample_rate = 1.0
+
+# Requests per second limit enforced an extended period, for Grafana backend log ingestion endpoint (/log).
+;log_endpoint_requests_per_second_limit = 3
+
+# Max requests accepted per short interval of time for Grafana backend log ingestion endpoint (/log).
+;log_endpoint_burst_limit = 15
+
+#################################### Usage Quotas ########################
+[quota]
+; enabled = false
+
+#### set quotas to -1 to make unlimited. ####
+# limit number of users per Org.
+; org_user = 10
+
+# limit number of dashboards per Org.
+; org_dashboard = 100
+
+# limit number of data_sources per Org.
+; org_data_source = 10
+
+# limit number of api_keys per Org.
+; org_api_key = 10
+
+# limit number of alerts per Org.
+;org_alert_rule = 100
+
+# limit number of orgs a user can create.
+; user_org = 10
+
+# Global limit of users.
+; global_user = -1
+
+# global limit of orgs.
+; global_org = -1
+
+# global limit of dashboards
+; global_dashboard = -1
+
+# global limit of api_keys
+; global_api_key = -1
+
+# global limit on number of logged in users.
+; global_session = -1
+
+# global limit of alerts
+;global_alert_rule = -1
+
+#################################### Unified Alerting ####################
+[unified_alerting]
+#Enable the Unified Alerting sub-system and interface. When enabled we'll migrate all of your alert rules and notification channels to the new system. New alert rules will be created and your notification channels will be converted into an Alertmanager configuration. Previous data is preserved to enable backwards compatibility but new data is removed.```
+;enabled = true
+
+# Comma-separated list of organization IDs for which to disable unified alerting. Only supported if unified alerting is enabled.
+;disabled_orgs =
+
+# Specify the frequency of polling for admin config changes.
+# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
+;admin_config_poll_interval = 60s
+
+# Specify the frequency of polling for Alertmanager config changes.
+# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
+;alertmanager_config_poll_interval = 60s
+
+# Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port. The default value is `0.0.0.0:9094`.
+;ha_listen_address = "0.0.0.0:9094"
+
+# Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port. The default value is `0.0.0.0:9094`.
+;ha_advertise_address = ""
+
+# Comma-separated list of initial instances (in a format of host:port) that will form the HA cluster. Configuring this setting will enable High Availability mode for alerting.
+;ha_peers = ""
+
+# Time to wait for an instance to send a notification via the Alertmanager. In HA, each Grafana instance will
+# be assigned a position (e.g. 0, 1). We then multiply this position with the timeout to indicate how long should
+# each instance wait before sending the notification to take into account replication lag.
+# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
+;ha_peer_timeout = "15s"
+
+# The interval between sending gossip messages. By lowering this value (more frequent) gossip messages are propagated
+# across cluster more quickly at the expense of increased bandwidth usage.
+# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
+;ha_gossip_interval = "200ms"
+
+# The interval between gossip full state syncs. Setting this interval lower (more frequent) will increase convergence speeds
+# across larger clusters at the expense of increased bandwidth usage.
+# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
+;ha_push_pull_interval = "60s"
+
+# Enable or disable alerting rule execution. The alerting UI remains visible. This option has a legacy version in the `[alerting]` section that takes precedence.
+;execute_alerts = true
+
+# Alert evaluation timeout when fetching data from the datasource. This option has a legacy version in the `[alerting]` section that takes precedence.
+# The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
+;evaluation_timeout = 30s
+
+# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. This option has a legacy version in the `[alerting]` section that takes precedence.
+;max_attempts = 3
+
+# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
+# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
+;min_interval = 10s
+
+#################################### Alerting ############################
+[alerting]
+# Disable legacy alerting engine & UI features
+;enabled = false
+
+# Makes it possible to turn off alert execution but alerting UI is visible
+;execute_alerts = true
+
+# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
+;error_or_timeout = alerting
+
+# Default setting for how Grafana handles nodata or null values in alerting. (alerting, no_data, keep_state, ok)
+;nodata_or_nullvalues = no_data
+
+# Alert notifications can include images, but rendering many images at the same time can overload the server
+# This limit will protect the server from render overloading and make sure notifications are sent out quickly
+;concurrent_render_limit = 5
+
+# Default setting for alert calculation timeout. Default value is 30
+;evaluation_timeout_seconds = 30
+
+# Default setting for alert notification timeout. Default value is 30
+;notification_timeout_seconds = 30
+
+# Default setting for max attempts to sending alert notifications. Default value is 3
+;max_attempts = 3
+
+# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
+;min_interval_seconds = 1
+
+# Configures for how long alert annotations are stored. Default is 0, which keeps them forever.
+# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
+;max_annotation_age =
+
+# Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
+;max_annotations_to_keep =
+
+#################################### Annotations #########################
+[annotations]
+# Configures the batch size for the annotation clean-up job. This setting is used for dashboard, API, and alert annotations.
+;cleanupjob_batchsize = 100
+
+[annotations.dashboard]
+# Dashboard annotations means that annotations are associated with the dashboard they are created on.
+
+# Configures how long dashboard annotations are stored. Default is 0, which keeps them forever.
+# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
+;max_age =
+
+# Configures max number of dashboard annotations that Grafana stores. Default value is 0, which keeps all dashboard annotations.
+;max_annotations_to_keep =
+
+[annotations.api]
+# API annotations means that the annotations have been created using the API without any
+# association with a dashboard.
+
+# Configures how long Grafana stores API annotations. Default is 0, which keeps them forever.
+# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
+;max_age =
+
+# Configures max number of API annotations that Grafana keeps. Default value is 0, which keeps all API annotations.
+;max_annotations_to_keep =
+
+#################################### Explore #############################
+[explore]
+# Enable the Explore section
+;enabled = true
+
+#################################### Internal Grafana Metrics ##########################
+# Metrics available at HTTP API Url /metrics
+[metrics]
+# Disable / Enable internal metrics
+;enabled = true
+# Graphite Publish interval
+;interval_seconds = 10
+# Disable total stats (stat_totals_*) metrics to be generated
+;disable_total_stats = false
+
+#If both are set, basic auth will be required for the metrics endpoint.
+; basic_auth_username =
+; basic_auth_password =
+
+# Metrics environment info adds dimensions to the `grafana_environment_info` metric, which
+# can expose more information about the Grafana instance.
+[metrics.environment_info]
+#exampleLabel1 = exampleValue1
+#exampleLabel2 = exampleValue2
+
+# Send internal metrics to Graphite
+[metrics.graphite]
+# Enable by setting the address setting (ex localhost:2003)
+;address =
+;prefix = prod.grafana.%(instance_name)s.
+
+#################################### Grafana.com integration ##########################
+# Url used to import dashboards directly from Grafana.com
+[grafana_com]
+;url = https://grafana.com
+
+#################################### 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
+# sampling_server_url is the URL of a sampling manager providing a sampling strategy.
+;sampling_server_url =
+# Whether or not to use Zipkin propagation (x-b3- HTTP headers).
+;zipkin_propagation = false
+# Setting this to true disables shared RPC spans.
+# Not disabling is the most common setting when using Zipkin elsewhere in your infrastructure.
+;disable_shared_zipkin_spans = false
+
+#################################### 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]
+;endpoint =
+;path_style_access =
+;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
+
+[rendering]
+# Options to configure a remote HTTP image rendering service, e.g. using https://github.com/grafana/grafana-image-renderer.
+# URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service.
+;server_url =
+# If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/.
+;callback_url =
+# Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server,
+# which this setting can help protect against by only allowing a certain amount of concurrent requests.
+;concurrent_render_request_limit = 30
+
+[panels]
+# If set to true Grafana will allow script tags in text panels. Not recommended as it enable XSS vulnerabilities.
+;disable_sanitize_html = false
+
+[plugins]
+;enable_alpha = false
+;app_tls_skip_verify_insecure = false
+# Enter a comma-separated list of plugin identifiers to identify plugins to load even if they are unsigned. Plugins with modified signatures are never loaded.
+;allow_loading_unsigned_plugins =
+# Enable or disable installing / uninstalling / updating plugins directly from within Grafana.
+;plugin_admin_enabled = false
+;plugin_admin_external_manage_enabled = false
+;plugin_catalog_url = https://grafana.com/grafana/plugins/
+# Enter a comma-separated list of plugin identifiers to hide in the plugin catalog.
+;plugin_catalog_hidden_plugins =
+
+#################################### Grafana Live ##########################################
+[live]
+# max_connections to Grafana Live WebSocket endpoint per Grafana server instance. See Grafana Live docs
+# if you are planning to make it higher than default 100 since this can require some OS and infrastructure
+# tuning. 0 disables Live, -1 means unlimited connections.
+;max_connections = 100
+
+# allowed_origins is a comma-separated list of origins that can establish connection with Grafana Live.
+# If not set then origin will be matched over root_url. Supports wildcard symbol "*".
+;allowed_origins =
+
+# engine defines an HA (high availability) engine to use for Grafana Live. By default no engine used - in
+# this case Live features work only on a single Grafana server. Available options: "redis".
+# Setting ha_engine is an EXPERIMENTAL feature.
+;ha_engine =
+
+# ha_engine_address sets a connection address for Live HA engine. Depending on engine type address format can differ.
+# For now we only support Redis connection address in "host:port" format.
+# This option is EXPERIMENTAL.
+;ha_engine_address = "127.0.0.1:6379"
+
+#################################### Grafana Image Renderer Plugin ##########################
+[plugin.grafana-image-renderer]
+# Instruct headless browser instance to use a default timezone when not provided by Grafana, e.g. when rendering panel image of alert.
+# See ICU’s metaZones.txt (https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt) for a list of supported
+# timezone IDs. Fallbacks to TZ environment variable if not set.
+;rendering_timezone =
+
+# Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert.
+# Please refer to the HTTP header Accept-Language to understand how to format this value, e.g. 'fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5'.
+;rendering_language =
+
+# Instruct headless browser instance to use a default device scale factor when not provided by Grafana, e.g. when rendering panel image of alert.
+# Default is 1. Using a higher value will produce more detailed images (higher DPI), but will require more disk space to store an image.
+;rendering_viewport_device_scale_factor =
+
+# Instruct headless browser instance whether to ignore HTTPS errors during navigation. Per default HTTPS errors are not ignored. Due to
+# the security risk it's not recommended to ignore HTTPS errors.
+;rendering_ignore_https_errors =
+
+# Instruct headless browser instance whether to capture and log verbose information when rendering an image. Default is false and will
+# only capture and log error messages. When enabled, debug messages are captured and logged as well.
+# For the verbose information to be included in the Grafana server log you have to adjust the rendering log level to debug, configure
+# [log].filter = rendering:debug.
+;rendering_verbose_logging =
+
+# Instruct headless browser instance whether to output its debug and error messages into running process of remote rendering service.
+# Default is false. This can be useful to enable (true) when troubleshooting.
+;rendering_dumpio =
+
+# Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found
+# here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character.
+;rendering_args =
+
+# You can configure the plugin to use a different browser binary instead of the pre-packaged version of Chromium.
+# Please note that this is not recommended, since you may encounter problems if the installed version of Chrome/Chromium is not
+# compatible with the plugin.
+;rendering_chrome_bin =
+
+# Instruct how headless browser instances are created. Default is 'default' and will create a new browser instance on each request.
+# Mode 'clustered' will make sure that only a maximum of browsers/incognito pages can execute concurrently.
+# Mode 'reusable' will have one browser instance and will create a new incognito page on each request.
+;rendering_mode =
+
+# When rendering_mode = clustered, you can instruct how many browsers or incognito pages can execute concurrently. Default is 'browser'
+# and will cluster using browser instances.
+# Mode 'context' will cluster using incognito pages.
+;rendering_clustering_mode =
+# When rendering_mode = clustered, you can define the maximum number of browser instances/incognito pages that can execute concurrently. Default is '5'.
+;rendering_clustering_max_concurrency =
+# When rendering_mode = clustered, you can specify the duration a rendering request can take before it will time out. Default is `30` seconds.
+;rendering_clustering_timeout =
+
+# Limit the maximum viewport width, height and device scale factor that can be requested.
+;rendering_viewport_max_width =
+;rendering_viewport_max_height =
+;rendering_viewport_max_device_scale_factor =
+
+# Change the listening host and port of the gRPC server. Default host is 127.0.0.1 and default port is 0 and will automatically assign
+# a port not in use.
+;grpc_host =
+;grpc_port =
+
+[enterprise]
+# Path to a valid Grafana Enterprise license.jwt file
+;license_path =
+
+[feature_toggles]
+# enable features, separated by spaces
+;enable =
+
+[date_formats]
+# For information on what formatting patterns that are supported https://momentjs.com/docs/#/displaying/
+
+# Default system date format used in time range picker and other places where full time is displayed
+;full_date = YYYY-MM-DD HH:mm:ss
+
+# Used by graph and other places where we only show small intervals
+;interval_second = HH:mm:ss
+;interval_minute = HH:mm
+;interval_hour = MM/DD HH:mm
+;interval_day = MM/DD
+;interval_month = YYYY-MM
+;interval_year = YYYY
+
+# Experimental feature
+;use_browser_locale = false
+
+# Default timezone for user preferences. Options are 'browser' for the browser local timezone or a timezone name from IANA Time Zone database, e.g. 'UTC' or 'Europe/Amsterdam' etc.
+;default_timezone = browser
+
+[expressions]
+# Enable or disable the expressions functionality.
+;enabled = true
+
+[geomap]
+# Set the JSON configuration for the default basemap
+;default_baselayer_config = `{
+; "type": "xyz",
+; "config": {
+; "attribution": "Open street map",
+; "url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
+; }
+;}`
+
+# Enable or disable loading other base map layers
+;enable_custom_baselayers = true
diff --git a/nginx/sites-enabled/PowerStationMonitor.conf b/nginx/sites-enabled/PowerStationMonitor.conf
new file mode 100644
index 0000000..4e7ef62
--- /dev/null
+++ b/nginx/sites-enabled/PowerStationMonitor.conf
@@ -0,0 +1,75 @@
+map $http_upgrade $connection_upgrade {
+ default upgrade;
+ '' close;
+}
+
+server {
+ listen 80;
+ #root /usr/share/nginx/html;
+ #index index.html index.htm;
+
+ add_header 'Access-Control-Allow-Origin' '*' always;
+ add_header 'Access-Control-Allow_Credentials' 'true' always;
+ 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' always;
+ add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH' always;
+ add_header X-Frame-Options SAMEORIGIN;
+ location / {
+ proxy_pass http://localhost:8080/basicui/app/;
+ 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;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "Upgrade";
+ proxy_read_timeout 3600;
+ }
+
+ location /mdl {
+ proxy_pass http://localhost:8080/basicui/mdl;
+ }
+ location /roboto.css {
+ proxy_pass http://localhost:8080/basicui/roboto.css;
+ }
+ location /material-icons.css {
+ proxy_pass http://localhost:8080/basicui/material-icons.css;
+ }
+ location /smarthome.css {
+ proxy_pass http://localhost:8080/basicui/smarthome.css;
+ }
+ location /smarthome.js {
+ proxy_pass http://localhost:8080/basicui/smarthome.js;
+ }
+ location /icon {
+ proxy_pass http://localhost:8080/icon;
+ }
+ location /rest {
+ proxy_pass http://localhost:8080/rest;
+ 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;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "Upgrade";
+ }
+ location /fonts {
+ proxy_pass http://localhost:8080/basicui/fonts;
+ }
+ location /images {
+ proxy_pass http://localhost:8080/basicui/images;
+ }
+
+ location /grafana/ {
+ proxy_pass http://localhost:3000/;
+ proxy_set_header Host $host;
+ }
+
+ # Proxy Grafana Live WebSocket connections.
+ location /grafana/api/live {
+ rewrite ^/grafana/(.*) /$1 break;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ proxy_set_header Host $http_host;
+ proxy_pass http://localhost:3000/;
+ }
+}
diff --git a/nodered/Kunkin Control.json b/nodered/Kunkin Control.json
new file mode 100644
index 0000000..72cab77
--- /dev/null
+++ b/nodered/Kunkin Control.json
@@ -0,0 +1 @@
+[{"id":"3abae06a.2b9bd","type":"tab","label":"Kunkin KP184 Read and control","disabled":false,"info":"Read all Measurements from Kunkin KP184 and sends it to OpenHAB for Visualization.\n\nSetpoints from OpenHAB are sent to DC Load too.\n\nSerialports Settings\n\nBaud 115200\nDevice Adresse No.1\n\nDevice Adresse is statically because there is only one device present."},{"id":"a9ac179f.b9206","type":"inject","z":"3abae06a.2b9bd","name":"Poll Status","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"0.1","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":160,"wires":[["bc96a0a7.bf0438"]]},{"id":"f1d835ce.811","type":"function","z":"3abae06a.2b9bd","name":"CRC","func":"let data = Buffer.from(msg.payload);\n\nlet crc = 0xffff;\n\nfor (let i = 0; i < data.length; ++i) {\n crc ^= data[i];\n for (let j = 0; j < 8; ++j) {\n xor = 0;\n if ((crc & 1) != 0) {\n xor = 0xa001;\n }\n crc = (crc >> 1) ^ xor;\n }\n}\n\ndata = Buffer.concat([data, Buffer.alloc(2)])\n\ndata.writeUInt16BE(crc, data.length - 2);\n\nmsg.payload = data;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":160,"wires":[["1e06e235.3d76e6"]]},{"id":"1e06e235.3d76e6","type":"serial request","z":"3abae06a.2b9bd","name":"","serial":"eed39e04.d91888","x":900,"y":160,"wires":[["86acc9ab.9d9398"]]},{"id":"86acc9ab.9d9398","type":"function","z":"3abae06a.2b9bd","name":"Calc V, A","func":"if (msg.payload[1] == 3 && msg.payload[2] == 30) {\n var voltage = {payload: (msg.payload[5] << 8 | msg.payload[6] << 8 | msg.payload[7]) / 1000};\n var current = {payload: (msg.payload[8] << 8 | msg.payload[9] << 8 | msg.payload[10]) / 1000};\n //var on = {payload: (msg.payload[3] & 0b10000000) >> 0}; // is true if on flag is set\n //var mode = {payload: (msg.payload[3] & 0b01100000) >> 5};\n var data = {payload: msg.payload}; //Data passthrough\n}\n\n\nreturn [voltage, current/*, on, mode*/, data];","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1080,"y":220,"wires":[["b1bf4dc6.7b854"],["746fa2cb.fef98c"],["207bd04d.7de5a"]]},{"id":"93d0b500.156ed8","type":"openhab-v2-out","z":"3abae06a.2b9bd","name":"","controller":"d8ac56fb.00594","item":"DC_Load_Voltage","topic":"ItemUpdate","topicType":"ohCommandType","payload":"payload","payloadType":"msg","allowItemOverride":false,"x":1810,"y":160,"wires":[]},{"id":"d90d4a9c.f0c9b","type":"openhab-v2-out","z":"3abae06a.2b9bd","name":"","controller":"d8ac56fb.00594","item":"DC_Load_Current","topic":"ItemUpdate","topicType":"ohCommandType","payload":"payload","payloadType":"msg","allowItemOverride":false,"x":1810,"y":220,"wires":[]},{"id":"bc96a0a7.bf0438","type":"function","z":"3abae06a.2b9bd","name":"Request Status","func":"msg.payload = [0x01, 0x03, 0x03, 0x00, 0x00, 0x00]\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":160,"wires":[["f1d835ce.811"]]},{"id":"bc1e6987.c25368","type":"openhab-v2-out","z":"3abae06a.2b9bd","name":"","controller":"d8ac56fb.00594","item":"DC_Load_Mode","topic":"ItemUpdate","topicType":"ohCommandType","payload":"payload","payloadType":"msg","allowItemOverride":false,"x":1800,"y":340,"wires":[]},{"id":"190fa8b8.4bf09f","type":"openhab-v2-out","z":"3abae06a.2b9bd","name":"","controller":"d8ac56fb.00594","item":"DC_Load_OnOff","topic":"ItemUpdate","topicType":"ohCommandType","payload":"payload","payloadType":"msg","allowItemOverride":false,"x":1810,"y":280,"wires":[]},{"id":"207bd04d.7de5a","type":"buffer-parser","z":"3abae06a.2b9bd","name":"Parse States","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"bool","name":"OnOff","offset":3,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"bool","name":"Mode1","offset":3,"length":1,"offsetbit":1,"scale":"1","mask":""},{"type":"bool","name":"Mode2","offset":3,"length":1,"offsetbit":2,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":1270,"y":300,"wires":[["69b8751e.df97f4","d720fa49.d36118"]]},{"id":"69b8751e.df97f4","type":"function","z":"3abae06a.2b9bd","name":"Parse Mode","func":"msg.payload = msg.payload.Mode2 << 1 | msg.payload.Mode1;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1450,"y":340,"wires":[["c258d68.127ce28"]]},{"id":"d720fa49.d36118","type":"function","z":"3abae06a.2b9bd","name":"Modify OnOff","func":"if (msg.payload.OnOff == false) {\n msg.payload = \"OFF\";\n}\nif (msg.payload.OnOff == true) {\n msg.payload = \"ON\";\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1450,"y":280,"wires":[["166796f3.15e381"]]},{"id":"9ab3f7fd.76f97","type":"function","z":"3abae06a.2b9bd","name":"Set On Off","func":"if (msg.payload.state == \"ON\") {\n msg.payload = [0x01, 0x06, 0x01, 0x0E, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x01];\n}\n\nif (msg.payload.state == \"OFF\") {\n msg.payload = [0x01, 0x06, 0x01, 0x0E, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00];\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":220,"wires":[["f1d835ce.811"]]},{"id":"639e19a5.cf4fb","type":"openhab-v2-in","z":"3abae06a.2b9bd","outputs":1,"name":"DC Load Set On Off","controller":"d8ac56fb.00594","items":["DC_Load_Set_OnOff"],"eventTypes":["ItemCommandEvent"],"ohTimestamp":false,"enableOutput":true,"initialOutput":false,"storeState":false,"storeStateVariable":"","storeStateVariableType":"flow","x":130,"y":220,"wires":[["9ab3f7fd.76f97"]]},{"id":"b316e7d2.bbfa7","type":"openhab-v2-in","z":"3abae06a.2b9bd","outputs":1,"name":"DC Load Set Voltage","controller":"d8ac56fb.00594","items":["DC_Load_Set_Voltage"],"eventTypes":["ItemCommandEvent"],"ohTimestamp":false,"enableOutput":true,"initialOutput":false,"storeState":false,"storeStateVariable":"","storeStateVariableType":"flow","x":120,"y":280,"wires":[["476c134b.3992ec"]]},{"id":"6d60840e.ee251c","type":"openhab-v2-in","z":"3abae06a.2b9bd","outputs":1,"name":"DC Load Set Current","controller":"d8ac56fb.00594","items":["DC_Load_Set_Current"],"eventTypes":["ItemCommandEvent"],"ohTimestamp":false,"enableOutput":true,"initialOutput":false,"storeState":false,"storeStateVariable":"","storeStateVariableType":"flow","x":120,"y":340,"wires":[["ee6a1539.afb0b8"]]},{"id":"e74644d8.d28d5","type":"function","z":"3abae06a.2b9bd","name":"Set Current","func":"msg.payload = [0x01, 0x06, 0x01, 0x16, 0x00, 0x01, 0x04, 0x00, 0x00, msg.payload[0], msg.payload[1]];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":340,"wires":[["f1d835ce.811"]]},{"id":"ee6a1539.afb0b8","type":"function","z":"3abae06a.2b9bd","name":"Dec to Hex","func":"const hexchars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];\nlet val = msg.payload.state * 1000;\nlet answer = \"\";\nlet size = 4;\nwhile (size--) {\n answer = hexchars[val & 0xF] + answer;\n val = val >> 4;\n}\n\nmsg.payload = Buffer.from(answer, \"hex\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":340,"wires":[["e74644d8.d28d5"]]},{"id":"476c134b.3992ec","type":"function","z":"3abae06a.2b9bd","name":"Dec to Hex","func":"const hexchars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];\nlet val = msg.payload.state * 1000;\nlet answer = \"\";\nlet size = 4;\nwhile (size--) {\n answer = hexchars[val & 0xF] + answer;\n val = val >> 4;\n}\n\nmsg.payload = Buffer.from(answer, \"hex\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":280,"wires":[["747ef8d2.c1e61"]]},{"id":"747ef8d2.c1e61","type":"function","z":"3abae06a.2b9bd","name":"Set Voltage","func":"msg.payload = [0x01, 0x06, 0x01, 0x12, 0x00, 0x01, 0x04, 0x00, 0x00, msg.payload[0], msg.payload[1]];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":280,"wires":[["f1d835ce.811"]]},{"id":"5f2912ef.24cb0c","type":"openhab-v2-in","z":"3abae06a.2b9bd","outputs":1,"name":"DC Load Set Mode","controller":"d8ac56fb.00594","items":["DC_Load_Set_Mode"],"eventTypes":["ItemCommandEvent"],"ohTimestamp":false,"enableOutput":true,"initialOutput":false,"storeState":false,"storeStateVariable":"","storeStateVariableType":"flow","x":130,"y":400,"wires":[["7c6aab39.bdf55c"]]},{"id":"7c6aab39.bdf55c","type":"function","z":"3abae06a.2b9bd","name":"Dec to Hex","func":"const hexchars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];\nlet val = msg.payload.state;\nlet answer = \"\";\nlet size = 2;\nwhile (size--) {\n answer = hexchars[val & 0xF] + answer;\n val = val >> 4;\n}\n\nmsg.payload = Buffer.from(answer, \"hex\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":400,"wires":[["9a21acc0.92cee8"]]},{"id":"9a21acc0.92cee8","type":"function","z":"3abae06a.2b9bd","name":"Set Mode","func":"msg.payload = [0x01, 0x06, 0x01, 0x10, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, msg.payload[0]];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":400,"wires":[["f1d835ce.811"]]},{"id":"b1bf4dc6.7b854","type":"rbe","z":"3abae06a.2b9bd","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","x":1630,"y":160,"wires":[["93d0b500.156ed8"]]},{"id":"746fa2cb.fef98c","type":"rbe","z":"3abae06a.2b9bd","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","x":1630,"y":220,"wires":[["d90d4a9c.f0c9b"]]},{"id":"166796f3.15e381","type":"rbe","z":"3abae06a.2b9bd","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","x":1630,"y":280,"wires":[["190fa8b8.4bf09f"]]},{"id":"c258d68.127ce28","type":"rbe","z":"3abae06a.2b9bd","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","x":1630,"y":340,"wires":[["bc1e6987.c25368"]]},{"id":"e20619df.041eb","type":"openhab-v2-in","z":"3abae06a.2b9bd","outputs":1,"name":"DC Load Set Power","controller":"d8ac56fb.00594","items":["DC_Load_Set_Power"],"eventTypes":["ItemCommandEvent"],"ohTimestamp":false,"enableOutput":true,"initialOutput":false,"storeState":false,"storeStateVariable":"","storeStateVariableType":"flow","x":130,"y":460,"wires":[["db9f6789.5da5c8"]]},{"id":"f0d87268.e79c6","type":"openhab-v2-in","z":"3abae06a.2b9bd","outputs":1,"name":"DC Load Set Resistance","controller":"d8ac56fb.00594","items":["DC_Load_Set_Resistance"],"eventTypes":["ItemCommandEvent"],"ohTimestamp":false,"enableOutput":true,"initialOutput":false,"storeState":false,"storeStateVariable":"","storeStateVariableType":"flow","x":110,"y":520,"wires":[["f8d1df9a.68d8e"]]},{"id":"db9f6789.5da5c8","type":"function","z":"3abae06a.2b9bd","name":"Dec to Hex","func":"const hexchars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];\nlet val = msg.payload.state * 100;\nlet answer = \"\";\nlet size = 4;\nwhile (size--) {\n answer = hexchars[val & 0xF] + answer;\n val = val >> 4;\n}\n\nmsg.payload = Buffer.from(answer, \"hex\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":460,"wires":[["60ad1a5c.f5b88c"]]},{"id":"f8d1df9a.68d8e","type":"function","z":"3abae06a.2b9bd","name":"Dec to Hex","func":"const hexchars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];\nlet val = msg.payload.state * 10;\nlet answer = \"\";\nlet size = 4;\nwhile (size--) {\n answer = hexchars[val & 0xF] + answer;\n val = val >> 4;\n}\n\nmsg.payload = Buffer.from(answer, \"hex\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":520,"wires":[["cb6b24ab.8cc53"]]},{"id":"60ad1a5c.f5b88c","type":"function","z":"3abae06a.2b9bd","name":"Set Power","func":"msg.payload = [0x01, 0x06, 0x01, 0x1E, 0x00, 0x01, 0x04, 0x00, 0x00, msg.payload[0], msg.payload[1]];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":460,"wires":[["f1d835ce.811"]]},{"id":"cb6b24ab.8cc53","type":"function","z":"3abae06a.2b9bd","name":"Set Resistance","func":"msg.payload = [0x01, 0x06, 0x01, 0x1A, 0x00, 0x01, 0x04, 0x00, 0x00, msg.payload[0], msg.payload[1]];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":520,"wires":[["f1d835ce.811"]]},{"id":"eed39e04.d91888","type":"serial-port","serialport":"/dev/ttyDCLoad","serialbaud":"115200","databits":"8","parity":"none","stopbits":"1","waitfor":"0x01","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"25","bin":"bin","out":"time","addchar":"","responsetimeout":"30"},{"id":"d8ac56fb.00594","type":"openhab-v2-controller","name":"","protocol":"http","ignoreInvalidCertificate":true,"host":"localhost","port":"8080"}]
\ No newline at end of file
diff --git a/openhab2/html/index.html b/openhab2/html/index.html
new file mode 100644
index 0000000..58ba0e9
--- /dev/null
+++ b/openhab2/html/index.html
@@ -0,0 +1,5 @@
+
+openHAB user provided static content
+Serve your own static html pages or resources from here. Files stored in the openHAB configuration subfolder html will be available through the HTTP server of openHAB, e.g. http://device-address:8080/static/image.png.
+Resources for sitemap elements (image, video,...) can also be provided though this folder.
+
diff --git a/openhab2/html/readme.txt b/openhab2/html/readme.txt
new file mode 100644
index 0000000..5eeeb99
--- /dev/null
+++ b/openhab2/html/readme.txt
@@ -0,0 +1,3 @@
+Serve your own static html pages or resources from here.
+Files stored in this folder will be available through the HTTP server of openHAB, e.g. "http://device-address:8080/static/image.png".
+Resources for sitemap elements (image, video,...) can also be provided though this folder.
diff --git a/openhab2/icons/classic/batterycharger.png b/openhab2/icons/classic/batterycharger.png
new file mode 100644
index 0000000..ea7ae86
Binary files /dev/null and b/openhab2/icons/classic/batterycharger.png differ
diff --git a/openhab2/icons/classic/current.png b/openhab2/icons/classic/current.png
new file mode 100644
index 0000000..8c3ae95
Binary files /dev/null and b/openhab2/icons/classic/current.png differ
diff --git a/openhab2/icons/classic/electric_ah.png b/openhab2/icons/classic/electric_ah.png
new file mode 100644
index 0000000..07f101b
Binary files /dev/null and b/openhab2/icons/classic/electric_ah.png differ
diff --git a/openhab2/icons/classic/electric_wh.png b/openhab2/icons/classic/electric_wh.png
new file mode 100644
index 0000000..5583628
Binary files /dev/null and b/openhab2/icons/classic/electric_wh.png differ
diff --git a/openhab2/icons/classic/input_voltage.png b/openhab2/icons/classic/input_voltage.png
new file mode 100644
index 0000000..7dca483
Binary files /dev/null and b/openhab2/icons/classic/input_voltage.png differ
diff --git a/openhab2/icons/classic/mode.png b/openhab2/icons/classic/mode.png
new file mode 100644
index 0000000..0b6a50c
Binary files /dev/null and b/openhab2/icons/classic/mode.png differ
diff --git a/openhab2/icons/classic/power.png b/openhab2/icons/classic/power.png
new file mode 100644
index 0000000..5e871ec
Binary files /dev/null and b/openhab2/icons/classic/power.png differ
diff --git a/openhab2/icons/classic/quick_select.png b/openhab2/icons/classic/quick_select.png
new file mode 100644
index 0000000..b148ddc
Binary files /dev/null and b/openhab2/icons/classic/quick_select.png differ
diff --git a/openhab2/icons/classic/readme.txt b/openhab2/icons/classic/readme.txt
new file mode 100644
index 0000000..7fc793f
--- /dev/null
+++ b/openhab2/icons/classic/readme.txt
@@ -0,0 +1,6 @@
+Your additional icons go here.
+Icons can be provided as png (32x32) or preferably as svg files.
+ClassicUI and BasicUI can be configured to accept svg (default) or png icons.
+
+Check out the openHAB documentation for more details:
+https://www.openhab.org/docs/configuration/items.html#icons
diff --git a/openhab2/icons/classic/reset.png b/openhab2/icons/classic/reset.png
new file mode 100644
index 0000000..646ac60
Binary files /dev/null and b/openhab2/icons/classic/reset.png differ
diff --git a/openhab2/icons/classic/sicherheitsschaltung.png b/openhab2/icons/classic/sicherheitsschaltung.png
new file mode 100644
index 0000000..2f85d0d
Binary files /dev/null and b/openhab2/icons/classic/sicherheitsschaltung.png differ
diff --git a/openhab2/icons/classic/timer.png b/openhab2/icons/classic/timer.png
new file mode 100644
index 0000000..055c329
Binary files /dev/null and b/openhab2/icons/classic/timer.png differ
diff --git a/openhab2/icons/classic/voltage.png b/openhab2/icons/classic/voltage.png
new file mode 100644
index 0000000..7797e16
Binary files /dev/null and b/openhab2/icons/classic/voltage.png differ
diff --git a/openhab2/items/dc_load.items b/openhab2/items/dc_load.items
new file mode 100644
index 0000000..c858457
--- /dev/null
+++ b/openhab2/items/dc_load.items
@@ -0,0 +1,22 @@
+Group gDC_Load "DC Elektronische Last, Kunkin KP184, 150V 40A 400W"
+
+Number DC_Load_Voltage "Spannung [%.3f V]" (gDC_Load)
+Number DC_Load_Current "Strom [%.3f A]" (gDC_Load)
+Switch DC_Load_OnOff "Eingang [MAP(dc_load_EinAus.map):%s]" (gDC_Load)
+Number DC_Load_Mode "Modus [MAP(dc_load_mode.map):%s]" (gDC_Load)
+Number DC_Load_Power "Leistung [%.2f W]" (gDC_Load)
+Number DC_Load_Watthours "Wattstunden [%.3f Wh]" (gDC_Load)
+Number DC_Load_Amperehours "Amperestunden [%.3f Ah]" (gDC_Load)
+
+Switch DC_Load_Set_OnOff "Lasteingang schalten" (gDC_Load)
+Number DC_Load_Set_Voltage "Spannungs Sollwert [%.3f V]" (gDC_Load)
+Number DC_Load_Set_Current "Strom Sollwert [%.3f A]" (gDC_Load)
+Number DC_Load_Set_Resistance "Widerstand Sollwert [%.1f Ohm]" (gDC_Load)
+Number DC_Load_Set_Power "Leistungs Sollwert [%.1f W]" (gDC_Load)
+Number DC_Load_Set_Mode "Modus [MAP(dc_load_mode.map):%s]" (gDC_Load)
+Switch DC_Load_Set_Reset "Zähler zurücksetzen" (gDC_Load)
+
+Switch DC_Load_Set_BattMode "Akku entladen" (gDC_Load)
+Number DC_Load_Set_Batt_MinVoltage "Entladeschlussspannung [%.3f V]" (gDC_Load)
+
+Number DC_Load_Timer "Timer [%.0f s]" (gDC_Load)
\ No newline at end of file
diff --git a/openhab2/items/dc_supply.items b/openhab2/items/dc_supply.items
new file mode 100644
index 0000000..1f54de3
--- /dev/null
+++ b/openhab2/items/dc_supply.items
@@ -0,0 +1,23 @@
+Group gDC_Supply "DC Labornetzgerät, Riden RD6018, 60V 18A"
+
+Number DC_Supply_Voltage "Spannung [%.2f V]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_main:voltage_actual:number", expire="1m,0"}
+Number DC_Supply_Current "Strom [%.2f A]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_main:current_actual:number", expire="1m,0"}
+Number DC_Supply_Input_Voltage "Eingangsspannung [%.2f V]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_main:voltage_input:number", expire="1m,0"}
+Number DC_Supply_Protection "Sicherheitsabschaltung [MAP(dc_supply_protection.map):%s]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_main:protection:number", expire="1m,0"}
+Number DC_Supply_Amperehours "Amperestunden [%.3f Ah]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_sec:ampere_hours:number", expire="1m,0"}
+Number DC_Supply_Watthours "Wattstunden [%.3f Wh]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_sec:watt_hours:number", expire="1m,0"}
+Number DC_Supply_Power "Leistung [%.1f W]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_main:power:number", expire="1m,0"}
+Number DC_Supply_Mode "Modus [MAP(dc_supply_mode.map):%s]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_main:mode:number", expire="1m,0"}
+
+Number DC_Supply_Voltage_Setpoint "Spannungs Sollwert [%.2f V]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_main:voltage_setpoint:number", expire="1m,0"}
+Number DC_Supply_Current_Setpoint "Strom Sollwert [%.2f A]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_main:current_setpoint:number", expire="1m,0"}
+Number DC_Supply_PowerOnOff "Lastausgang schalten" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_main:output_enable:number", expire="1m,0"}
+
+Number DC_Supply_Temp_Internal "Temperatur Intern [%.0f °C]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_main:temperature_internal:number", expire="1m,0"}
+Number DC_Supply_Temp_External "Temperatur Extern [%.0f °C]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_sec:temperature_external:number", expire="1m,0"}
+Number DC_Supply_Temp_External_Active (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_sec:temperature_external_active:number", expire="1m,0"}
+
+Number DC_Supply_Batt_Active "Batterielademodus [MAP(dc_supply_battmode.map):%s]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_sec:battery_mode_active:number", expire="1m,0"}
+Number DC_Supply_Batt_Voltage "Batteriespannung [%.2f V]" (gDC_Supply) {channel="modbus:data:dcsupply:dcsupply_sec:voltage_battery:number", expire="1m,0"}
+Number DC_Supply_Timer "Timer [%.0f s]" (gDC_Supply)
+Switch DC_Supply_Set_Reset "Zähler zurücksetzen" (gDC_Supply)
\ No newline at end of file
diff --git a/openhab2/items/readme.txt b/openhab2/items/readme.txt
new file mode 100644
index 0000000..b214510
--- /dev/null
+++ b/openhab2/items/readme.txt
@@ -0,0 +1,5 @@
+Your item definitions go here.
+All items files have to have the ".items" file extension and must follow a special syntax.
+
+Check out the openHAB documentation for more details:
+https://www.openhab.org/docs/configuration/items.html
diff --git a/openhab2/persistence/influxdb.persist b/openhab2/persistence/influxdb.persist
new file mode 100644
index 0000000..61c2619
--- /dev/null
+++ b/openhab2/persistence/influxdb.persist
@@ -0,0 +1,12 @@
+Strategies {
+ everyHour : "0 0 * * * ?"
+ everyDay : "0 0 0 * * ?"
+ everySecond : "* * * ? * * *"
+ every1Min : "0 0/1 * 1/1 * ? *"
+ every10Sec : "*/10 * * ? * * *"
+ default = everyChange
+}
+
+//Items {
+// DC_Load_Power, DC_Load_Watthours, DC_Load_Amperehours : strategy = every1Min
+//}
\ No newline at end of file
diff --git a/openhab2/persistence/mapdb.persist b/openhab2/persistence/mapdb.persist
new file mode 100644
index 0000000..78512a4
--- /dev/null
+++ b/openhab2/persistence/mapdb.persist
@@ -0,0 +1,7 @@
+Strategies {
+ default = everyUpdate
+}
+
+Items {
+ * : strategy = everyChange, restoreOnStartup
+}
diff --git a/openhab2/persistence/readme.txt b/openhab2/persistence/readme.txt
new file mode 100644
index 0000000..b1df35b
--- /dev/null
+++ b/openhab2/persistence/readme.txt
@@ -0,0 +1,5 @@
+Your persistence configuration goes here.
+All persistence files have to have the ".persist" file extension and must follow a special syntax.
+
+Check out the openHAB documentation for more details:
+https://www.openhab.org/docs/configuration/persistence.html
diff --git a/openhab2/rules/convert_values_dcsupply.rules.unused b/openhab2/rules/convert_values_dcsupply.rules.unused
new file mode 100644
index 0000000..eeec1e6
--- /dev/null
+++ b/openhab2/rules/convert_values_dcsupply.rules.unused
@@ -0,0 +1,7 @@
+/*rule "Convert Voltage"
+when
+ Item DC_Supply_Voltage changed
+then
+ DC_Supply_Voltage.postUpdate(String::format("%1.2f",DC_Supply_Voltage.state as DecimalType / 10))
+end
+*/
\ No newline at end of file
diff --git a/openhab2/rules/dc_load_calc.rules b/openhab2/rules/dc_load_calc.rules
new file mode 100644
index 0000000..a35b564
--- /dev/null
+++ b/openhab2/rules/dc_load_calc.rules
@@ -0,0 +1,67 @@
+rule "Reset DC Load Ah Wh Timer"
+when
+ Item DC_Load_Set_Reset changed to ON
+then
+ DC_Load_Amperehours.sendCommand("0");
+ DC_Load_Watthours.sendCommand("0");
+ DC_Load_Timer.sendCommand("0");
+ DC_Load_Set_Reset.sendCommand("OFF");
+end
+
+rule "Calculate DC Load Timer"
+when
+ Time cron "* * * ? * * *"
+then
+ if (DC_Load_OnOff.state == ON) {
+ val temp = (DC_Load_Timer.state as Number) + 1;
+ DC_Load_Timer.sendCommand(temp);
+ }
+ if (DC_Load_Timer.state == NULL || DC_Load_Timer.state == "") {
+ DC_Load_Timer.sendCommand("0");
+ }
+end
+
+rule "Calculate DC Load Power"
+when
+ Item DC_Load_Voltage changed or Item DC_Load_Current changed
+then
+ val temp = (DC_Load_Voltage.state as Number) * (DC_Load_Current.state as Number);
+ DC_Load_Power.sendCommand(temp);
+end
+
+rule "Calculate DC Load Amperehours"
+when
+ Time cron "* * * ? * * *"
+then
+ if (DC_Load_OnOff.state == ON) {
+ val temp = (DC_Load_Current.state as Number) / 3600;
+ DC_Load_Amperehours.sendCommand(temp + (DC_Load_Amperehours.state as Number));
+ }
+ if (DC_Load_Amperehours.state == NULL || DC_Load_Amperehours.state == "") {
+ DC_Load_Amperehours.sendCommand("0");
+ }
+end
+
+rule "Calculate DC Load Watthours"
+when
+ Time cron "* * * ? * * *"
+then
+ if (DC_Load_OnOff.state == ON) {
+ val temp = (DC_Load_Power.state as Number) / 3600;
+ DC_Load_Watthours.sendCommand(temp + (DC_Load_Watthours.state as Number));
+ }
+ if (DC_Load_Watthours.state == NULL || DC_Load_Watthours.state == "") {
+ DC_Load_Watthours.sendCommand("0");
+ }
+end
+
+rule "Stop Battery Discharge"
+when
+ Item DC_Load_Voltage changed
+then
+ if (DC_Load_Set_BattMode.state == ON) {
+ if (DC_Load_Voltage.state < DC_Load_Set_Batt_MinVoltage.state) {
+ DC_Load_Set_OnOff.sendCommand("OFF");
+ }
+ }
+end
\ No newline at end of file
diff --git a/openhab2/rules/dc_load_history.rules b/openhab2/rules/dc_load_history.rules
new file mode 100644
index 0000000..19f1fef
--- /dev/null
+++ b/openhab2/rules/dc_load_history.rules
@@ -0,0 +1,12 @@
+rule "Send datavalues from DC Load to history if input is powered on"
+when
+ Time cron "*/10 * * ? * * *"
+then
+ if (DC_Load_OnOff.state == ON) {
+ DC_Load_Voltage.persist("influxdb")
+ DC_Load_Current.persist("influxdb")
+ DC_Load_Power.persist("influxdb")
+ DC_Load_Watthours.persist("influxdb")
+ DC_Load_Watthours.persist("influxdb")
+ }
+end
\ No newline at end of file
diff --git a/openhab2/rules/dc_supply_calc.rules b/openhab2/rules/dc_supply_calc.rules
new file mode 100644
index 0000000..eda6518
--- /dev/null
+++ b/openhab2/rules/dc_supply_calc.rules
@@ -0,0 +1,22 @@
+rule "Reset DC Supply Ah Wh Timer"
+when
+ Item DC_Supply_Set_Reset changed to ON
+then
+ DC_Load_Amperehours.sendCommand("0");
+ DC_Load_Watthours.sendCommand("0");
+ DC_Supply_Timer.sendCommand("0");
+ DC_Supply_Set_Reset.sendCommand("OFF");
+end
+
+rule "Calculate DC Supply Timer"
+when
+ Time cron "* * * ? * * *"
+then
+ if (DC_Supply_PowerOnOff.state == 1) {
+ val temp = (DC_Supply_Timer.state as Number) + 1;
+ DC_Supply_Timer.sendCommand(temp);
+ }
+ if (DC_Supply_Timer.state == NULL || DC_Supply_Timer.state == "") {
+ DC_Supply_Timer.sendCommand("0");
+ }
+end
\ No newline at end of file
diff --git a/openhab2/rules/dc_supply_history.rules b/openhab2/rules/dc_supply_history.rules
new file mode 100644
index 0000000..1c5f30c
--- /dev/null
+++ b/openhab2/rules/dc_supply_history.rules
@@ -0,0 +1,22 @@
+rule "Send datavalues from DC Supply to history if output is powered on"
+when
+ Time cron "*/10 * * ? * * *"
+then
+ if (DC_Supply_PowerOnOff.state == ON) {
+ DC_Supply_Voltage.persist("influxdb")
+ DC_Supply_Current.persist("influxdb")
+ DC_Supply_Power.persist("influxdb")
+ DC_Supply_Amperehours.persist("influxdb")
+ DC_Supply_Watthours.persist("influxdb")
+ DC_Supply_Temp_Internal.persist("influxdb")
+ }
+end
+
+rule "Send external temperature if connected to history"
+when
+ Time cron "*/10 * * ? * * *"
+then
+ if (DC_Supply_Temp_External_Active.state == ON) {
+ DC_Supply_Temp_External.persist("influxdb")
+ }
+end
\ No newline at end of file
diff --git a/openhab2/rules/readme.txt b/openhab2/rules/readme.txt
new file mode 100644
index 0000000..f7952e1
--- /dev/null
+++ b/openhab2/rules/readme.txt
@@ -0,0 +1,5 @@
+Your rules go here.
+All rule files have to have the ".rules" file extension and must follow a special syntax.
+
+Check out the openHAB documentation for more details:
+https://www.openhab.org/docs/configuration/rules-dsl.html
diff --git a/openhab2/scripts/readme.txt b/openhab2/scripts/readme.txt
new file mode 100644
index 0000000..0faff68
--- /dev/null
+++ b/openhab2/scripts/readme.txt
@@ -0,0 +1,5 @@
+Your scripts go here.
+All script files have to have the ".script" file extension and must follow a special syntax.
+
+Check out the openHAB documentation for more details:
+https://www.openhab.org/docs/configuration/rules-dsl.html#scripts
diff --git a/openhab2/services/addons.cfg b/openhab2/services/addons.cfg
new file mode 100644
index 0000000..a72c3ad
--- /dev/null
+++ b/openhab2/services/addons.cfg
@@ -0,0 +1,50 @@
+# The installation package of this openHAB instance
+# Note: This is only regarded at the VERY FIRST START of openHAB
+# Note: If you want to specify your add-ons yourself through entries below, set the package to "minimal"
+# as otherwise your definition might be in conflict with what the installation package defines.
+#
+# Optional. If not set, the dashboard (https://:8080/) will ask you to choose a package.
+#
+# Valid options:
+# - minimal : Installation only with dashboard, but no UIs or other add-ons. Use this for custom setups.
+# - simple : Setup for using openHAB purely through UIs - you need to expect MANY constraints in functionality!
+# - standard : Default setup for normal users, best for textual setup
+# - expert : Setup for expert users, especially for people migrating from openHAB 1.x
+# - demo : A demo setup which includes UIs, a few bindings, config files etc.
+#
+# See https://www.openhab.org/docs/configuration/packages.html for a detailed explanation of these packages.
+#
+#package = minimal
+
+# Access Remote Add-on Repository
+# Defines whether the remote openHAB add-on repository should be used for browsing and installing add-ons.
+# This not only makes latest snapshots of add-ons available, it is also required for the installation of
+# any legacy 1.x add-on. (default is true)
+#
+#remote = true
+
+# Include legacy 1.x bindings. If set to true, it also allows the installation of 1.x bindings for which there is
+# already a 2.x version available (requires remote repo access, see above). (default is false)
+#
+#legacy = true
+
+# A comma-separated list of bindings to install (e.g. "binding = sonos,knx,zwave")
+#binding =
+
+# A comma-separated list of UIs to install (e.g. "ui = basic,paper")
+#ui =
+
+# A comma-separated list of persistence services to install (e.g. "persistence = rrd4j,jpa")
+#persistence =
+
+# A comma-separated list of actions to install (e.g. "action = mail,pushover")
+#action =
+
+# A comma-separated list of transformation services to install (e.g. "transformation = map,jsonpath")
+#transformation =
+
+# A comma-separated list of voice services to install (e.g. "voice = marytts,freetts")
+#voice =
+
+# A comma-separated list of miscellaneous services to install (e.g. "misc = myopenhab")
+#misc =
diff --git a/openhab2/services/influxdb.cfg b/openhab2/services/influxdb.cfg
new file mode 100644
index 0000000..dc4200e
--- /dev/null
+++ b/openhab2/services/influxdb.cfg
@@ -0,0 +1,6 @@
+url=http://localhost:8086
+version=V1
+user=openhab2
+password=0ZYDJu6G000
+db=power_station
+retentionPolicy=autogen
\ No newline at end of file
diff --git a/openhab2/services/mapdb.cfg b/openhab2/services/mapdb.cfg
new file mode 100644
index 0000000..57ad40e
--- /dev/null
+++ b/openhab2/services/mapdb.cfg
@@ -0,0 +1,5 @@
+# the commit interval in seconds (optional, default to '5')
+#commitinterval=5
+
+# issue a commit even if the state did not change (optional, defaults to 'false')
+#commitsamestate=false
diff --git a/openhab2/services/readme.txt b/openhab2/services/readme.txt
new file mode 100644
index 0000000..62ba811
--- /dev/null
+++ b/openhab2/services/readme.txt
@@ -0,0 +1,6 @@
+Your service configurations will reside here.
+All configuration files have to have the ".cfg" file extension.
+Service configuration files are automatically created as soon as you install an add-on that can be configured.
+
+Check out the openHAB documentation for more details:
+https://www.openhab.org/docs/configuration/services.html
diff --git a/openhab2/services/runtime.cfg b/openhab2/services/runtime.cfg
new file mode 100644
index 0000000..7c09845
--- /dev/null
+++ b/openhab2/services/runtime.cfg
@@ -0,0 +1,86 @@
+##################### LOCALE ####################
+
+# The default language that should be used. If not specified, the system default locale is used.
+# The ISO 639 alpha-2 or alpha-3 language code (if there is no alpha-2 one).
+# Example: "en" (English), "de" (German), "ja" (Japanese), "kok" (Konkani)
+#
+#org.eclipse.smarthome.i18n:language=
+
+# The region that should be used.
+# ISO 3166 alpha-2 country code or UN M.49 numeric-3 area code.
+# Example: "US" (United States), "DE" (Germany), "FR" (France), "029" (Caribbean)
+#
+#org.eclipse.smarthome.i18n:region=
+
+################ PERSISTENCE ####################
+
+# The persistence service to use if no other is specified.
+#
+#org.eclipse.smarthome.persistence:default=
+
+################### AUDIO #######################
+
+# This parameter defines the default audio source to use (if not set, the first available one will be used.
+#
+#org.eclipse.smarthome.audio:defaultSource=
+
+# This parameter defines the default audio sink to use (if not set, the first available one will be used.
+#
+#org.eclipse.smarthome.audio:defaultSink=
+
+##################### VOICE #####################
+
+# This parameter defines the default text-to-speech service to use (if not set, the first available one will be used.
+#
+#org.eclipse.smarthome.voice:defaultTTS=
+
+# This parameter defines the default speech-to-text service to use (if not set, the first available one will be used.
+#
+#org.eclipse.smarthome.voice:defaultSTT=
+
+# The default voice to use if no specific TTS service or voice is specified.
+#
+#org.eclipse.smarthome.voice:defaultVoice=
+
+# The default human language interpreter to use if no other is specified.
+#
+#org.eclipse.smarthome.voice:defaultHLI=
+
+################### EPHEMERIS ###################
+
+# This parameter defines the default list of usual non workable days for the Ephemeris service.
+# The value has to be surrounded by square brackets ('[' and ']') and optionally contain value delimiters - a comma ',' to be interpreted as a list of values.
+# Example: [SATURDAY,SUNDAY]
+#
+org.openhab.ephemeris:dayset-weekend=[SATURDAY,SUNDAY]
+
+# This parameter defines the default list of usual workable days for the Ephemeris service.
+# The value has to be surrounded by square brackets ('[' and ']') and optionally contain value delimiters - a comma ',' to be interpreted as a list of values.
+#
+org.openhab.ephemeris:dayset-school=[MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY]
+
+################ MISCELLANOUS ###################
+
+# The karaf sshHost parameter configures the bind address for the ssh login to karaf.
+# Default is 127.0.0.1 (localhost), so it is only possible to login from the local machine.
+#
+# Setting this to the address of another network interfaces will allow login from this network.
+# Setting this to 0.0.0.0 will allow login from all network interfaces.
+#
+# !!! Security warning !!!
+# Remember to change default login/password, if you allow external login.
+# See https://www.openhab.org/docs/administration/console.html for details.
+#
+#org.apache.karaf.shell:sshHost = 0.0.0.0
+
+# Setting this to true will automatically approve all inbox entries and create Things for them,
+# so that they are immediately available in the system (default is false)
+#
+#org.eclipse.smarthome.inbox:autoApprove=true
+
+# This setting allows to switch between a "simple" and an "advanced" mode for item management.
+# In simple mode (autoLinks=true), links and their according items are automatically created for new Things.
+# In advanced mode (autoLinks=false), the user has the full control about which items channels are linked to.
+# Existing links will remain untouched. (default is true)
+#
+#org.eclipse.smarthome.links:autoLinks=false
diff --git a/openhab2/sitemaps/default.sitemap b/openhab2/sitemaps/default.sitemap
new file mode 100644
index 0000000..7fee9cd
--- /dev/null
+++ b/openhab2/sitemaps/default.sitemap
@@ -0,0 +1,71 @@
+sitemap default label="Power Station Manager" {
+ Frame label="Labornetzgerät - Übersicht" {
+ Text item=DC_Supply_Voltage valuecolor=[>40="orange",>50="red"] icon="voltage.png"
+ Text item=DC_Supply_Current valuecolor=[>10="orange",>15="red"] icon="current.png"
+ Text item=DC_Supply_Amperehours valuecolor=[>0="purple"] icon="electric_ah.png"
+ Text item=DC_Supply_Watthours valuecolor=[>0="purple"] icon="electric_wh.png"
+ Text item=DC_Supply_Power valuecolor=[<49="grey",>49="green",>200="orange"] icon="power.png"
+ Text item=DC_Supply_Protection valuecolor=[0="green", >=1="red"] icon="sicherheitsschaltung.png"
+ Text item=DC_Supply_Mode valuecolor=[0="green", 1="red"] icon="mode.png"
+ Text item=DC_Supply_Input_Voltage valuecolor=[<60="red",>64="green"] icon="input_voltage.png"
+ Text item=DC_Supply_Timer icon="timer.png"
+ Switch item=DC_Supply_Set_Reset mappings=[ON="Reset"] icon="reset.png"
+ }
+ Frame label="Labornetzgerät - Batterie-Lader und Temperaturen" {
+ Text item=DC_Supply_Temp_Internal icon=temperature
+ Text item=DC_Supply_Temp_External icon=temperature visibility=[DC_Supply_Temp_External_Active == 0]
+ Text label="Temperatur Extern [Nicht angeschl.]" icon=temperature visibility=[DC_Supply_Temp_External_Active == 1]
+ Text item=DC_Supply_Batt_Active valuecolor=[1="green"] icon="batterycharger.png"
+ Text item=DC_Supply_Batt_Voltage visibility=[DC_Supply_Batt_Active == 1] icon="voltage.png"
+ }
+ Frame label="Labornetzgerät - Sollwerte" {
+ Setpoint item=DC_Supply_Voltage_Setpoint step=0.1 minValue=0.5 maxValue=60 icon="pressure"
+ Text label="" icon="none"
+ Switch item=DC_Supply_Voltage_Setpoint label="" icon="quick_select.png" mappings=[3.3="3.3V", 4.2="4.2V", 5="5V", 7="7V", 12="12V", 15="15V", 24="24V", 30="30V", 48="48V", 54="54V", 60="60V"]
+ Text label="" icon="none"
+ Setpoint item=DC_Supply_Current_Setpoint step=0.1 minValue=0.1 maxValue=18 icon="pressure"
+ Text label="" icon="none"
+ Switch item=DC_Supply_Current_Setpoint label="" icon="quick_select.png" mappings=[1="1A", 2="2A", 3="3A", 4="4A", 5="5A", 6="6A", 7="7A", 8="8A", 9="9A", 10="10A", 12="12A", 14="14A", 18="18A"]
+ Text label="" icon="none"
+ Switch item=DC_Supply_PowerOnOff mappings=[0="Aus", 1 = "Ein"] icon=switch
+
+ }
+ Frame label="Elektronisch DC Last - Übersicht" {
+ Text item=DC_Load_Voltage valuecolor=[>40="orange",>50="red"] icon="voltage.png"
+ Text item=DC_Load_Current valuecolor=[>10="orange",>15="red"] icon="current.png"
+ Text item=DC_Load_Amperehours valuecolor=[>0="purple"] icon="electric_ah.png"
+ Text item=DC_Load_Watthours valuecolor=[>0="purple"] icon="electric_wh.png"
+ Text item=DC_Load_Power valuecolor=[>5="purple"] icon="power.png"
+ Text item=DC_Load_Mode icon="mode.png"
+ Text item=DC_Load_OnOff valuecolor=[OFF="green", ON="red"] icon=switch
+ Text item=DC_Load_Timer icon="timer.png"
+ Switch item=DC_Load_Set_Reset mappings=[ON="Reset"] icon="reset.png"
+ }
+ Frame label="Batterie Entlade Trend" {
+ Webview url="grafana/d-solo/5_pfO0Wgz/dc-load-battery-discharging?orgId=1&panelId=2&refresh=1m" icon="none" height=15
+ }
+ Frame label="Elektronisch DC Last - Sollwerte" {
+ Setpoint item=DC_Load_Set_Voltage step=0.1 minValue=0.5 maxValue=150 icon="pressure" visibility=[DC_Load_Mode == 0]
+ Text label="" icon="none" visibility=[DC_Load_Mode == 0]
+ Switch item=DC_Load_Set_Voltage label="" icon="quick_select.png" mappings=[3.3="3.3V", 4="4V", 5="5V", 7="7V", 12="12V", 15="15V", 24="24V", 30="30V", 50="50V", 80="80V", 100="100V", 120="120V", 150="150V"] visibility=[DC_Load_Mode == 0]
+ Text label="" icon="none" visibility=[DC_Load_Mode == 0]
+ Setpoint item=DC_Load_Set_Current step=0.1 minValue=0.1 maxValue=40 icon="pressure" visibility=[DC_Load_Mode == 1]
+ Text label="" icon="none" visibility=[DC_Load_Mode == 1]
+ Switch item=DC_Load_Set_Current label="" icon="quick_select.png" mappings=[1="1A", 2="2A", 3="3A", 4="4A", 5="5A", 6="6A", 7="7A", 8="8A", 10="10A", 20="20A", 30="30A", 35="35A", 40="40A"] visibility=[DC_Load_Mode == 1]
+ Text label="" icon="none" visibility=[DC_Load_Mode == 1]
+ Setpoint item=DC_Load_Set_Resistance minValue=0.1 maxValue=1000 icon="pressure" visibility=[DC_Load_Mode == 2]
+ Text label="" icon="none" visibility=[DC_Load_Mode == 2]
+ Switch item=DC_Load_Set_Resistance label="" icon="quick_select.png" mappings=[1="1Ohm", 2="2Ohm", 3="3Ohm", 4="4Ohm", 5="5Ohm", 6="6Ohm", 7="7Ohm", 8="8Ohm", 10="10Ohm", 20="20Ohm", 30="30Ohm", 35="35Ohm", 40="40Ohm"] visibility=[DC_Load_Mode == 2]
+ Text label="" icon="none" visibility=[DC_Load_Mode == 2]
+ Setpoint item=DC_Load_Set_Power step=1 minValue=1 maxValue=400 icon="pressure" visibility=[DC_Load_Mode == 3]
+ Text label="" icon="none" visibility=[DC_Load_Mode == 3]
+ Switch item=DC_Load_Set_Power label="" icon="quick_select.png" mappings=[1="1W", 2="2W", 3="3W", 4="4W", 5="5W", 6="6W", 7="7W", 8="8W", 10="10W", 100="100W", 200="200W", 300="300W", 400="400W"] visibility=[DC_Load_Mode == 3]
+ Text label="" icon="none" visibility=[DC_Load_Mode == 3]
+ Setpoint item=DC_Load_Set_Mode minValue=0 maxValue=3 icon="pressure" visibility=[DC_Load_Set_OnOff == "OFF"]
+ Text label="" icon="none"
+ Switch item=DC_Load_Set_BattMode icon="battery" visibility=[DC_Load_Set_OnOff == "OFF"]
+ Setpoint item=DC_Load_Set_Batt_MinVoltage icon="battery" step=0.1
+ //Text label="" icon="none" visibility=[DC_Load_Set_OnOff == "OFF"]
+ Switch item=DC_Load_Set_OnOff mappings=[OFF="Aus", ON = "Ein"] icon=switch
+ }
+}
\ No newline at end of file
diff --git a/openhab2/sitemaps/readme.txt b/openhab2/sitemaps/readme.txt
new file mode 100644
index 0000000..85c7a47
--- /dev/null
+++ b/openhab2/sitemaps/readme.txt
@@ -0,0 +1,5 @@
+Your sitemap definitions go here.
+All sitemap files have to have the ".sitemap" file extension and must follow a special syntax.
+
+Check out the openHAB documentation for more details:
+https://www.openhab.org/docs/configuration/sitemaps.html
diff --git a/openhab2/sounds/barking.mp3 b/openhab2/sounds/barking.mp3
new file mode 100644
index 0000000..5a3c41d
Binary files /dev/null and b/openhab2/sounds/barking.mp3 differ
diff --git a/openhab2/sounds/doorbell.mp3 b/openhab2/sounds/doorbell.mp3
new file mode 100644
index 0000000..7a8a5a3
Binary files /dev/null and b/openhab2/sounds/doorbell.mp3 differ
diff --git a/openhab2/things/modbus_dc_supply.things b/openhab2/things/modbus_dc_supply.things
new file mode 100644
index 0000000..e9c4d18
--- /dev/null
+++ b/openhab2/things/modbus_dc_supply.things
@@ -0,0 +1,24 @@
+Bridge modbus:serial:dcsupply [ port="/dev/ttyDCSupply", baud=115200, stopBits="1.0", parity="none", dataBits=8, encoding="rtu" ] {
+
+ Bridge poller dcsupply_main [ start=4, length=15, refresh=500, type="holding" ] {
+ Thing data temperature_internal [ readStart="5", readValueType="int16" ]
+ Thing data voltage_setpoint [ readStart="8", readValueType="uint16" , readTransform="JS(divide100.js)", writeStart="8", writeType="holding", writeValueType="int16", writeTransform="JS(multiply100.js)"]
+ Thing data current_setpoint [ readStart="9", readValueType="uint16", readTransform="JS(divide100.js)", writeStart="9", writeType="holding", writeValueType="int16", writeTransform="JS(multiply100.js)"]
+ Thing data voltage_actual [ readStart="10", readValueType="uint16", readTransform="JS(divide100.js)"]
+ Thing data current_actual [ readStart="11", readValueType="uint16", readTransform="JS(divide100.js)"]
+ Thing data power [ readStart="13", readValueType="uint16", readTransform="JS(divide100.js)"]
+ Thing data voltage_input [ readStart="14", readValueType="uint16", readTransform="JS(divide100.js)"]
+ Thing data protection [ readStart="16", readValueType="uint16" ]
+ Thing data mode [ readStart="17", readValueType="uint16" ]
+ Thing data output_enable [ readStart="18", readValueType="uint16", writeStart="18", writeType="holding", writeStart="18", writeValueType="int16"]
+ }
+
+ Bridge poller dcsupply_sec [ start=32, length=11, refresh=500, type="holding" ] {
+ Thing data battery_mode_active [ readStart="32", readValueType="uint16" ]
+ Thing data voltage_battery [ readStart="33", readValueType="uint16", readTransform="JS(divide100.js)"]
+ Thing data temperature_external_active [ readStart="34", readValueType="int16" ]
+ Thing data temperature_external [ readStart="35", readValueType="int16" ]
+ Thing data ampere_hours [ readStart="38", readValueType="uint32", readTransform="JS(divide1000.js)"]
+ Thing data watt_hours [ readStart="40", readValueType="uint32", readTransform="JS(divide1000.js)" ]
+ }
+}
\ No newline at end of file
diff --git a/openhab2/things/readme.txt b/openhab2/things/readme.txt
new file mode 100644
index 0000000..27b6689
--- /dev/null
+++ b/openhab2/things/readme.txt
@@ -0,0 +1,5 @@
+Your thing definitions go here.
+All thing files have to have the ".things" file extension and must follow a special syntax.
+
+Check out the openHAB documentation for more details:
+https://www.openhab.org/docs/configuration/things.html
diff --git a/openhab2/transform/dc_load_EinAus.map b/openhab2/transform/dc_load_EinAus.map
new file mode 100644
index 0000000..d848843
--- /dev/null
+++ b/openhab2/transform/dc_load_EinAus.map
@@ -0,0 +1,2 @@
+ON=Ein
+OFF=Aus
\ No newline at end of file
diff --git a/openhab2/transform/dc_load_mode.map b/openhab2/transform/dc_load_mode.map
new file mode 100644
index 0000000..25381e5
--- /dev/null
+++ b/openhab2/transform/dc_load_mode.map
@@ -0,0 +1,4 @@
+0=Konstantspannung
+1=Konstantstrom
+2=Konstantwiderstand
+3=Konstantleistung
\ No newline at end of file
diff --git a/openhab2/transform/dc_supply_OnOff.map b/openhab2/transform/dc_supply_OnOff.map
new file mode 100644
index 0000000..f290d83
--- /dev/null
+++ b/openhab2/transform/dc_supply_OnOff.map
@@ -0,0 +1,2 @@
+1=ON
+0=OFF
\ No newline at end of file
diff --git a/openhab2/transform/dc_supply_battmode.map b/openhab2/transform/dc_supply_battmode.map
new file mode 100644
index 0000000..5d2dd00
--- /dev/null
+++ b/openhab2/transform/dc_supply_battmode.map
@@ -0,0 +1,2 @@
+0=Inaktiv
+1=Aktiv
\ No newline at end of file
diff --git a/openhab2/transform/dc_supply_mode.map b/openhab2/transform/dc_supply_mode.map
new file mode 100644
index 0000000..9b1a73d
--- /dev/null
+++ b/openhab2/transform/dc_supply_mode.map
@@ -0,0 +1,2 @@
+0=Konstantspannung
+1=Konstantstrom
\ No newline at end of file
diff --git a/openhab2/transform/dc_supply_protection.map b/openhab2/transform/dc_supply_protection.map
new file mode 100644
index 0000000..eec72f5
--- /dev/null
+++ b/openhab2/transform/dc_supply_protection.map
@@ -0,0 +1,3 @@
+2=OCP
+1=OVP
+0=OK
\ No newline at end of file
diff --git a/openhab2/transform/de.map b/openhab2/transform/de.map
new file mode 100644
index 0000000..8cc1579
--- /dev/null
+++ b/openhab2/transform/de.map
@@ -0,0 +1,3 @@
+CLOSED=zu
+OPEN=offen
+NULL=undefiniert
diff --git a/openhab2/transform/divide100.js b/openhab2/transform/divide100.js
new file mode 100644
index 0000000..ea29f77
--- /dev/null
+++ b/openhab2/transform/divide100.js
@@ -0,0 +1,4 @@
+(function(i) {
+ return parseFloat(i) / 100;
+ })(input)
+
\ No newline at end of file
diff --git a/openhab2/transform/divide1000.js b/openhab2/transform/divide1000.js
new file mode 100644
index 0000000..ec1fca2
--- /dev/null
+++ b/openhab2/transform/divide1000.js
@@ -0,0 +1,4 @@
+(function(i) {
+ return parseFloat(i) / 1000;
+ })(input)
+
\ No newline at end of file
diff --git a/openhab2/transform/en.map b/openhab2/transform/en.map
new file mode 100644
index 0000000..bd08f17
--- /dev/null
+++ b/openhab2/transform/en.map
@@ -0,0 +1,4 @@
+CLOSED=closed
+OPEN=open
+NULL=unknown
+
\ No newline at end of file
diff --git a/openhab2/transform/multiply100.js b/openhab2/transform/multiply100.js
new file mode 100644
index 0000000..ec438ee
--- /dev/null
+++ b/openhab2/transform/multiply100.js
@@ -0,0 +1,4 @@
+(function(i) {
+ return parseFloat(i) * 100;
+ })(input)
+
\ No newline at end of file
diff --git a/openhab2/transform/multiply1000.js b/openhab2/transform/multiply1000.js
new file mode 100644
index 0000000..ec7b73f
--- /dev/null
+++ b/openhab2/transform/multiply1000.js
@@ -0,0 +1,4 @@
+(function(i) {
+ return parseFloat(i) * 1000;
+ })(input)
+
\ No newline at end of file
diff --git a/openhab2/transform/readme.txt b/openhab2/transform/readme.txt
new file mode 100644
index 0000000..6933c16
--- /dev/null
+++ b/openhab2/transform/readme.txt
@@ -0,0 +1,5 @@
+Transformations like map or jsonpath can utilize configuration files with data definitions.
+These files have their specific file extensions and syntax definition.
+
+Check out the openHAB documentation for more details:
+https://www.openhab.org/docs/configuration/transformations.html
diff --git a/openhab2/transform/switch.js b/openhab2/transform/switch.js
new file mode 100644
index 0000000..ad2a6ad
--- /dev/null
+++ b/openhab2/transform/switch.js
@@ -0,0 +1,6 @@
+(function(i) {
+ if (parseInt(i) > 0)
+ return "ON"
+ else
+ return "OFF";
+ })(input)
\ No newline at end of file
diff --git a/udev/rules/99-usbcom.rules b/udev/rules/99-usbcom.rules
new file mode 100644
index 0000000..01b101c
--- /dev/null
+++ b/udev/rules/99-usbcom.rules
@@ -0,0 +1,3 @@
+SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A50285BI", SYMLINK+="ttyDCLoad"
+SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyDCSupply"
+