]> git.basschouten.com Git - openhab-addons.git/commitdiff
[pihole] Add channels for gravity (#17413)
authorMartin <martin.grzeslowski@gmail.com>
Sun, 15 Sep 2024 11:55:31 +0000 (13:55 +0200)
committerGitHub <noreply@github.com>
Sun, 15 Sep 2024 11:55:31 +0000 (13:55 +0200)
* Add channels for gravity

Signed-off-by: Martin GrzeĊ›lowski <martin.grzeslowski@gmail.com>
bundles/org.openhab.binding.pihole/README.md
bundles/org.openhab.binding.pihole/src/main/java/org/openhab/binding/pihole/internal/PiHoleBindingConstants.java
bundles/org.openhab.binding.pihole/src/main/java/org/openhab/binding/pihole/internal/PiHoleHandler.java
bundles/org.openhab.binding.pihole/src/main/java/org/openhab/binding/pihole/internal/PiHoleHandlerFactory.java
bundles/org.openhab.binding.pihole/src/main/resources/OH-INF/thing/thing-types.xml
bundles/org.openhab.binding.pihole/src/main/resources/OH-INF/update/gravity.xml [new file with mode: 0644]

index 27c2d05ff00528d9e9e5bcd29947db4cd328ab4a..6516b910427689d6557133db8e1dadf7514fa96f 100644 (file)
@@ -28,36 +28,38 @@ The Pi-hole Binding allows you to monitor Pi-hole statistics and control its fun
 
 ## Channels
 
-| Channel                 | Type   | Read/Write | Description                                                |
-|-------------------------|--------|------------|------------------------------------------------------------|
-| domains-being-blocked   | Number | RO         | The total number of domains currently being blocked.       |
-| dns-queries-today       | Number | RO         | The count of DNS queries made today.                       |
-| ads-blocked-today       | Number | RO         | The number of ads blocked today.                           |
-| ads-percentage-today    | Number | RO         | The percentage of ads blocked today.                       |
-| unique-domains          | Number | RO         | The count of unique domains queried.                       |
-| queries-forwarded       | Number | RO         | The number of queries forwarded to an external DNS server. |
-| queries-cached          | Number | RO         | The number of queries served from the cache.               |
-| clients-ever-seen       | Number | RO         | The total number of unique clients ever seen.              |
-| unique-clients          | Number | RO         | The current count of unique clients.                       |
-| dns-queries-all-types   | Number | RO         | The total number of DNS queries of all types.              |
-| reply-unknown           | Number | RO         | DNS replies with an unknown status.                        |
-| reply-nodata            | Number | RO         | DNS replies indicating no data.                            |
-| reply-nxdomain          | Number | RO         | DNS replies indicating non-existent domain.                |
-| reply-cname             | Number | RO         | DNS replies with a CNAME record.                           |
-| reply-ip                | Number | RO         | DNS replies with an IP address.                            |
-| reply-domain            | Number | RO         | DNS replies with a domain name.                            |
-| reply-rrname            | Number | RO         | DNS replies with a resource record name.                   |
-| reply-servfail          | Number | RO         | DNS replies indicating a server failure.                   |
-| reply-refused           | Number | RO         | DNS replies indicating refusal.                            |
-| reply-notimp            | Number | RO         | DNS replies indicating not implemented.                    |
-| reply-other             | Number | RO         | DNS replies with other statuses.                           |
-| reply-dnssec            | Number | RO         | DNS replies with DNSSEC information.                       |
-| reply-none              | Number | RO         | DNS replies with no data.                                  |
-| reply-blob              | Number | RO         | DNS replies with a BLOB (binary large object).             |
-| dns-queries-all-replies | Number | RO         | The total number of DNS queries with all reply types.      |
-| privacy-level           | Number | RO         | The privacy level setting.                                 |
-| enabled                 | Switch | RO         | The current status of blocking                             |
-| disable-enable          | String | RW         | Is blocking enabled/disabled                               |
+| Channel                 | Type     | Read/Write | Description                                                |
+|-------------------------|----------|------------|------------------------------------------------------------|
+| domains-being-blocked   | Number   | RO         | The total number of domains currently being blocked.       |
+| dns-queries-today       | Number   | RO         | The count of DNS queries made today.                       |
+| ads-blocked-today       | Number   | RO         | The number of ads blocked today.                           |
+| ads-percentage-today    | Number   | RO         | The percentage of ads blocked today.                       |
+| unique-domains          | Number   | RO         | The count of unique domains queried.                       |
+| queries-forwarded       | Number   | RO         | The number of queries forwarded to an external DNS server. |
+| queries-cached          | Number   | RO         | The number of queries served from the cache.               |
+| clients-ever-seen       | Number   | RO         | The total number of unique clients ever seen.              |
+| unique-clients          | Number   | RO         | The current count of unique clients.                       |
+| dns-queries-all-types   | Number   | RO         | The total number of DNS queries of all types.              |
+| reply-unknown           | Number   | RO         | DNS replies with an unknown status.                        |
+| reply-nodata            | Number   | RO         | DNS replies indicating no data.                            |
+| reply-nxdomain          | Number   | RO         | DNS replies indicating non-existent domain.                |
+| reply-cname             | Number   | RO         | DNS replies with a CNAME record.                           |
+| reply-ip                | Number   | RO         | DNS replies with an IP address.                            |
+| reply-domain            | Number   | RO         | DNS replies with a domain name.                            |
+| reply-rrname            | Number   | RO         | DNS replies with a resource record name.                   |
+| reply-servfail          | Number   | RO         | DNS replies indicating a server failure.                   |
+| reply-refused           | Number   | RO         | DNS replies indicating refusal.                            |
+| reply-notimp            | Number   | RO         | DNS replies indicating not implemented.                    |
+| reply-other             | Number   | RO         | DNS replies with other statuses.                           |
+| reply-dnssec            | Number   | RO         | DNS replies with DNSSEC information.                       |
+| reply-none              | Number   | RO         | DNS replies with no data.                                  |
+| reply-blob              | Number   | RO         | DNS replies with a BLOB (binary large object).             |
+| dns-queries-all-replies | Number   | RO         | The total number of DNS queries with all reply types.      |
+| privacy-level           | Number   | RO         | The privacy level setting.                                 |
+| enabled                 | Switch   | RO         | The current status of blocking                             |
+| disable-enable          | String   | RW         | Is blocking enabled/disabled                               |
+| gravity-last-update     | DateTime | RO         | Last update of gravity                                     |
+| gravity-file-exists     | DateTime | RO         | Does gravity file exists                                   |
 
 ## Full Example
 
index 3adc0f87fba4f771acaefc99cb949a26c2c794eb..0eca2bca361e8379e602a8969173f6be52dfb44b 100644 (file)
@@ -58,6 +58,8 @@ public class PiHoleBindingConstants {
         public static final String PRIVACY_LEVEL_CHANNEL = "privacy-level";
         public static final String ENABLED_CHANNEL = "enabled";
         public static final String DISABLE_ENABLE_CHANNEL = "disable-enable";
+        public static final String GRAVITY_FILE_EXISTS = "gravity-file-exists";
+        public static final String GRAVITY_LAST_UPDATE = "gravity-last-update";
 
         public static enum DisableEnable {
             DISABLE,
index 4ed38f200d2c41018d5ee957b3655239d04eb281..9fa260e599f9dea73bf02a08cb43f1afe800beb8 100644 (file)
 package org.openhab.binding.pihole.internal;
 
 import static java.util.concurrent.TimeUnit.*;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.ADS_BLOCKED_TODAY_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.ADS_PERCENTAGE_TODAY_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.CLIENTS_EVER_SEEN_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.DISABLE_ENABLE_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.DNS_QUERIES_ALL_REPLIES_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.DNS_QUERIES_ALL_TYPES_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.DNS_QUERIES_TODAY_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.DOMAINS_BEING_BLOCKED_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.DisableEnable;
+import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.*;
 import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.DisableEnable.ENABLE;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.ENABLED_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.PRIVACY_LEVEL_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.QUERIES_CACHED_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.QUERIES_FORWARDED_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_BLOB_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_CNAME_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_DNSSEC_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_DOMAIN_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_IP_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_NODATA_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_NONE_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_NOTIMP_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_NXDOMAIN_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_OTHER_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_REFUSED_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_RRNAME_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_SERVFAIL_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.REPLY_UNKNOWN_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.UNIQUE_CLIENTS_CHANNEL;
-import static org.openhab.binding.pihole.internal.PiHoleBindingConstants.Channels.UNIQUE_DOMAINS_CHANNEL;
 import static org.openhab.core.library.unit.Units.PERCENT;
 import static org.openhab.core.thing.ThingStatus.OFFLINE;
 import static org.openhab.core.thing.ThingStatus.ONLINE;
@@ -52,6 +24,7 @@ import static org.openhab.core.thing.ThingStatusDetail.*;
 import java.math.BigDecimal;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.time.Instant;
 import java.util.Collection;
 import java.util.Optional;
 import java.util.Set;
@@ -63,6 +36,8 @@ import org.eclipse.jetty.client.HttpClient;
 import org.openhab.binding.pihole.internal.rest.AdminService;
 import org.openhab.binding.pihole.internal.rest.JettyAdminService;
 import org.openhab.binding.pihole.internal.rest.model.DnsStatistics;
+import org.openhab.core.i18n.TimeZoneProvider;
+import org.openhab.core.library.types.DateTimeType;
 import org.openhab.core.library.types.DecimalType;
 import org.openhab.core.library.types.OnOffType;
 import org.openhab.core.library.types.QuantityType;
@@ -87,14 +62,16 @@ public class PiHoleHandler extends BaseThingHandler implements AdminService {
     private static final int HTTP_DELAY_SECONDS = 1;
     private final Logger logger = LoggerFactory.getLogger(PiHoleHandler.class);
     private final Object lock = new Object();
+    private final TimeZoneProvider timeZoneProvider;
     private final HttpClient httpClient;
 
     private @Nullable AdminService adminService;
     private @Nullable DnsStatistics dnsStatistics;
     private @Nullable ScheduledFuture<?> scheduledFuture;
 
-    public PiHoleHandler(Thing thing, HttpClient httpClient) {
+    public PiHoleHandler(Thing thing, TimeZoneProvider timeZoneProvider, HttpClient httpClient) {
         super(thing);
+        this.timeZoneProvider = timeZoneProvider;
         this.httpClient = httpClient;
     }
 
@@ -218,6 +195,19 @@ public class PiHoleHandler extends BaseThingHandler implements AdminService {
         if (localDnsStatistics.enabled()) {
             updateState(DISABLE_ENABLE_CHANNEL, new StringType(ENABLE.toString()));
         }
+        var gravityLastUpdated = localDnsStatistics.gravityLastUpdated();
+        if (gravityLastUpdated != null) {
+            var absolute = gravityLastUpdated.absolute();
+            if (absolute != null) {
+                var instant = Instant.ofEpochSecond(absolute);
+                var zonedDateTime = instant.atZone(timeZoneProvider.getTimeZone());
+                updateState(GRAVITY_LAST_UPDATE, new DateTimeType(zonedDateTime));
+            }
+            var fileExists = gravityLastUpdated.fileExists();
+            if (fileExists != null) {
+                updateState(GRAVITY_FILE_EXISTS, OnOffType.from(fileExists));
+            }
+        }
     }
 
     private void updateDecimalState(String channelID, @Nullable Integer value) {
index 3ff0c29fcf002628419aaa2b612f64c035cd5b15..c778bea57af701425006596be42bd0fa75265112 100644 (file)
@@ -18,6 +18,7 @@ import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.i18n.TimeZoneProvider;
 import org.openhab.core.io.net.http.HttpClientFactory;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingTypeUID;
@@ -39,10 +40,13 @@ import org.osgi.service.component.annotations.Reference;
 public class PiHoleHandlerFactory extends BaseThingHandlerFactory {
 
     private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(PI_HOLE_TYPE);
+    private final TimeZoneProvider timeZoneProvider;
     private final HttpClientFactory httpClientFactory;
 
     @Activate
-    public PiHoleHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
+    public PiHoleHandlerFactory(@Reference TimeZoneProvider timeZoneProvider,
+            @Reference HttpClientFactory httpClientFactory) {
+        this.timeZoneProvider = timeZoneProvider;
         this.httpClientFactory = httpClientFactory;
     }
 
@@ -56,7 +60,7 @@ public class PiHoleHandlerFactory extends BaseThingHandlerFactory {
         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
 
         if (PI_HOLE_TYPE.equals(thingTypeUID)) {
-            return new PiHoleHandler(thing, httpClientFactory.getCommonHttpClient());
+            return new PiHoleHandler(thing, timeZoneProvider, httpClientFactory.getCommonHttpClient());
         }
 
         return null;
index b5ba080748e6a4952fe6dedeb53a4c10c43a0a8e..27949e316bd5496b5375071ef4e3687fd810dbb3 100644 (file)
                        <channel id="enabled" typeId="enabled-channel"/>
                        <channel id="disable-enable" typeId="disable-enable-channel"/>
                </channels>
+               <properties>
+                       <property name="thingTypeVersion">1</property>
+               </properties>
 
                <config-description>
                        <parameter name="hostname" type="text" required="true">
                        </options>
                </command>
        </channel-type>
+       <channel-type id="gravity-file-exists-channel">
+               <item-type>Switch</item-type>
+               <label>Gravity File Exists</label>
+               <state readOnly="true"/>
+       </channel-type>
+       <channel-type id="gravity-last-update-channel">
+               <item-type>DateTime</item-type>
+               <label>Gravity Last Update</label>
+               <category>time</category>
+               <state readOnly="true"/>
+       </channel-type>
 </thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.pihole/src/main/resources/OH-INF/update/gravity.xml b/bundles/org.openhab.binding.pihole/src/main/resources/OH-INF/update/gravity.xml
new file mode 100644 (file)
index 0000000..0b184c1
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
+
+       <thing-type uid="pihole:server">
+               <instruction-set targetVersion="1">
+                       <add-channel id="gravity-file-exists">
+                               <type>pihole:gravity-file-exists-channel</type>
+                       </add-channel>
+                       <add-channel id="gravity-last-update">
+                               <type>pihole:gravity-last-update-channel</type>
+                       </add-channel>
+               </instruction-set>
+       </thing-type>
+</update:update-descriptions>