# @name EcoTrackerMonitor # @desc Stromverbrauch+Zählerstände eines EcoTracker IR von Everhome # @author Töm (taschenserver im Discord) # @version 0.3 # @config ecotracker_ip text "EcoTracker Netzwerkadresse/IP-Adresse" default=ecotracker.local maxlen=253 # @config refreshrate number "Datenaktualisierungrate" default=5 min=2 max=600 unit=Sek. # @config duration number "Anzeigedauer" default=5 min=1 max=600 unit=Sek. # @config hold_powercounter number "Zählerstand-/WLAN-Infos Dauer (mittlere Taste)" default=10 min=2 max=600 unit=Sek. # @config max_cons number "Max. Stromverbrauch pro Phase" default=3600 min=0 max=3600 unit=Watt # @config max_feed_in number "Max. Einspeisung pro Phase" default=3600 min=0 max=3600 unit=Watt # @config WiFi_signal_strength bool "Indikator WLAN-Signalstärke anzeigen" default=true # @config power_consumption color "Stromverbrauch" default=0xFF0000 # @config power_feed_in color "Einspeisung" default=0x00FF00 # @config zero_power_consumption color "0-Verbrauch" default=0x666666 class EcoTrackerMon var url, ssid var durationMs, power, rssi, ticks, maxticks, eStatticks, holdStat, max_cons, max_feed_in, hc, busel var phases var pc, pf, p0 var eCO, eCI, eCI1, eCI2 var wifiInd def _color_from_value(value) var m = self.max_cons var c = self.pc if value < 0 value = -value m = self.max_feed_in c = self.pf end if value > m value = m end if value == 0 value = int(self.p0) else var f = 0.30 + 0.70 * (real(value) / m) var r = int(((c >> 16) & 0xFF) * f) var g = int(((c >> 8) & 0xFF) * f) var b = int(( c & 0xFF) * f) value = (r << 16) | (g << 8) | b end return value end def init() self.url = "http://"+store.get("ecotracker_ip", "192.168.178.99")+"/v1/json" self.durationMs = store.get("duration",5)*1000 self.power = nil self.rssi = nil self.ssid = nil self.phases = [0,0,0] self.maxticks = store.get("refreshrate",5) self.max_cons = store.get("max_cons",3600) self.max_feed_in = store.get("max_feed_in",3600) self.pc = store.get("power_consumption",0xFF0000) self.pf = store.get("power_feed_in",0x00FF00) self.p0 = store.get("zero_power_consumption",0x666666) self.wifiInd = store.get("WiFi_signal_strength",true) self.ticks = 0 self.busel = 0 self.eStatticks = 0 self.hc = store.get("hold_powercounter",10) end def on_body(body, status) if status == 401 log("token rejected") return end if body == nil return end m = re.search("\"power\":\\s*(-?\\d+)", body) if m != nil self.power = num(m[1]) end m = re.search("\"rssi\":\\s*(-?\\d+)", body) if m != nil self.rssi = num(m[1]) end m = re.search("\"ssid\":\\s*\"([^\"]*)\"", body) if m != nil self.ssid = m[1] end m = re.search("\"powerPhase1\":\\s*(-?\\d+)", body) if m != nil self.phases[0] = num(m[1]) end m = re.search("\"powerPhase2\":\\s*(-?\\d+)", body) if m != nil self.phases[1] = num(m[1]) end m = re.search("\"powerPhase3\":\\s*(-?\\d+)", body) if m != nil self.phases[2] = num(m[1]) end m = re.search("\"energyCounterOut\":\\s*(-?\\d+)", body) if m != nil self.eCO = round(real(m[1])/1000,1) end m = re.search("\"energyCounterIn\":\\s*(-?\\d+)", body) if m != nil self.eCI = round(real(m[1])/1000,1) end m = re.search("\"energyCounterInT1\":\\s*(-?\\d+)", body) if m != nil self.eCI1 = round(real(m[1])/1000,1) end m = re.search("\"energyCounterInT2\":\\s*(-?\\d+)", body) if m != nil self.eCI2 = round(real(m[1])/1000,1) end end def duration() return self.durationMs end def loop() if self.ticks <= 0 self.ticks = self.maxticks http.get(self.url, / b, st -> self.on_body(b, st)) end self.ticks -= 1 if self.eStatticks <= 0 self.busel = 0 else self.eStatticks -= 1 end end def draw() var t, tcolor clear() # Powercounter if self.busel == 1 t = ["","","","","","","",""] t[0] = "1.8.0: " t[1] = str(self.eCI)+" kWh" if self.eCI1 != nil t[2] = " 1.8.1: " t[3] = str(self.eCI1)+" kWh" end if self.eCI2 != nil t[4] = " 1.8.2: " t[5] = str(self.eCI2)+" kWh" end t[6]=" 2.8.0: " t[7]=str(self.eCO)+" kWh" font("large") scroll_text([[t[0],0xAAAAAA],[t[1],0xFFFFFF],[t[2],0xAAAAAA],[t[3],0xFFFFFF],[t[4],0xAAAAAA],[t[5],0xFFFFFF],[t[6],0xAAAAAA],[t[7],0xFFFFFF]],0xFFFFFF,{"mode":"loop","gap":8,"repeat":10}) return end # WIFI-Info if self.busel == 2 t = ["","",""] if self.rssi != nil t[0] = str(self.rssi)+" dbm" end if self.ssid != nil t[1] = " SSID: " t[2] = self.ssid end font("large") scroll_text([["WIFI: ",0xAAAAAA],[t[0],0xFFFFFF],[t[1],0xAAAAAA],[t[2],0xFFFFFF]],0xFFFFFF,{"mode":"loop","gap":8,"repeat":10}) return end # Power if self.power == nil icon("40562", 0, 0) tcolor = 0xFF0000 t = "OFF" else t = str(self.power) if self.power > -10000 && self.power < 10000 t = t+"W" end if self.power == 0 icon("55398", 0, 0) tcolor = self.p0 elif self.power < 0 icon("52648", 0, 0) tcolor = self.pf else icon("52715", 0, 0) tcolor = self.pc end end var w = text_ink_width(t) text(9+((width()-9 - w) / 2), 6, t, tcolor) # Phases for x : 0 .. 2 if self.phases[x] != nil tcolor = self._color_from_value(self.phases[x]) line((11+(x*7)),7,(15+(x*7)),7, tcolor) end end # WIFI if self.wifiInd == true if self.rssi == nil || self.rssi < -79 # WLAN db pixel(0, 0, 0xFF0000) elif self.rssi < -69 pixel(0, 0, 0xFFFF00) end end end def on_button(btn) if btn == "select" self.ticks = 0 self.busel += 1 if self.busel > 2 self.busel = 0 end self.eStatticks = self.hc end end end return EcoTrackerMon()