From 1cc72345dc52dd6e4459306b0189c222170e3c57 Mon Sep 17 00:00:00 2001 From: John W Kerns Date: Tue, 12 Mar 2024 14:34:01 -0700 Subject: [PATCH 1/2] Added Palo Alto Firewall Dynamic Routing by HTTP --- .../6.4/README.md | 97 ++++ ...alto_firewall_dynamic_routing_by_http.yaml | 430 ++++++++++++++++++ README.md | 1 + 3 files changed, 528 insertions(+) create mode 100644 Network_Devices/Palo_Alto/template_palo_alto_firewall_dynamic_routing_by_http/6.4/README.md create mode 100644 Network_Devices/Palo_Alto/template_palo_alto_firewall_dynamic_routing_by_http/6.4/template_palo_alto_firewall_dynamic_routing_by_http.yaml diff --git a/Network_Devices/Palo_Alto/template_palo_alto_firewall_dynamic_routing_by_http/6.4/README.md b/Network_Devices/Palo_Alto/template_palo_alto_firewall_dynamic_routing_by_http/6.4/README.md new file mode 100644 index 000000000..600b998c1 --- /dev/null +++ b/Network_Devices/Palo_Alto/template_palo_alto_firewall_dynamic_routing_by_http/6.4/README.md @@ -0,0 +1,97 @@ +# Template Palo Alto Firewall Dynamic Routing by HTTP + +Monitor dynamic routing neighbors (OSPFv2, OSPFv3, and BGP) on a Palo Alto firewall using the XML API. + +Template requires the `{$PAN_API_KEY}` macro to be entered/overridden with an API key for a user on the firewall. A superuser can be used and will work, but if setting up a limited user with an Admin Role, make sure to include the [XML API / Operational Requests] permission in the Admin Role. + +Obtaining the API key from the firewall requires using the API. This can be done one of two ways: + +1. Use your browser to obtain the API key: Copy the URL example below and replace it with the firewall's IP/hostname as well as the username and password of the user you want to use. You should get an XML response with the API key contained within. Copy the API key and override the {$PAN_API_KEY} macro for monitored hosts. + - Browser URL: `https://X.X.X.X/api/?type=keygen&user=SOMEUSER&password=SUPERSECRETPASSWORD` + +2. Use CURL to query the firewall's API and obtain the API key: Copy the command example below and replace it with the firewall's IP/hostname as well as the username and password of the user you want to use. You should get an XML response with the API key contained within. Copy the API key and override the {$PAN_API_KEY} macro for monitored hosts. + - > Note: If your password uses special characters, you may need to escape them with backslashes. + - `curl -k -G -X GET "https://X.X.X.X/api/?type=keygen" --data-urlencode "user=SOMEUSER" --data-urlencode "password=SUPER\!SECRETPASSWORD"` + +## Macros used + +There are no macros links in this template. + +## Template links + +There are no template links in this template. + +## Discovery rules + +|Name|Description|Type|Key and additional info| +|----|-----------|----|----| +|BGP Neighbors|Pull a list of configured BGP neighbors and their states|Dependent Item|`bgp.neighbor.discovery`| +|OSPFv2 Neighbors|Pull a list of OSPFv2 adjacencies and their states|Dependent Item|`ospfv2.neighbor.discovery`| +|OSPFv3 Neighbors|Pull a list of OSPFv3 adjacencies and their states|Dependent Item|`ospfv3.neighbor.discovery`| + + + +## Items collected + +|Name|Description|Type|Key and additional info| +|----|-----------|----|----| +|Get BGP Neighbors|Retrieve list of BGP neighbors and their details|`HTTP agent`|`bgp.neighbors` - Used by discovery rule to enumerate BGP neighbors| +|Get OSPFv2 Neighbors|Retrieve list of OSPFv2 (IPv4) adjacencies and their details|`HTTP agent`|`ospfv2.neighbors` - Used by discovery rule to enumerate dynamic OSPFv2 adjacencies| +|Get OSPFv3 Neighbors|Retrieve list of OSPFv3 (IPv6) adjacencies and their details|`HTTP agent`|`ospfv3.neighbors` - Used by discovery rule to enumerate dynamic OSPFv3 adjacencies| +|High-Availability State|Retrieve the firewall's HA state|`HTTP agent`|`ha.state` - Used to determine if triggers should fire for states of neighbors/adjacencies.| + + + + +## Triggers + +|Name|Description|Expression|Priority| +|----|-----------|----------|--------| +|No API data for 5 minutes|-|

**Expression**: `nodata(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv2.neighbors,5m)=1 or nodata(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv3.neighbors,5m)=1 or nodata(/Palo Alto Firewall Dynamic Routing by HTTP/bgp.neighbors,5m)=1`

**Recovery expression**:

