Hi Andre –
Sure … It’s a total hack-job though. Here’s the process:
Copy the files from the ted5000 component into the custom_components folder – create a new one called “tedpro” or something like that.
Modify the init.py to the following:
"""The ted pro component."""
Modify the manifest.json to the following:
{
"domain": "tedpro",
"name": "The Energy Detective Pro",
"documentation": "https://www.home-assistant.io/integrations/ted5000",
"requirements": ["xmltodict==0.12.0"],
"codeowners": []
}
And then edit the sensor.py to the following:
"""Support gathering ted pro information."""
from datetime import timedelta
import logging
import requests
import voluptuous as vol
import xmltodict
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, POWER_WATT, VOLT, ELECTRICAL_VOLT_AMPERE, PERCENTAGE
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = "ted"
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=2)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_PORT, default=80): cv.port,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
}
)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Ted pro sensor."""
host = config.get(CONF_HOST)
port = config.get(CONF_PORT)
name = config.get(CONF_NAME)
url = f"http://{host}:{port}/api/SystemOverview.xml"
urlSpyder = f"http://{host}:{port}/api/SpyderData.xml"
gateway = TedProGateway(url, urlSpyder)
# Get MUT information to create the sensors.
gateway.update()
dev = []
for mtu in gateway.data:
dev.append(TedProSensor(gateway, name, mtu, POWER_WATT))
dev.append(TedProSensor(gateway, name, mtu, VOLT))
dev.append(TedProSensor(gateway, name, mtu, ELECTRICAL_VOLT_AMPERE))
dev.append(TedProSensor(gateway, name, mtu, PERCENTAGE))
# Individual sensors (derived)
dev.append(PowerSensor(gateway, "Power Grid", 0, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Solar", 1, POWER_WATT))
dev.append(PowerSensor(gateway, "Power ADU", 2, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Well Pump", 3, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Fridge", 4, POWER_WATT))
dev.append(PowerSensor(gateway, "Power UPS", 5, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Dishwasher", 6, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Washer", 7, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Microwave", 8, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Dryer", 9, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Outdoor", 10, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Car Charger", 11, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Sunroom Floor", 12, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Finished Basement", 13, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Unfinished Basement", 14, POWER_WATT))
dev.append(PowerSensor(gateway, "Power AC Air Handler", 15, POWER_WATT))
dev.append(PowerSensor(gateway, "Power Stove", 16, POWER_WATT))
add_entities(dev)
return True
class TedProSensor(Entity):
"""Implementation of a Ted Pro sensor."""
def __init__(self, gateway, name, mtu, unit):
"""Initialize the sensor."""
units = {POWER_WATT: "power", VOLT: "voltage", ELECTRICAL_VOLT_AMPERE: "kva", PERCENTAGE: "pf"}
self._gateway = gateway
self._name = "{} mtu{} {}".format(name, mtu, units[unit])
self._mtu = mtu
self._unit = unit
self.update()
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def unit_of_measurement(self):
"""Return the unit the value is expressed in."""
return self._unit
@property
def state(self):
"""Return the state of the resources."""
try:
return self._gateway.data[self._mtu][self._unit]
except KeyError:
pass
def update(self):
"""Get the latest data from REST API."""
self._gateway.update()
class PowerSensor(Entity):
"""Implementation of a Ted Pro sensor."""
def __init__(self, gateway, name, number, unit):
"""Initialize the sensor."""
units = {POWER_WATT: "power"}
self._gateway = gateway
self._name = name
self._number = number
self._unit = unit
self.update()
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def unit_of_measurement(self):
"""Return the unit the value is expressed in."""
return self._unit
@property
def state(self):
"""Return the state of the resources."""
try:
return self._gateway.power[self._number]
except KeyError:
pass
def update(self):
"""Get the latest data from REST API."""
self._gateway.update()
class TedProGateway:
"""The class for handling the data retrieval."""
def __init__(self, url, urlSpyder):
"""Initialize the data object."""
self.url = url
self.urlSpyder = urlSpyder
self.data = {}
self.power = {}
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Get the latest data from the TedPro XML API."""
try:
request = requests.get(self.url, timeout=10)
requestSpyder = requests.get(self.urlSpyder, timeout=10)
except requests.exceptions.RequestException as err:
_LOGGER.error("No connection to endpoint: %s", err)
else:
doc = xmltodict.parse(request.text)
docSpyder = xmltodict.parse(requestSpyder.text)
mtus = 3
"""int(doc["DialDataDetail"]["MTUVal"]["NumberMTU"])"""
for mtu in range(1, mtus + 1):
power = int(doc["DialDataDetail"]["MTUVal"]["MTU%d" % mtu]["Value"])
voltage = int(doc["DialDataDetail"]["MTUVal"]["MTU%d" % mtu]["Voltage"])
kva = int(doc["DialDataDetail"]["MTUVal"]["MTU%d" % mtu]["KVA"])
pf = int(doc["DialDataDetail"]["MTUVal"]["MTU%d" % mtu]["PF"])
self.data[mtu] = {POWER_WATT: power, VOLT: voltage / 10, ELECTRICAL_VOLT_AMPERE: kva, PERCENTAGE: pf / 10}
mtu1power = int(doc["DialDataDetail"]["MTUVal"]["MTU1"]["Value"])
mtu2power = int(doc["DialDataDetail"]["MTUVal"]["MTU2"]["Value"])
mtu3power = int(doc["DialDataDetail"]["MTUVal"]["MTU3"]["Value"])
gridpower = mtu1power-mtu3power
solarpower = -mtu2power
adupower = mtu3power
# Set up individual power sensors
self.power[0] = gridpower #grid minus ADU
self.power[1] = solarpower # Solar
self.power[2] = mtu3power # ADU
# Parse through Spyder data
spyder1 = docSpyder["SpyderData"]["Spyder"][0]
spyder2 = docSpyder["SpyderData"]["Spyder"][1]
self.power[3] = int(spyder1['Group'][0]['Now'])
self.power[4] = int(spyder1['Group'][1]['Now'])
self.power[5] = int(spyder1['Group'][2]['Now'])
self.power[6] = int(spyder1['Group'][3]['Now'])
self.power[7] = int(spyder1['Group'][4]['Now'])
self.power[8] = int(spyder1['Group'][5]['Now'])
self.power[9] = int(spyder1['Group'][6]['Now'])
self.power[10] = int(spyder1['Group'][7]['Now'])
self.power[11] = int(spyder2['Group'][0]['Now'])
self.power[12] = int(spyder2['Group'][1]['Now'])
self.power[13] = int(spyder2['Group'][2]['Now'])
self.power[14] = int(spyder2['Group'][3]['Now'])
self.power[15] = int(spyder2['Group'][4]['Now'])
self.power[16] = int(spyder2['Group'][5]['Now'])
You will need to modify the Spyder sensors in dev.append in the setup_platform method. Plus I’m sure that if you’re a Python programmer, you can probably figure out a much better way to do this.
I’m basically mapping a number in the self.power[] array to a sensor.
You’ll also need to change the # of mtu’s to match your setup. I have 3 mtu’s. I also do some fancy math with the raw power data from the mtu’s to make it make more sense with my particular setup. That’s happening in the self.power[0] … code.
To make this work, you will need to add:
- platform: tedpro
host: <ip address of your tedpro
to your configuration.yaml.
Again – this is a total hack-job. It’s not on Git, because I frankly don’t have the time to make this bullet proof and universal for everyone to use. Feel free to grab my mods though (for anyone wanting to do that).
Good luck!