/*
* GivEnergy Connect
*
* Copyright 2023 Ben Deitch
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
*/
/* ChangeLog:
* 03/06/2023 - v0.1 - Initial implementation
*/
definition(
name: "GivEnergy Connect",
namespace: "xap",
author: "Ben Deitch",
description: "Integrates GivEnergy Battery System into Hubitat via local GivTCP service.",
category: "My Apps",
iconUrl: "", iconX2Url: "", iconX3Url: ""
)
preferences {
section("
GivTCP
") {
input name: "serviceAddress", type: "string", required: true, title: "GivTCP Service IP Address"
input name: "servicePort", type: "number", required: true, title: "GivTCP Service Port"
input name: "pollingInterval", type: "number", required: true, range: "1..59", title: "Polling Interval (seconds)"
}
section("Other Settings
") {
input name: "debugLogging", type: "bool", title: "Enable/disable debug logging", defaultValue: false, required: false
}
}
def log(message) {
if (debugLogging) {
log.debug message
}
}
def installed() {
initialize()
}
def uninstalled() {
removeChildren()
}
def updated() {
initialize()
}
def initialize() {
unschedule()
createChildren()
scheduleQuery()
}
def getChildDniRoot() {
"givenergy-connect"
}
def getBatteryDni() {
childDniRoot + "-batt"
}
def getBattery() {
getChildDevice batteryDni
}
def getGridDni() {
childDniRoot + "-grid"
}
def getGrid() {
getChildDevice gridDni
}
def getLoadDni() {
childDniRoot + "-load"
}
def getLoad() {
getChildDevice loadDni
}
def getPvDni() {
childDniRoot + "-pv"
}
def getPv() {
getChildDevice pvDni
}
def createChildren() {
if (!battery) {
log "Create Battery Device"
addChildDevice "xap", "Battery Power Meter Child Device", batteryDni, [name: 'GivEnergy Battery']
}
if (!grid) {
log "Create Grid Device"
addChildDevice "xap", "Power Meter Child Device", gridDni, [name: 'GivEnergy Grid Power']
}
if (!load) {
log "Create Load Device"
addChildDevice "xap", "Power Meter Child Device", loadDni, [name: 'GivEnergy Load Power']
}
if (!pv) {
log "Create PV Device"
addChildDevice "xap", "Power Meter Child Device", pvDni, [name: 'GivEnergy PV Power']
}
}
def removeChildren() {
childDevices.each {deleteChildDevice(it.deviceNetworkId)}
}
def scheduleQuery() {
log.info "Scheduling refresh every ${pollingInterval} seconds"
schedule("0/${pollingInterval} * * * * ? *", queryStats)
}
def refresh() {
queryStats()
}
def queryStats() {
log "Query for battery data"
asynchttpGet "handleStatsResponse", [uri: "http://${serviceAddress}:${servicePort}/runAll"]
}
def handleStatsResponse(response, data) {
def json = getResponseJson(response)
log json
def power = json?.Power?.Power
if (power) {
battery.sendEvent (name: "power", value: power.Invertor_Power, unit: "watts")
battery.sendEvent (name: "battery", value: power.SOC)
grid.sendEvent (name: "power", value: power.Grid_Power, unit: "watts")
load.sendEvent (name: "power", value: power.Load_Power, unit: "watts")
pv.sendEvent (name: "power", value: power.PV_Power, unit: "watts")
}
}
private getResponseJson(response) {
if (response.status == 200) {
def json = response.json
if (json) {
json
} else {
log.warn "Received response that didn't contain any JSON"
}
} else {
log.warn "Received error response [${response.status}] : ${response.errorMessage}"
}
}