|high| + + + +## BGP Neighbors + +### Item Prototypes + +- BGP Neighbor `{#NEIGHBOR.VIRTUAL_ROUTER}`/`{#NEIGHBOR.PEER_GROUP}`/`{#NEIGHBOR.NAME}` (`{#NEIGHBOR.REMOTE_AS}`) Incoming Routes (Accepted) +- BGP Neighbor `{#NEIGHBOR.VIRTUAL_ROUTER}`/`{#NEIGHBOR.PEER_GROUP}`/`{#NEIGHBOR.NAME}` (`{#NEIGHBOR.REMOTE_AS}`) Incoming Routes (Total) +- BGP Neighbor `{#NEIGHBOR.VIRTUAL_ROUTER}`/`{#NEIGHBOR.PEER_GROUP}`/`{#NEIGHBOR.NAME}` (`{#NEIGHBOR.REMOTE_AS}`) Outgoing Routes (Advertised) +- BGP Neighbor `{#NEIGHBOR.VIRTUAL_ROUTER}`/`{#NEIGHBOR.PEER_GROUP}`/`{#NEIGHBOR.NAME}` (`{#NEIGHBOR.REMOTE_AS}`) Outgoing Routes (Total) +- BGP Neighbor `{#NEIGHBOR.VIRTUAL_ROUTER}`/`{#NEIGHBOR.PEER_GROUP}`/`{#NEIGHBOR.NAME}` (`{#NEIGHBOR.REMOTE_AS}`) State +- BGP Neighbor `{#NEIGHBOR.VIRTUAL_ROUTER}`/`{#NEIGHBOR.PEER_GROUP}`/`{#NEIGHBOR.NAME}` (`{#NEIGHBOR.REMOTE_AS}`) Status Flap Count + +### Trigger Prototypes + +- BGP Neighbor `{#NEIGHBOR.VIRTUAL_ROUTER}`/`{#NEIGHBOR.PEER_GROUP}`/`{#NEIGHBOR.NAME}` (`{#NEIGHBOR.REMOTE_AS}`) Down +- BGP Neighbor `{#NEIGHBOR.VIRTUAL_ROUTER}`/`{#NEIGHBOR.PEER_GROUP}`/`{#NEIGHBOR.NAME}` (`{#NEIGHBOR.REMOTE_AS}`) Flapped + + + +## OSPFv2 Neighbors + +### Item Prototypes + +- OSPFv2 Neighbor `{#NEIGHBOR.ROUTERID}` (`{#NEIGHBOR.ADDRESS}` - `{#NEIGHBOR.VIRTUAL_ROUTER}`) State + +### Trigger Prototypes + +- OSPFv2 Neighbor `{#NEIGHBOR.ROUTERID}` (`{#NEIGHBOR.ADDRESS}` - `{#NEIGHBOR.VIRTUAL_ROUTER}`) Disappeared +- OSPFv2 Neighbor `{#NEIGHBOR.ROUTERID}` (`{#NEIGHBOR.ADDRESS}` - `{#NEIGHBOR.VIRTUAL_ROUTER}`) State Changed +- OSPFv2 Neighbor `{#NEIGHBOR.ROUTERID}` (`{#NEIGHBOR.ADDRESS}` - `{#NEIGHBOR.VIRTUAL_ROUTER}`) Stuck + + + +## OSPFv3 Neighbors + +### Item Prototypes + +- OSPFv3 Neighbor `{#NEIGHBOR.ROUTERID}` (`{#NEIGHBOR.ADDRESS}` - `{#NEIGHBOR.VIRTUAL_ROUTER}` - Intf`{#NEIGHBOR.INTERFACE_ID}`) State +- OSPFv3 Neighbor `{#NEIGHBOR.ROUTERID}` (`{#NEIGHBOR.ADDRESS}` - `{#NEIGHBOR.VIRTUAL_ROUTER}` - Intf`{#NEIGHBOR.INTERFACE_ID}`) Status + +### Trigger Prototypes + +- OSPFv3 Neighbor `{#NEIGHBOR.ROUTERID}` (`{#NEIGHBOR.ADDRESS}` - `{#NEIGHBOR.VIRTUAL_ROUTER}` - Intf`{#NEIGHBOR.INTERFACE_ID}`) Disappeared +- OSPFv3 Neighbor `{#NEIGHBOR.ROUTERID}` (`{#NEIGHBOR.ADDRESS}` - `{#NEIGHBOR.VIRTUAL_ROUTER}` - Intf`{#NEIGHBOR.INTERFACE_ID}`) State Changed] +- OSPFv3 Neighbor `{#NEIGHBOR.ROUTERID}` (`{#NEIGHBOR.ADDRESS}` - `{#NEIGHBOR.VIRTUAL_ROUTER}` - Intf`{#NEIGHBOR.INTERFACE_ID}`) Stuck diff --git a/Network_Devices/Palo_Alto/template_palo_alto_firewall_dynamic_routing_by_http/6.4/template_palo_alto_firewall_dynamic_routing_by_http.yaml b/Network_Devices/Palo_Alto/template_palo_alto_firewall_dynamic_routing_by_http/6.4/template_palo_alto_firewall_dynamic_routing_by_http.yaml new file mode 100644 index 000000000..caec0f920 --- /dev/null +++ b/Network_Devices/Palo_Alto/template_palo_alto_firewall_dynamic_routing_by_http/6.4/template_palo_alto_firewall_dynamic_routing_by_http.yaml @@ -0,0 +1,430 @@ +zabbix_export: + version: '6.4' + template_groups: + - uuid: 36bff6c29af64692839d077febfc7079 + name: 'Templates/Network devices' + templates: + - uuid: 264e9f322b9c40d4b20c869e602c625b + template: 'Palo Alto Firewall Dynamic Routing by HTTP' + name: 'Palo Alto Firewall Dynamic Routing by HTTP' + description: | + Monitor dynamic routing neighbors (OSPFv2, OSPFv3, and BGP) on a Palo Alto firewall using the XML API. + + Template requires the `{$PAN_API_KEY}` macro to be entered/overridden with an API key for a user on the firewall. A superuser can be used and will work, but if setting up a limited user with an Admin Role, make sure to include the [XML API / Operational Requests] permission in the Admin Role. + + Obtaining the API key from the firewall requires using the API. This can be done one of two ways: + + 1. Use your browser to obtain the API key: Copy the URL example below and replace it with the firewall's IP/hostname as well as the username and password of the user you want to use. You should get an XML response with the API key contained within. Copy the API key and override the {$PAN_API_KEY} macro for monitored hosts. + - Browser URL: `https://X.X.X.X/api/?type=keygen&user=SOMEUSER&password=SUPERSECRETPASSWORD` + + 2. Use CURL to query the firewall's API and obtain the API key: Copy the command example below and replace it with the firewall's IP/hostname as well as the username and password of the user you want to use. You should get an XML response with the API key contained within. Copy the API key and override the {$PAN_API_KEY} macro for monitored hosts. + - > Note: If your password uses special characters, you may need to escape them with backslashes. + - `curl -k -G -X GET "https://X.X.X.X/api/?type=keygen" --data-urlencode "user=SOMEUSER" --data-urlencode "password=SUPER\!SECRETPASSWORD"` + groups: + - name: 'Templates/Network devices' + items: + - uuid: 56992db2ef094271883e23907124bdf5 + name: 'Get BGP Neighbors' + type: HTTP_AGENT + key: bgp.neighbors + history: 1d + trends: '0' + value_type: TEXT + description: 'Retrieve list of BGP neighbors and their details' + preprocessing: + - type: XML_TO_JSON + parameters: + - '' + - type: STR_REPLACE + parameters: + - '-' + - _ + - type: STR_REPLACE + parameters: + - '@' + - '' + - type: JAVASCRIPT + parameters: + - | + // Convert the JSON output to an array for processing by discovery and items + const data = JSON.parse(value) + // If there are no neighbors (data.response.result is null) + if (!data.response.result) { + // Return an empty array + return JSON.stringify([]) + // If result.entry is an array + } else if (Array.isArray(data.response.result.entry)) { + // Return it as is + return JSON.stringify(data.response.result.entry) + // If result.entry is a single object and not an array + } else { + // Return it as an array + return JSON.stringify([data.response.result.entry]) + } + timeout: 10s + url: 'https://{HOST.CONN}/api/' + query_fields: + - name: type + value: op + - name: cmd + value: '' + - name: key + value: '{$PAN_API_KEY}' + - uuid: f0525eae5e034e30915d8b222055cdc2 + name: 'High-Availability State' + type: HTTP_AGENT + key: ha.state + history: 1d + trends: '0' + value_type: TEXT + description: 'Retrieve the firewall''s HA state. Used to determine if triggers should fire for states of neighbors/adjacencies.' + preprocessing: + - type: XML_TO_JSON + parameters: + - '' + - type: STR_REPLACE + parameters: + - '-' + - _ + - type: STR_REPLACE + parameters: + - '@' + - '' + - type: JAVASCRIPT + parameters: + - | + // Convert the JSON output to a native JS objects + const data = JSON.parse(value) + // If the state info does not exist in the response + if (!data.response.result.group.local_info.state) { + // Return a friendly message + return 'No HA' + // If the state info does exist in the response + } else { + // Return it as a string + return data.response.result.group.local_info.state + } + timeout: 10s + url: 'https://{HOST.CONN}/api/' + query_fields: + - name: type + value: op + - name: cmd + value: '' + - name: key + value: '{$PAN_API_KEY}' + - uuid: 24a849bbebcd442a98a618704600a8f8 + name: 'Get OSPFv2 Neighbors' + type: HTTP_AGENT + key: ospfv2.neighbors + history: 1d + trends: '0' + value_type: TEXT + description: 'Retrieve list of OSPFv2 neighbors and their details' + preprocessing: + - type: XML_TO_JSON + parameters: + - '' + - type: STR_REPLACE + parameters: + - '-' + - _ + - type: JAVASCRIPT + parameters: + - | + // Convert the JSON output to an array for processing by discovery and items + const data = JSON.parse(value) + // If there are no neighbors (data.response.result is null) + if (!data.response.result) { + // Return an empty array + return JSON.stringify([]) + // If result.entry is an array + } else if (Array.isArray(data.response.result.entry)) { + // Return it as is + return JSON.stringify(data.response.result.entry) + // If result.entry is a single object and not an array + } else { + // Return it as an array + return JSON.stringify([data.response.result.entry]) + } + timeout: 10s + url: 'https://{HOST.CONN}/api/' + query_fields: + - name: type + value: op + - name: cmd + value: '' + - name: key + value: '{$PAN_API_KEY}' + - uuid: be4f67985ae241f8a8b3a42afa1f066e + name: 'Get OSPFv3 Neighbors' + type: HTTP_AGENT + key: ospfv3.neighbors + history: 1d + trends: '0' + value_type: TEXT + description: 'Retrieve list of OSPFv3 neighbors and their details' + preprocessing: + - type: XML_TO_JSON + parameters: + - '' + - type: STR_REPLACE + parameters: + - '-' + - _ + - type: JAVASCRIPT + parameters: + - | + // Convert the JSON output to an array for processing by discovery and items + const data = JSON.parse(value) + // If there are no neighbors (data.response.result is null) + if (!data.response.result) { + // Return an empty array + return JSON.stringify([]) + // If result.entry is an array + } else if (Array.isArray(data.response.result.entry)) { + // Return it as is + return JSON.stringify(data.response.result.entry) + // If result.entry is a single object and not an array + } else { + // Return it as an array + return JSON.stringify([data.response.result.entry]) + } + timeout: 10s + url: 'https://{HOST.CONN}/api/' + query_fields: + - name: type + value: op + - name: cmd + value: '' + - name: key + value: '{$PAN_API_KEY}' + discovery_rules: + - uuid: f1c32df4d08e484695bba058c79d86a6 + name: 'BGP Neighbors' + type: DEPENDENT + key: bgp.neighbor.discovery + delay: '0' + description: 'Pull a list of configured BGP neighbors and their states' + item_prototypes: + - uuid: 952b04ebe0a7496ea5400b4fd63b731a + name: 'BGP Neighbor {#NEIGHBOR.VIRTUAL_ROUTER}/{#NEIGHBOR.PEER_GROUP}/{#NEIGHBOR.NAME} ({#NEIGHBOR.REMOTE_AS}) Incoming Routes (Accepted)' + type: DEPENDENT + key: 'bgp.neighbor.acceptedroutesin.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.PEER_GROUP}.{#NEIGHBOR.NAME}]' + delay: '0' + trends: '0' + value_type: TEXT + preprocessing: + - type: JSONPATH + parameters: + - '$.[?(@.vr == ''{#NEIGHBOR.VIRTUAL_ROUTER}'' && @.peer_group == ''{#NEIGHBOR.PEER_GROUP}'' && @.peer == ''{#NEIGHBOR.NAME}'')].prefix_counter.entry.incoming_accepted.first()' + master_item: + key: bgp.neighbors + - uuid: 7bcb216fa9854121a097171c24fc16c7 + name: 'BGP Neighbor {#NEIGHBOR.VIRTUAL_ROUTER}/{#NEIGHBOR.PEER_GROUP}/{#NEIGHBOR.NAME} ({#NEIGHBOR.REMOTE_AS}) Outgoing Routes (Advertised)' + type: DEPENDENT + key: 'bgp.neighbor.advertisedroutesout.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.PEER_GROUP}.{#NEIGHBOR.NAME}]' + delay: '0' + trends: '0' + value_type: TEXT + preprocessing: + - type: JSONPATH + parameters: + - '$.[?(@.vr == ''{#NEIGHBOR.VIRTUAL_ROUTER}'' && @.peer_group == ''{#NEIGHBOR.PEER_GROUP}'' && @.peer == ''{#NEIGHBOR.NAME}'')].prefix_counter.entry.outgoing_advertised.first()' + master_item: + key: bgp.neighbors + - uuid: 7740f3a50813419ab69b25b712b09107 + name: 'BGP Neighbor {#NEIGHBOR.VIRTUAL_ROUTER}/{#NEIGHBOR.PEER_GROUP}/{#NEIGHBOR.NAME} ({#NEIGHBOR.REMOTE_AS}) State' + type: DEPENDENT + key: 'bgp.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.PEER_GROUP}.{#NEIGHBOR.NAME}]' + delay: '0' + trends: '0' + value_type: TEXT + preprocessing: + - type: JSONPATH + parameters: + - '$.[?(@.vr == ''{#NEIGHBOR.VIRTUAL_ROUTER}'' && @.peer_group == ''{#NEIGHBOR.PEER_GROUP}'' && @.peer == ''{#NEIGHBOR.NAME}'')].status.first()' + master_item: + key: bgp.neighbors + - uuid: 62887be5d3184673a0e973b524385e4f + name: 'BGP Neighbor {#NEIGHBOR.VIRTUAL_ROUTER}/{#NEIGHBOR.PEER_GROUP}/{#NEIGHBOR.NAME} ({#NEIGHBOR.REMOTE_AS}) Status Flap Count' + type: DEPENDENT + key: 'bgp.neighbor.statusflaps.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.PEER_GROUP}.{#NEIGHBOR.NAME}]' + delay: '0' + trends: '0' + value_type: TEXT + preprocessing: + - type: JSONPATH + parameters: + - '$.[?(@.vr == ''{#NEIGHBOR.VIRTUAL_ROUTER}'' && @.peer_group == ''{#NEIGHBOR.PEER_GROUP}'' && @.peer == ''{#NEIGHBOR.NAME}'')].status_flap_counts.first()' + master_item: + key: bgp.neighbors + - uuid: 5bf671d9324240d88301eb3c619aa522 + name: 'BGP Neighbor {#NEIGHBOR.VIRTUAL_ROUTER}/{#NEIGHBOR.PEER_GROUP}/{#NEIGHBOR.NAME} ({#NEIGHBOR.REMOTE_AS}) Incoming Routes (Total)' + type: DEPENDENT + key: 'bgp.neighbor.totalroutesin.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.PEER_GROUP}.{#NEIGHBOR.NAME}]' + delay: '0' + trends: '0' + value_type: TEXT + preprocessing: + - type: JSONPATH + parameters: + - '$.[?(@.vr == ''{#NEIGHBOR.VIRTUAL_ROUTER}'' && @.peer_group == ''{#NEIGHBOR.PEER_GROUP}'' && @.peer == ''{#NEIGHBOR.NAME}'')].prefix_counter.entry.incoming_total.first()' + master_item: + key: bgp.neighbors + - uuid: f12388d94a444f81b5375f785683ef54 + name: 'BGP Neighbor {#NEIGHBOR.VIRTUAL_ROUTER}/{#NEIGHBOR.PEER_GROUP}/{#NEIGHBOR.NAME} ({#NEIGHBOR.REMOTE_AS}) Outgoing Routes (Total)' + type: DEPENDENT + key: 'bgp.neighbor.totalroutesout.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.PEER_GROUP}.{#NEIGHBOR.NAME}]' + delay: '0' + trends: '0' + value_type: TEXT + preprocessing: + - type: JSONPATH + parameters: + - '$.[?(@.vr == ''{#NEIGHBOR.VIRTUAL_ROUTER}'' && @.peer_group == ''{#NEIGHBOR.PEER_GROUP}'' && @.peer == ''{#NEIGHBOR.NAME}'')].prefix_counter.entry.outgoing_total.first()' + master_item: + key: bgp.neighbors + trigger_prototypes: + - uuid: cd682604e50e4b0482999b5fc762d616 + expression: 'last(/Palo Alto Firewall Dynamic Routing by HTTP/bgp.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.PEER_GROUP}.{#NEIGHBOR.NAME}])<>"Established" and last(/Palo Alto Firewall Dynamic Routing by HTTP/ha.state)<>"passive"' + name: 'BGP Neighbor {#NEIGHBOR.VIRTUAL_ROUTER}/{#NEIGHBOR.PEER_GROUP}/{#NEIGHBOR.NAME} ({#NEIGHBOR.REMOTE_AS}) Down' + priority: HIGH + description: | + Neighbor state is not equal to "Established" + + If the firewall's HA status is "passive", then this trigger will not fire + - uuid: b6278a6641e24b66bc7812ed34baee42 + expression: 'change(/Palo Alto Firewall Dynamic Routing by HTTP/bgp.neighbor.statusflaps.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.PEER_GROUP}.{#NEIGHBOR.NAME}])=1 and last(/Palo Alto Firewall Dynamic Routing by HTTP/ha.state)<>"passive"' + name: 'BGP Neighbor {#NEIGHBOR.VIRTUAL_ROUTER}/{#NEIGHBOR.PEER_GROUP}/{#NEIGHBOR.NAME} ({#NEIGHBOR.REMOTE_AS}) Flapped' + priority: WARNING + description: | + Neighbor flap count changed + + If the firewall's HA status is "passive", then this trigger will not fire + manual_close: 'YES' + master_item: + key: bgp.neighbors + lld_macro_paths: + - lld_macro: '{#NEIGHBOR.NAME}' + path: $.peer + - lld_macro: '{#NEIGHBOR.PEER_GROUP}' + path: $.peer_group + - lld_macro: '{#NEIGHBOR.REMOTE_AS}' + path: $.remote_as + - lld_macro: '{#NEIGHBOR.VIRTUAL_ROUTER}' + path: $.vr + - uuid: 6cbaa20de6bd40b4ab46f0a2ffa25bc7 + name: 'OSPFv2 Neighbors' + type: DEPENDENT + key: ospfv2.neighbor.discovery + delay: '0' + description: 'Pull a list of OSPFv2 adjacencies and their states' + item_prototypes: + - uuid: 6ede889a67b64761b436f90ae58e3f96 + name: 'OSPFv2 Neighbor {#NEIGHBOR.ROUTERID} ({#NEIGHBOR.ADDRESS} - {#NEIGHBOR.VIRTUAL_ROUTER}) State' + type: DEPENDENT + key: 'ospfv2.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}:{#NEIGHBOR.ADDRESS}]' + delay: '0' + trends: '0' + value_type: TEXT + preprocessing: + - type: JSONPATH + parameters: + - '$.[?(@.virtual_router == ''{#NEIGHBOR.VIRTUAL_ROUTER}'' && @.neighbor_address == ''{#NEIGHBOR.ADDRESS}'')].status.first()' + master_item: + key: ospfv2.neighbors + trigger_prototypes: + - uuid: ba23dc840f0b4363827c39a95ef5981a + expression: 'change(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv2.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}:{#NEIGHBOR.ADDRESS}])=1' + name: 'OSPFv2 Neighbor {#NEIGHBOR.ROUTERID} ({#NEIGHBOR.ADDRESS} - {#NEIGHBOR.VIRTUAL_ROUTER}) State Changed' + priority: WARNING + description: 'The neighbor state changed since the last query' + manual_close: 'YES' + - uuid: 7372a0cca43943068517339d3e35fa71 + expression: '(last(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv2.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}:{#NEIGHBOR.ADDRESS}])<>"full") and (last(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv2.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}:{#NEIGHBOR.ADDRESS}])<>"2way")' + name: 'OSPFv2 Neighbor {#NEIGHBOR.ROUTERID} ({#NEIGHBOR.ADDRESS} - {#NEIGHBOR.VIRTUAL_ROUTER}) Stuck' + priority: AVERAGE + description: 'Neighbor state is not equal to "full" or "2way"' + trigger_prototypes: + - uuid: 64d858956eeb4bba9eacd8657204e7c8 + expression: 'nodata(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv2.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}:{#NEIGHBOR.ADDRESS}],3m,"strict")=1 and nodata(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv2.neighbors,2m,"strict")=0' + name: 'OSPFv2 Neighbor {#NEIGHBOR.ROUTERID} ({#NEIGHBOR.ADDRESS} - {#NEIGHBOR.VIRTUAL_ROUTER}) Disappeared' + priority: HIGH + description: 'The neighbor state item has no data or neighbor has disappeared from the firewall' + master_item: + key: ospfv2.neighbors + lld_macro_paths: + - lld_macro: '{#NEIGHBOR.ADDRESS}' + path: $.neighbor_address + - lld_macro: '{#NEIGHBOR.ROUTERID}' + path: $.neighbor_router_id + - lld_macro: '{#NEIGHBOR.VIRTUAL_ROUTER}' + path: $.virtual_router + - uuid: 400194a90a94481e925e30ff36848da6 + name: 'OSPFv3 Neighbors' + type: DEPENDENT + key: ospfv3.neighbor.discovery + delay: '0' + description: 'Pull a list of OSPFv3 adjacencies and their states' + item_prototypes: + - uuid: 7a40fc7c070c41dfaf7164af83fad6a8 + name: 'OSPFv3 Neighbor {#NEIGHBOR.ROUTERID} ({#NEIGHBOR.ADDRESS} - {#NEIGHBOR.VIRTUAL_ROUTER} - Intf{#NEIGHBOR.INTERFACE_ID}) State' + type: DEPENDENT + key: 'ospfv3.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}.{#NEIGHBOR.ADDRESS}.{#NEIGHBOR.INTERFACE_ID}]' + delay: '0' + trends: '0' + value_type: TEXT + preprocessing: + - type: JSONPATH + parameters: + - '$.[?(@.neighbor_link_local == ''{#NEIGHBOR.ADDRESS}'' && @.local_if_id == ''{#NEIGHBOR.INTERFACE_ID}'')].state.first()' + master_item: + key: ospfv3.neighbors + trigger_prototypes: + - uuid: 09c43ed525db4c0cb6ce0cc82433c63b + expression: 'change(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv3.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}.{#NEIGHBOR.ADDRESS}.{#NEIGHBOR.INTERFACE_ID}])=1' + name: 'OSPFv3 Neighbor {#NEIGHBOR.ROUTERID} ({#NEIGHBOR.ADDRESS} - {#NEIGHBOR.VIRTUAL_ROUTER} - Intf{#NEIGHBOR.INTERFACE_ID}) State Changed' + priority: WARNING + description: 'The neighbor state changed since the last query' + manual_close: 'YES' + - uuid: 0055949c42c14d84b8ecba5622b07b39 + expression: '(last(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv3.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}.{#NEIGHBOR.ADDRESS}.{#NEIGHBOR.INTERFACE_ID}])<>"full") and (last(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv3.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}.{#NEIGHBOR.ADDRESS}.{#NEIGHBOR.INTERFACE_ID}])<>"2way")' + name: 'OSPFv3 Neighbor {#NEIGHBOR.ROUTERID} ({#NEIGHBOR.ADDRESS} - {#NEIGHBOR.VIRTUAL_ROUTER} - Intf{#NEIGHBOR.INTERFACE_ID}) Stuck' + priority: AVERAGE + description: 'Neighbor state is not equal to "full" or "2way"' + - uuid: 8a3ddd5ae52c45c69beee1722ed85840 + name: 'OSPFv3 Neighbor {#NEIGHBOR.ROUTERID} ({#NEIGHBOR.ADDRESS} - {#NEIGHBOR.VIRTUAL_ROUTER} - Intf{#NEIGHBOR.INTERFACE_ID}) Status' + type: DEPENDENT + key: 'ospfv3.neighbor.status.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}.{#NEIGHBOR.ADDRESS}.{#NEIGHBOR.INTERFACE_ID}]' + delay: '0' + trends: '0' + value_type: TEXT + preprocessing: + - type: JSONPATH + parameters: + - '$.[?(@.neighbor_link_local == ''{#NEIGHBOR.ADDRESS}'' && @.local_if_id == ''{#NEIGHBOR.INTERFACE_ID}'')].status.first()' + master_item: + key: ospfv3.neighbors + trigger_prototypes: + - uuid: f1f8dcddb69d47058caaf37eb42d415e + expression: 'nodata(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv3.neighbor.state.[{#NEIGHBOR.VIRTUAL_ROUTER}.{#NEIGHBOR.ROUTERID}.{#NEIGHBOR.ADDRESS}.{#NEIGHBOR.INTERFACE_ID}],3m,"strict")=1 and nodata(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv3.neighbors,2m,"strict")=0' + name: 'OSPFv3 Neighbor {#NEIGHBOR.ROUTERID} ({#NEIGHBOR.ADDRESS} - {#NEIGHBOR.VIRTUAL_ROUTER} - Intf{#NEIGHBOR.INTERFACE_ID}) Disappeared' + priority: HIGH + description: 'The neighbor state item has no data or neighbor has disappeared from the firewall' + master_item: + key: ospfv3.neighbors + lld_macro_paths: + - lld_macro: '{#NEIGHBOR.ADDRESS}' + path: $.neighbor_link_local + - lld_macro: '{#NEIGHBOR.INTERFACE_ID}' + path: $.local_if_id + - lld_macro: '{#NEIGHBOR.ROUTERID}' + path: $.neighbor_id + - lld_macro: '{#NEIGHBOR.VIRTUAL_ROUTER}' + path: $.virtual_router + triggers: + - uuid: 010de81659dd4baa952c75b5ca22cdc4 + expression: 'nodata(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv2.neighbors,5m)=1 or nodata(/Palo Alto Firewall Dynamic Routing by HTTP/ospfv3.neighbors,5m)=1 or nodata(/Palo Alto Firewall Dynamic Routing by HTTP/bgp.neighbors,5m)=1' + name: 'No API data for 5 minutes' + priority: HIGH diff --git a/README.md b/README.md index 95952ecdd..5ccb264ba 100644 --- a/README.md +++ b/README.md @@ -398,6 +398,7 @@ This repository is dedicated to templates that are created and maintained by Zab * [Newtec](Network_Devices/Other/template_zabbix-newtecel470_satellite_modem) * [Palo_Alto](Network_Devices/Palo_Alto) * [Palo_Alto_Firewall](Network_Devices/Palo_Alto/template_palo_alto_firewall) + * [Palo Alto Firewall Dynamic Routing by HTTP](Network_Devices/Palo_Alto/template_palo_alto_firewall_dynamic_routing_by_http) * [Palo_Alto_PA200](Network_Devices/Palo_Alto/template_palo_alto_pa-200_pan-os_ver.6.0.x) * [Palo Alto SNMPv3 Auth Priv](Network_Devices/Palo_Alto/template_palo_alto_snmpv3) * [Palo Alto SNMPv2 64-bit counters](Network_Devices/Palo_Alto/template_palo_alto_with_64-bit_counters_(snmpv2)) From 0a64afe30c12561a9c5c6162d419a36ccb0497ca Mon Sep 17 00:00:00 2001 From: John W Kerns Date: Tue, 12 Mar 2024 15:14:40 -0700 Subject: [PATCH 2/2] Added Ambient Weather by HTTP --- README.md | 1 + .../Ambient_Weather/6.4/README.md | 70 +++++ .../6.4/template_ambient_weather.yaml | 270 ++++++++++++++++++ 3 files changed, 341 insertions(+) create mode 100644 Weather_Measurements/Ambient_Weather/6.4/README.md create mode 100644 Weather_Measurements/Ambient_Weather/6.4/template_ambient_weather.yaml diff --git a/README.md b/README.md index 5ccb264ba..ece83d40f 100644 --- a/README.md +++ b/README.md @@ -1002,5 +1002,6 @@ This repository is dedicated to templates that are created and maintained by Zab * [VM VMware UUID VM Standalone](Virtualization/VMware/template_vmware_uuid_vm_standalone) * [..Docker.OSLinux.ShortTermContainers](Virtualization/template_docker) * [Weather_Measurements](Weather_Measurements) + * [Ambient Weather by HTTP](Weather_Measurements/Ambient_Weather) * [Sonicwall SNMP - TZ600](Weather_Measurements/template_sensor_temp_e_umidade) * [ZBX-ESP-ENV](Weather_Measurements/template_temperature_and_humidity_monitoring_for_zabbix_using_esp8266_and_dht11_sensors) diff --git a/Weather_Measurements/Ambient_Weather/6.4/README.md b/Weather_Measurements/Ambient_Weather/6.4/README.md new file mode 100644 index 000000000..27d4a2da8 --- /dev/null +++ b/Weather_Measurements/Ambient_Weather/6.4/README.md @@ -0,0 +1,70 @@ +# Template Ambient Weather by HTTP + +Gather weather stats from your Ambient Weather station using your Ambient Weather online account. + +You will need to replace the `{$AWNET.APPLICATIONKEY}` and `{$AWNET.APIKEY}` macros with a developer application key and an API key. + +Zabbix server will poll the Ambient Weather website API to pull data. Zabbix does not poll the weather station directly. + +To generate an **Application Key**: + +- Log in to your Ambient Weather web dashboard +- Navigate to your profile +- Scroll to the "API Keys" section +- Click on the link in the text "Developers: An Application Key is also required for each application that you develop. **Click here** to create one." +- Enter a description in the field and click "**Create Application Key**" + +To generate an **API Key**: + +- Log in to your Ambient Weather web dashboard +- Navigate to your profile +- Scroll to the "API Keys" section +- Click on the "**Create Application Key**" button +- Give the API key a name if desired + + + +## Macros used + +|Name|Description|Default|Type| +|----|-----------|-------|----| +|`{$AWNET.APPLICATIONKEY}`|Ambient Weather generated application key|none|Text macro| +|`{$AWNET.APIKEY}`|Ambient Weather generated API key|none|Text macro| + + + +## Discovery rules + +|Name|Description|Type|Key and additional info| +|----|-----------|----|----| +|Get Stats|Process weather station data into items|Dependent Item|`tempf[{#DEVICE.MAC}]`| + + + +## Items collected + +|Name|Description|Type|Key and additional info| +|----|-----------|----|----| +|Get Devices|Get a list of Ambient Weather stations from the account to be used by the discovery rule|`HTTP agent`|`devices`| +|`{#DEVICE.NAME}` Barometric Pressure (Absolute)|Barometric Pressure (Absolute)|`Dependent Item`|`baromabsin[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Barometric Pressure (Relative)|Barometric Pressure (Relative)|`Dependent Item`|`baromrelin[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Indoor Dew Point|Indoor Dew Point|`Dependent Item`|`dewPointin[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Outdoor Dew Point|Outdoor Dew Point|`Dependent Item`|`dewPoint[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Indoor Feels Like|Indoor Feels Like|`Dependent Item`|`feelsLikein[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Outdoor Feels Like|Outdoor Feels Like|`Dependent Item`|`feelsLike[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Indoor Humidity|Indoor Humidity|`Dependent Item`|`humidityin[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Outdoor Humidity|Outdoor Humidity|`Dependent Item`|`humidity[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Solar Radiation|Solar Radiation|`Dependent Item`|`solarradiation[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Indoor Temperature (C)|Indoor Temperature (C)|`Dependent Item`|`tempinc[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Indoor Temperature|Indoor Temperature|`Dependent Item`|`tempin[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Outdoor Temperature (C)|Outdoor Temperature (C)|`Dependent Item`|`tempoutc[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Outdoor Temperature|Outdoor Temperature|`Dependent Item`|`tempout[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Wind Direction|Wind Direction|`Dependent Item`|`winddir[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Wind Gust|Wind Gust|`Dependent Item`|`windgustmph[{#DEVICE.MAC}]`| +|`{#DEVICE.NAME}` Wind Speed|Wind Speed|`Dependent Item`|`windspeedmph[{#DEVICE.MAC}]`| + + + +## Triggers + +There are no triggers in this template. diff --git a/Weather_Measurements/Ambient_Weather/6.4/template_ambient_weather.yaml b/Weather_Measurements/Ambient_Weather/6.4/template_ambient_weather.yaml new file mode 100644 index 000000000..3625cadbd --- /dev/null +++ b/Weather_Measurements/Ambient_Weather/6.4/template_ambient_weather.yaml @@ -0,0 +1,270 @@ +zabbix_export: + version: '6.4' + template_groups: + - uuid: 7df96b18c230490a9a0a9e2307226338 + name: Templates + - uuid: c2c162144c2d4c5491c8801193af4945 + name: Templates/Cloud + templates: + - uuid: 558c11af8e9249159ae1d969ca055900 + template: 'Ambient Weather by HTTP' + name: 'Ambient Weather by HTTP' + description: | + Gather weather stats from your Ambient Weather station using your Ambient Weather online account. + + You will need to replace the `{$AWNET.APPLICATIONKEY}` and `{$AWNET.APIKEY}` macros with a developer application key and an API key. + + Zabbix server will poll the Ambient Weather website API to pull data. Zabbix does not poll the weather station directly. + + To generate an **Application Key**: + + - Log in to your Ambient Weather web dashboard + - Navigate to your profile + - Scroll to the "API Keys" section + - Click on the link in the text "Developers: An Application Key is also required for each application that you develop. **Click here** to create one." + - Enter a description in the field and click "**Create Application Key**" + + To generate an **API Key**: + + - Log in to your Ambient Weather web dashboard + - Navigate to your profile + - Scroll to the "API Keys" section + - Click on the "**Create Application Key**" button + - Give the API key a name if desired + groups: + - name: Templates + - name: Templates/Cloud + items: + - uuid: 72f54170526a4240bceed5e47b2a9928 + name: 'Get Devices' + type: HTTP_AGENT + key: devices + history: '0' + trends: '0' + value_type: TEXT + description: 'Get a list of Ambient Weather stations from the account to be used by the discovery rule' + timeout: 10s + url: 'https://rt.ambientweather.net/v1/devices' + query_fields: + - name: applicationKey + value: '{$AWNET.APPLICATIONKEY}' + - name: apiKey + value: '{$AWNET.APIKEY}' + output_format: JSON + discovery_rules: + - uuid: 4889dcd807974b208a1d65822a7e489a + name: 'Get Stats' + type: DEPENDENT + key: 'tempf[{#DEVICE.MAC}]' + delay: '0' + description: 'Process weather station data into items' + item_prototypes: + - uuid: 6a5fece782c7434db5089d7de060ca0f + name: '{#DEVICE.NAME} Barometric Pressure (Absolute)' + type: DEPENDENT + key: 'baromabsin[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: 'in Hg' + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.baromabsin.first()' + master_item: + key: devices + - uuid: 51c7449742a242b78944e88125032e40 + name: '{#DEVICE.NAME} Barometric Pressure (Relative)' + type: DEPENDENT + key: 'baromrelin[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: 'in Hg' + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.baromrelin.first()' + master_item: + key: devices + - uuid: 28f21b68c2f8403c9fe35e49f92d6765 + name: '{#DEVICE.NAME} Indoor Dew Point' + type: DEPENDENT + key: 'dewPointin[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: F + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.dewPointin.first()' + master_item: + key: devices + - uuid: d80e4f8c6c3c49a08f9294db8a00375d + name: '{#DEVICE.NAME} Outdoor Dew Point' + type: DEPENDENT + key: 'dewPoint[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: F + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.dewPoint.first()' + master_item: + key: devices + - uuid: 5e3b4b33c16546c588f3741a83edc679 + name: '{#DEVICE.NAME} Indoor Feels Like' + type: DEPENDENT + key: 'feelsLikein[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: F + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.feelsLikein.first()' + master_item: + key: devices + - uuid: eec6d05a5ba84846a439493911f1be48 + name: '{#DEVICE.NAME} Outdoor Feels Like' + type: DEPENDENT + key: 'feelsLike[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: F + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.feelsLike.first()' + master_item: + key: devices + - uuid: 325a9916d962457a8089e9e3ffe3e27e + name: '{#DEVICE.NAME} Indoor Humidity' + type: DEPENDENT + key: 'humidityin[{#DEVICE.MAC}]' + delay: '0' + units: '%' + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.humidityin.first()' + master_item: + key: devices + - uuid: 8d197177a95a4b9d85318b9c43cd50db + name: '{#DEVICE.NAME} Outdoor Humidity' + type: DEPENDENT + key: 'humidity[{#DEVICE.MAC}]' + delay: '0' + units: '%' + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.humidity.first()' + master_item: + key: devices + - uuid: 155b1a4093c54ca9ad9c237e0cb9df3e + name: '{#DEVICE.NAME} Solar Radiation' + type: DEPENDENT + key: 'solarradiation[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: W/M² + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.solarradiation.first()' + master_item: + key: devices + - uuid: f8aeedd5864c4c0a931cc23c91e0153e + name: '{#DEVICE.NAME} Indoor Temperature (C)' + type: CALCULATED + key: 'tempinc[{#DEVICE.MAC}]' + value_type: FLOAT + units: C + params: '(last(//tempin[{#DEVICE.MAC}])-32)*(5/9)' + - uuid: b52a30bf002f4737ad56ec6cdc1b639b + name: '{#DEVICE.NAME} Indoor Temperature' + type: DEPENDENT + key: 'tempin[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: F + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.tempinf.first()' + master_item: + key: devices + - uuid: 53e4ea8ee7a34d24afe4ed40b8668bd1 + name: '{#DEVICE.NAME} Outdoor Temperature (C)' + type: CALCULATED + key: 'tempoutc[{#DEVICE.MAC}]' + value_type: FLOAT + units: C + params: '(last(//tempout[{#DEVICE.MAC}])-32)*(5/9)' + - uuid: 218199edfaf248de95abba4825ec1b87 + name: '{#DEVICE.NAME} Outdoor Temperature' + type: DEPENDENT + key: 'tempout[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: F + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.tempf.first()' + master_item: + key: devices + - uuid: 13fab80670c040c3b317fb1d66bb2b09 + name: '{#DEVICE.NAME} Wind Direction' + type: DEPENDENT + key: 'winddir[{#DEVICE.MAC}]' + delay: '0' + units: ° + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.winddir.first()' + master_item: + key: devices + - uuid: 98b796619a3844bcb01c29d09758670a + name: '{#DEVICE.NAME} Wind Gust' + type: DEPENDENT + key: 'windgustmph[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: MPH + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.windgustmph.first()' + master_item: + key: devices + - uuid: eaee255341b746b099362d200e45f731 + name: '{#DEVICE.NAME} Wind Speed' + type: DEPENDENT + key: 'windspeedmph[{#DEVICE.MAC}]' + delay: '0' + value_type: FLOAT + units: MPH + preprocessing: + - type: JSONPATH + parameters: + - '$.body.[?(@.macAddress == ''{#DEVICE.MAC}'')].lastData.windspeedmph.first()' + master_item: + key: devices + master_item: + key: devices + lld_macro_paths: + - lld_macro: '{#DEVICE.MAC}' + path: $.macAddress + - lld_macro: '{#DEVICE.NAME}' + path: $.info.name + preprocessing: + - type: JSONPATH + parameters: + - $.body + macros: + - macro: '{$AWNET.APIKEY}' + value: xxxxxxxxxxxxxxxxxxxxx + - macro: '{$AWNET.APPLICATIONKEY}' + value: xxxxxxxxxxxxxxxxxxxxx