2 # Checks inverter state as repoted by a metecontrol weblog
3 # device HTML interface, reports issues via Atlassian
4 # Opsgenie. Written with the intention to run via cron on
5 # a LTE Router with either OpenWRT or Teltonika RutOS.
6 # Requires curl for the Opsgenie part, otherwise
7 # sh/cut/cat/wget/test are enough.
9 # createAlert <alias> <message> <description>
13 local description="${3}"
15 if [ -z "${alias}" ]; then
16 echo "ERROR: Empty alert alias"
20 if [ -z "${message}" ]; then
21 echo "ERROR: Empty alert message"
25 curl -o /dev/null -s \
26 -X POST https://${API_HOST}/v2/alerts \
27 -H "Content-Type: application/json" \
28 -H "Authorization: GenieKey ${API_KEY}" \
31 \"message\":\"${message}\",
32 \"alias\":\"${alias}\",
33 \"description\":\"${description}\"
41 if [ -z "${alias}" ]; then
42 echo "ERROR: Empty alert alias"
46 curl -o /dev/null -s \
47 -X POST https://${API_HOST}/v2/alerts/${alias}/close?identifierType=alias \
48 -H "Authorization: GenieKey ${API_KEY}" \
49 -H "Content-Type: application/json" \
54 # parseMcLine <meteocontrol html page output line>
58 local wrleistung="$(echo ${input} | cut -d'>' -f 13 | cut -d'<' -f 1)"
59 local wradresse="$(echo ${input} | cut -d'>' -f 4 | cut -d'<' -f 1)"
60 local wrserial="$(echo ${input} | cut -d'>' -f 7 | cut -d'<' -f 1)"
62 # known bad case e.g. during the night
63 if [ "${wrleistung}" = "---" ]; then
64 echo "No Power Value at WR${wradresse} Serial:${wrserial}"
69 if [ "${wrleistung}" -gt 0 ]; then
74 echo "ERROR: WR${wradresse} ${wrleistung}W Serial:${wrserial}"
78 # parseMcOutput <meteocontrol status html output page>
82 if ! [ -f "${file}" ]; then
83 echo "ERROR: Supplied input ${file} is not a regular file"
87 grep "cLink" "${file}" | while read line; do
88 result="$(parseMcLine \"${line}\")"
90 if [ "${result}" = "OK" ]; then
94 echo -n "${result} -- "
98 # getMCstates <outfile> <status-url>
103 if [ -z "${outfile}" ]; then
104 echo "ERROR: no meteocontrol tmp file provided"
108 if [ -z "${url}" ]; then
109 echo "ERROR: no meteocontrol URL provided"
113 # remove eventual remains of prior runs
116 # ready to try to download the data from meteocontrol
117 if ! wget -q -O "${outfile}" "${url}"; then
118 echo "ERROR: could not download ${url} into ${outfile}"
122 # verify we have content to parse in our downloaded file
123 if ! grep -c -q cLink "${outfile}"; then
124 echo "ERROR: no matching cLink lines found in output file ${outfile}"
129 # checkAlertState <statefile> <new-status>
130 # return 0 on alert state change
131 # return 1 if nothing changed
133 local statefile="${1}"
134 local newstatus="${2}"
135 local oldstatus="null"
137 test -f "${statefile}" && oldstatus="$(cat ${statefile})"
138 if [ "${oldstatus}" = "${newstatus}" ]; then
142 # update state file on state change
143 echo "${newstatus}" > "${statefile}"
147 ### main configuration
148 API_HOST="api.eu.opsgenie.com"
151 # adjust meteocontrol default password and IPs
152 mc1="http://admin:ist02@192.168.1.2:80/html/de/onlineOverWr.html"
153 mc2="http://admin:ist02@192.168.1.3:80/html/de/onlineOverWr.html"
156 for dev in mc1 mc2; do
157 outfile="/tmp/${dev}.html"
158 statefile="/tmp/pvstate-${dev}"
159 url=$(eval echo \${$dev})
161 # download the html overview page from meteocontrol device
162 getMCstates "${outfile}" "${url}"
164 # parse the overview page and collect failures
165 failures=$(parseMcOutput "${outfile}")
167 # handle failures and alerting
168 if ! [ -z "${failures}" ]; then
169 checkAlertState "${statefile}" "FAILED" && \
170 createAlert "${dev}" "PV ${dev}" "${failures}"
174 # update alert state close alert on state change
175 checkAlertState "${statefile}" "OK" && \