-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpollen-virtual-sensor.groovy
145 lines (117 loc) · 4.14 KB
/
pollen-virtual-sensor.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* Pollen Virtual Sensor
*
* Author: jschlackman ([email protected])
* Version: 1.0
* Date: 2024-05-05
*
*/
metadata {
definition (
name: "Pollen Virtual Sensor",
namespace: "jschlackman",
author: "James Schlackman",
description: "Retrieves airborne pollen data from Pollen.com",
documentationLink: "https://github.com/jschlackman/PollenThing"
) {
capability "Sensor"
capability "Polling"
attribute "index", "number"
attribute "category", "enum", ["Low","Low-Medium","Medium","Medium-High","High"]
attribute "categoryColor", "string"
attribute "triggers", "string"
attribute "location", "string"
command "refresh"
}
preferences {
input name: "zipCode", type: "text", title: "Zip Code (optional)", required: false
}
}
// Parse events into attributes. This will never be called but needs to be present in the DTH code.
def parse(String description) {
log.debug("Pollen Sensor: Parsing '${description}'")
}
def installed() {
runEvery3Hours(poll)
poll()
}
def updated() {
poll()
}
def uninstalled() {
unschedule()
}
// handle commands
def poll() {
def pollenZip = null
// Use hub zipcode if user has not defined their own
if(zipCode) {
pollenZip = zipCode
} else {
pollenZip = location.zipCode
}
log.debug("Getting pollen data for ZIP: ${pollenZip}")
// Set up the Pollen.com API query
def params = [
uri: 'https://www.pollen.com/api/forecast/current/pollen/',
path: pollenZip,
headers: [Referer:'https://www.pollen.com']
]
try {
// Send query to the Pollen.com API
httpGet(params) {resp ->
// If we got a valid response
if (resp.data.ForecastDate) {
log.debug("Forecast retreived for ${resp.data.ForecastDate}")
// Parse the periods data array
resp.data.Location.periods.each {period ->
// Only interested in today's forecast
if (period.Type == 'Today') {
// Pollen index
send(name: "index", value: period.Index, descriptionText: "Pollen index is ${period.Index}")
def catName = ""
def catColor = ""
def indexNum = period.Index.toFloat()
// Set the category according to index thresholds
if (indexNum < 2.5) {catName = "Low"; catColor ="#90d2a7"}
else if (indexNum < 4.9) {catName = "Low-Medium"; catColor ="#44b621"}
else if (indexNum < 7.3) {catName = "Medium"; catColor ="#f1d801"}
else if (indexNum < 9.7) {catName = "Medium-High"; catColor ="#d04e00"}
else if (indexNum < 12) {catName = "High"; catColor ="#bc2323"}
else {catName = "Unknown"; catColor ="#000000"}
send(name: "category", value: catName, descriptionText: "Pollen level is ${catName}")
send(name: "categoryColor", value: catColor, descriptionText: "Pollen level color definition for display")
// Build the list of allergen triggers
def triggersList = period.Triggers.inject([]) { result, entry ->
result << "${entry.Name}"
}.join(", ")
send(name: "triggers", value: triggersList, descriptionText: "Top allergens in the reported location are ${triggersList}")
}
// Forecast location
send(name: "location", value: resp.data.Location.DisplayLocation, descriptionText: "Current allergy report for ${resp.data.Location.DisplayLocation}")
}
} else {
log.error("No valid data returned from Pollen.com API")
log.debug(resp);
}
}
}
catch (SocketTimeoutException e) {
log.error("Connection to Pollen.com API timed out.")
send(name: "location", value: "Timed out", descriptionText: "Connection timed out while retrieving data from API")
}
catch (e) {
log.error("Could not retrieve pollen data: $e")
send(name: "location", value: "Unknown error", descriptionText: "Could not retrieve data from API")
}
}
def refresh() {
poll()
}
def configure() {
poll()
}
private send(map) {
//log.debug("Pollen: event: $map")
sendEvent(map)
}