mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-29 12:34:21 +02:00
[pihole] NPE when getting session.sid (#19618)
* Resolves #19612 Signed-off-by: gael@lhopital.org <gael@lhopital.org>
This commit is contained in:
@@ -11,6 +11,7 @@ The Pi-hole Binding allows you to monitor Pi-hole statistics and control its fun
|
|||||||
- Real-time Statistics: Monitor key metrics such as the number of domains being blocked, DNS queries made today, ads blocked today, and more.
|
- Real-time Statistics: Monitor key metrics such as the number of domains being blocked, DNS queries made today, ads blocked today, and more.
|
||||||
- Control: Enable or disable Pi-hole's blocking functionality, configure blocking options, and adjust privacy settings directly from openHAB.
|
- Control: Enable or disable Pi-hole's blocking functionality, configure blocking options, and adjust privacy settings directly from openHAB.
|
||||||
- Integration: Seamlessly integrate Pi-hole data and controls with other openHAB items and rules to create advanced automation scenarios.
|
- Integration: Seamlessly integrate Pi-hole data and controls with other openHAB items and rules to create advanced automation scenarios.
|
||||||
|
- Version 6 of piHole is supported (configured via the `serverVersion` configuration parameter) starting with version 6.3 (6.2 will not work).
|
||||||
|
|
||||||
## Supported Things
|
## Supported Things
|
||||||
|
|
||||||
@@ -29,38 +30,38 @@ The Pi-hole Binding allows you to monitor Pi-hole statistics and control its fun
|
|||||||
|
|
||||||
## Channels
|
## Channels
|
||||||
|
|
||||||
| Channel | Type | Read/Write | Description |
|
| Channel | Type | Read/Write | Description |
|
||||||
|-------------------------|----------|------------|------------------------------------------------------------|
|
|-------------------------|----------------------|------------|------------------------------------------------------------|
|
||||||
| domains-being-blocked | Number | RO | The total number of domains currently being blocked. |
|
| 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. |
|
| dns-queries-today | Number | RO | The count of DNS queries made today. |
|
||||||
| ads-blocked-today | Number | RO | The number of ads blocked today. |
|
| ads-blocked-today | Number | RO | The number of ads blocked today. |
|
||||||
| ads-percentage-today | Number | RO | The percentage of ads blocked today. |
|
| ads-percentage-today | Number:Dimensionless | RO | The percentage of ads blocked today. |
|
||||||
| unique-domains | Number | RO | The count of unique domains queried. |
|
| 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-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. |
|
| 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. |
|
| clients-ever-seen | Number | RO | The total number of unique clients ever seen. |
|
||||||
| unique-clients | Number | RO | The current count of unique clients. |
|
| 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. |
|
| 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-unknown | Number | RO | DNS replies with an unknown status. |
|
||||||
| reply-nodata | Number | RO | DNS replies indicating no data. |
|
| reply-nodata | Number | RO | DNS replies indicating no data. |
|
||||||
| reply-nxdomain | Number | RO | DNS replies indicating non-existent domain. |
|
| reply-nxdomain | Number | RO | DNS replies indicating non-existent domain. |
|
||||||
| reply-cname | Number | RO | DNS replies with a CNAME record. |
|
| reply-cname | Number | RO | DNS replies with a CNAME record. |
|
||||||
| reply-ip | Number | RO | DNS replies with an IP address. |
|
| reply-ip | Number | RO | DNS replies with an IP address. |
|
||||||
| reply-domain | Number | RO | DNS replies with a domain name. |
|
| reply-domain | Number | RO | DNS replies with a domain name. |
|
||||||
| reply-rrname | Number | RO | DNS replies with a resource record name. |
|
| reply-rrname | Number | RO | DNS replies with a resource record name. |
|
||||||
| reply-servfail | Number | RO | DNS replies indicating a server failure. |
|
| reply-servfail | Number | RO | DNS replies indicating a server failure. |
|
||||||
| reply-refused | Number | RO | DNS replies indicating refusal. |
|
| reply-refused | Number | RO | DNS replies indicating refusal. |
|
||||||
| reply-notimp | Number | RO | DNS replies indicating not implemented. |
|
| reply-notimp | Number | RO | DNS replies indicating not implemented. |
|
||||||
| reply-other | Number | RO | DNS replies with other statuses. |
|
| reply-other | Number | RO | DNS replies with other statuses. |
|
||||||
| reply-dnssec | Number | RO | DNS replies with DNSSEC information. |
|
| reply-dnssec | Number | RO | DNS replies with DNSSEC information. |
|
||||||
| reply-none | Number | RO | DNS replies with no data. |
|
| reply-none | Number | RO | DNS replies with no data. |
|
||||||
| reply-blob | Number | RO | DNS replies with a BLOB (binary large object). |
|
| 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. |
|
| dns-queries-all-replies | Number | RO | The total number of DNS queries with all reply types. |
|
||||||
| privacy-level | Number | RO | The privacy level setting. |
|
| privacy-level | Number | RO | The privacy level setting. |
|
||||||
| enabled | Switch | RO | The current status of blocking |
|
| enabled | Switch | RO | The current status of blocking |
|
||||||
| disable-enable | String | RW | Is blocking enabled/disabled |
|
| disable-enable | String | RW | Is blocking enabled/disabled |
|
||||||
| gravity-last-update | DateTime | RO | Last update of gravity |
|
| gravity-last-update | DateTime | RO | Last update of gravity |
|
||||||
| gravity-file-exists | DateTime | RO | Does gravity file exists |
|
| gravity-file-exists | DateTime | RO | Does gravity file exists |
|
||||||
|
|
||||||
## Full Example
|
## Full Example
|
||||||
|
|
||||||
@@ -77,7 +78,7 @@ Thing pihole:server:a4a077edb8 "Pi-hole" @ "Location"
|
|||||||
Type number : domains_being_blocked "Domains Blocked" [ ]
|
Type number : domains_being_blocked "Domains Blocked" [ ]
|
||||||
Type number : dns_queries_today "DNS Queries Today" [ ]
|
Type number : dns_queries_today "DNS Queries Today" [ ]
|
||||||
Type number : ads_blocked_today "Ads Blocked Today" [ ]
|
Type number : ads_blocked_today "Ads Blocked Today" [ ]
|
||||||
Type number : ads_percentage_today "Ads Percentage Today" [ ]
|
Type Number:Dimensionless : ads_percentage_today "Ads Percentage Today" [ ]
|
||||||
Type number : unique_domains "Unique Domains" [ ]
|
Type number : unique_domains "Unique Domains" [ ]
|
||||||
Type number : queries_forwarded "Queries Forwarded" [ ]
|
Type number : queries_forwarded "Queries Forwarded" [ ]
|
||||||
Type number : queries_cached "Queries Cached" [ ]
|
Type number : queries_cached "Queries Cached" [ ]
|
||||||
@@ -111,7 +112,7 @@ Thing pihole:server:a4a077edb8 "Pi-hole" @ "Location"
|
|||||||
Number domains_being_blocked "Domains Blocked" { channel="pihole:server:a4a077edb8:domains_being_blocked" }
|
Number domains_being_blocked "Domains Blocked" { channel="pihole:server:a4a077edb8:domains_being_blocked" }
|
||||||
Number dns_queries_today "DNS Queries Today" { channel="pihole:server:a4a077edb8:dns_queries_today" }
|
Number dns_queries_today "DNS Queries Today" { channel="pihole:server:a4a077edb8:dns_queries_today" }
|
||||||
Number ads_blocked_today "Ads Blocked Today" { channel="pihole:server:a4a077edb8:ads_blocked_today" }
|
Number ads_blocked_today "Ads Blocked Today" { channel="pihole:server:a4a077edb8:ads_blocked_today" }
|
||||||
Number ads_percentage_today "Ads Percentage Today" { channel="pihole:server:a4a077edb8:ads_percentage_today" }
|
Number:Dimensionless ads_percentage_today "Ads Percentage Today" { channel="pihole:server:a4a077edb8:ads_percentage_today" }
|
||||||
Number unique_domains "Unique Domains" { channel="pihole:server:a4a077edb8:unique_domains" }
|
Number unique_domains "Unique Domains" { channel="pihole:server:a4a077edb8:unique_domains" }
|
||||||
Number queries_forwarded "Queries Forwarded" { channel="pihole:server:a4a077edb8:queries_forwarded" }
|
Number queries_forwarded "Queries Forwarded" { channel="pihole:server:a4a077edb8:queries_forwarded" }
|
||||||
Number queries_cached "Queries Cached" { channel="pihole:server:a4a077edb8:queries_cached" }
|
Number queries_cached "Queries Cached" { channel="pihole:server:a4a077edb8:queries_cached" }
|
||||||
|
|||||||
+4
@@ -87,9 +87,13 @@ public class JettyAdminServiceV6 extends AdminService {
|
|||||||
var request = client.newRequest(authURI).timeout(TIMEOUT_SECONDS, SECONDS).method(HttpMethod.POST)
|
var request = client.newRequest(authURI).timeout(TIMEOUT_SECONDS, SECONDS).method(HttpMethod.POST)
|
||||||
.header(HttpHeader.ACCEPT, "application/json").content(new StringContentProvider(tokenJson));
|
.header(HttpHeader.ACCEPT, "application/json").content(new StringContentProvider(tokenJson));
|
||||||
var content = send(request).getContentAsString();
|
var content = send(request).getContentAsString();
|
||||||
|
logger.debug("Session update request answer: {}", content);
|
||||||
|
|
||||||
if (gson.fromJson(content, SessionAnswer.class) instanceof SessionAnswer answer) {
|
if (gson.fromJson(content, SessionAnswer.class) instanceof SessionAnswer answer) {
|
||||||
Session session = answer.session();
|
Session session = answer.session();
|
||||||
|
if (session == null) {
|
||||||
|
throw new PiHoleException("Received an empty session");
|
||||||
|
}
|
||||||
sid = session.sid();
|
sid = session.sid();
|
||||||
sessionValidity = Instant.now().plusSeconds(session.cautiousValidity());
|
sessionValidity = Instant.now().plusSeconds(session.cautiousValidity());
|
||||||
return session.sid();
|
return session.sid();
|
||||||
|
|||||||
+1
-1
@@ -20,5 +20,5 @@ import org.eclipse.jdt.annotation.Nullable;
|
|||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public record Blocking(boolean blocking, @Nullable Long timer) {
|
public record Blocking(boolean blocking, @Nullable Long timer) {
|
||||||
public static Blocking BLOCK = new Blocking(true, null);
|
public static final Blocking BLOCK = new Blocking(true, null);
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -70,10 +70,14 @@ public record ConfigAnswer(Config config, double took) {
|
|||||||
public record RateLimit(int count, int interval) {
|
public record RateLimit(int count, int interval) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record Domain(String name, boolean local) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public record Dns(List<String> upstreams, boolean cNAMEdeepInspect, boolean blockESNI, boolean edns0ecs,
|
public record Dns(List<String> upstreams, boolean cNAMEdeepInspect, boolean blockESNI, boolean edns0ecs,
|
||||||
boolean ignoreLocalhost, boolean showDNSSEC, boolean analyzeOnlyAandAAAA, String piholePTR,
|
boolean ignoreLocalhost, boolean showDNSSEC, boolean analyzeOnlyAandAAAA, String piholePTR,
|
||||||
String replyWhenBusy, int blockTTL, List<String> hosts, boolean domainNeeded, boolean expandHosts,
|
String replyWhenBusy, int blockTTL, List<String> hosts, boolean domainNeeded, boolean expandHosts,
|
||||||
String domain, boolean bogusPriv, boolean dnssec, String _interface, String hostRecord,
|
Domain domain, boolean bogusPriv, boolean dnssec, String _interface, String hostRecord,
|
||||||
String listeningMode, boolean queryLogging, List<Object> cnameRecords, int port, List<Object> revServers,
|
String listeningMode, boolean queryLogging, List<Object> cnameRecords, int port, List<Object> revServers,
|
||||||
Cache cache, Blocking blocking, SpecialDomains specialDomains, Reply reply, RateLimit rateLimit) {
|
Cache cache, Blocking blocking, SpecialDomains specialDomains, Reply reply, RateLimit rateLimit) {
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -13,12 +13,13 @@
|
|||||||
package org.openhab.binding.pihole.internal.rest.model.v6;
|
package org.openhab.binding.pihole.internal.rest.model.v6;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gaël L'hopital - Initial contribution
|
* @author Gaël L'hopital - Initial contribution
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public record SessionAnswer(Session session, double took) {
|
public record SessionAnswer(@Nullable Session session, double took) {
|
||||||
public record Session(boolean valid, boolean totp, String sid, String csrf, int validity, String message) {
|
public record Session(boolean valid, boolean totp, String sid, String csrf, int validity, String message) {
|
||||||
public int cautiousValidity() {
|
public int cautiousValidity() {
|
||||||
return validity / 3 * 2;
|
return validity / 3 * 2;
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ channel-type.pihole.number-channel.label = Number channel
|
|||||||
|
|
||||||
channel.ads_blocked_today.label = Ads Blocked Today
|
channel.ads_blocked_today.label = Ads Blocked Today
|
||||||
channel.ads_blocked_today.description = The number of ads blocked today.
|
channel.ads_blocked_today.description = The number of ads blocked today.
|
||||||
channel.ads_percentage_today.label = Ads Percentage Today
|
channel.ads_percentage_today.label = Ads Today
|
||||||
channel.ads_percentage_today.description = The percentage of ads blocked today.
|
channel.ads_percentage_today.description = The percentage of ads blocked today.
|
||||||
channel.clients_ever_seen.label = Clients Ever Seen
|
channel.clients_ever_seen.label = Clients Ever Seen
|
||||||
channel.clients_ever_seen.description = The total number of unique clients ever seen.
|
channel.clients_ever_seen.description = The total number of unique clients ever seen.
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
<label>Ads Blocked Today</label>
|
<label>Ads Blocked Today</label>
|
||||||
<description>The number of ads blocked today.</description>
|
<description>The number of ads blocked today.</description>
|
||||||
</channel>
|
</channel>
|
||||||
<channel id="ads-percentage-today" typeId="number-channel">
|
<channel id="ads-percentage-today" typeId="percentage-channel">
|
||||||
<label>Ads Percentage Today</label>
|
<label>Ads Today</label>
|
||||||
<description>The percentage of ads blocked today.</description>
|
<description>The percentage of ads blocked today.</description>
|
||||||
</channel>
|
</channel>
|
||||||
<channel id="unique-domains" typeId="number-channel">
|
<channel id="unique-domains" typeId="number-channel">
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
<channel id="disable-enable" typeId="disable-enable-channel"/>
|
<channel id="disable-enable" typeId="disable-enable-channel"/>
|
||||||
</channels>
|
</channels>
|
||||||
<properties>
|
<properties>
|
||||||
<property name="thingTypeVersion">1</property>
|
<property name="thingTypeVersion">2</property>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<config-description>
|
<config-description>
|
||||||
@@ -154,6 +154,11 @@
|
|||||||
<label>Number channel</label>
|
<label>Number channel</label>
|
||||||
<state readOnly="true"/>
|
<state readOnly="true"/>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
<channel-type id="percentage-channel">
|
||||||
|
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||||
|
<label>Percentage Channel</label>
|
||||||
|
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||||
|
</channel-type>
|
||||||
<channel-type id="enabled-channel">
|
<channel-type id="enabled-channel">
|
||||||
<item-type>Switch</item-type>
|
<item-type>Switch</item-type>
|
||||||
<label>Status</label>
|
<label>Status</label>
|
||||||
|
|||||||
+7
@@ -13,4 +13,11 @@
|
|||||||
</add-channel>
|
</add-channel>
|
||||||
</instruction-set>
|
</instruction-set>
|
||||||
</thing-type>
|
</thing-type>
|
||||||
|
<thing-type uid="pihole:server">
|
||||||
|
<instruction-set targetVersion="2">
|
||||||
|
<update-channel id="ads-percentage-today">
|
||||||
|
<type>pihole:percentage-channel</type>
|
||||||
|
</update-channel>
|
||||||
|
</instruction-set>
|
||||||
|
</thing-type>
|
||||||
</update:update-descriptions>
|
</update:update-descriptions>
|
||||||
Reference in New Issue
Block a user