Plugin - CurrentCost EnvyR (via Xively)

Python and python framework
Post Reply
User avatar
ycahome
Posts: 70
Joined: Sunday 12 February 2017 11:55
Target OS: Linux
Domoticz version: beta
Contact:

Plugin - CurrentCost EnvyR (via Xively)

Post by ycahome » Friday 24 February 2017 21:48

If you have the Current Cost EnvyR Power monitor

Image

connected with Netsmart Bridge

Image

to http://my.currentcost.com/?

you are in the right place.

Am building one plugin for us who have this device and don't want to return back to serial connection.

Let me know if anyone is available to test this plugin with me.

I will post here soon the first version of the plugin.

Any help will be appreciated...

Update:
Here is the code Version 1.0.2

Code: Select all


"""
CurrentCost EnvyR via Xively Plugin

Author: Ycahome, 2017

Version:    1.0.1: Initial Version
            1.0.2: Improvements:Timeout Added on Url Request
"""
"""


<plugin key="CCxiveReader" name="Current Cost EnvyR (via Xively)" author="ycahome" version="1.0.2" wikilink="" externallink="https://www.domoticz.com/forum/">
    <params>
        <param field="Mode1" label="XivelyApiKey" width="200px" required="true" default="Type your Xively Key Here"/>
        <param field="Mode2" label="XivelyFeed" width="200px" required="true" default="10001"/>
        <param field="Mode3" label="Update every x seconds" width="200px" required="true" default="300"/>
        <param field="Mode4" label="Debug" width="75px">
            <options>
                <option label="True" value="Debug"/>
                <option label="False" value="Normal"  default="False" />
            </options>
        </param>
    </params>
</plugin>
"""




import Domoticz
import json
import urllib.request
import urllib.error


from math import radians, cos, sin, asin, sqrt
from datetime import datetime, timedelta





class BasePlugin:

    def __init__(self):
        self.debug = False
        self.error = False
        self.nextpoll = datetime.now()
        self.pollinterval = 60  #Time in seconds between two polls
        return

    def onStart(self):
        Domoticz.Debug("onStart called")
        if Parameters["Mode6"] == 'Debug':
            self.debug = True
            Domoticz.Debugging(1)
            DumpConfigToLog()
        else:
            Domoticz.Debugging(0)

        # create the mandatory child device if it does not yet exist
        if 1 not in Devices:
    	    # Add Power and temperature device(s)
            Domoticz.Device(Name="Power", Unit=1, TypeName="kWh").Create()
            Domoticz.Device(Name="Temp", Unit=2, TypeName="Temperature").Create()
            Domoticz.Log("Devices created.")


    def onStop(self):
        Domoticz.Debug("onStop called")
        Domoticz.Debugging(0)


    def onCommand(self, Unit, Command, Level, Hue):
        Domoticz.Debug(
            "onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level))

    def onHeartbeat(self):
        now = datetime.now()
        if now >= self.nextpoll:
          self.nextpoll = now + timedelta(seconds=self.pollinterval)
          try:
             # poll Xively URL
             XivelyDataVar = getXivelyDataJSON(parseIntValue(Parameters["Mode2"]),"1",Parameters["Mode1"])
          except:
            Domoticz.Error("getXivelyDataJSON -Mode1-Feed -Error")
          else:
            Domoticz.Log("CurrentCost Power Consumprion (via Xively):"+XivelyDataVar["current_value"])

            CalcEnergyVar = CalculateEnergy(XivelyDataVar["current_value"],parseIntValue(Parameters["Mode3"]))

            if Parameters["Mode4"] == "Debug":
                 Domoticz.Log("Power spend on this period (CalcEnergyVar):"+str(CalcEnergyVar))

            ValueFromDevice = Devices[1].sValue
            ValueFromDevice = ValueFromDevice.split(';',2)
            if Parameters["Mode4"] == "Debug":
                Domoticz.Log("Value from Device: " + str(ValueFromDevice[1]))

            usedEnergy = ValueFromDevice[1]
            valueToUpdate = XivelyDataVar["current_value"]+";" +str(float(usedEnergy)+float(CalcEnergyVar))
            if Parameters["Mode4"] == "Debug":
                Domoticz.Log("Value to save to Device: " + valueToUpdate)

            UpdateDevice(1,0,valueToUpdate)
            #UpdateDevice(1,int(XivelyDataVar["current_value"]),str(usedEnergy+CalcEnergyVar))
            #UpdateDevice(1,int(XivelyDataVar["current_value"]),str(float(Devices[1].sValue) + CalcEnergyVar))
            #UpdateDevice(1,0,"0")

            try:
              # poll Xively URL
              XivelyDataVar = getXivelyDataJSON(parseIntValue(Parameters["Mode2"]),"0",Parameters["Mode1"])
            except:
              Domoticz.Error("getXivelyDataJSON -Mode2-Feed Error")
            else:
              Domoticz.Log("CurrentCost Temperature (via Xively):"+XivelyDataVar["current_value"])
              UpdateDevice(2,0,XivelyDataVar["current_value"])



global _plugin
_plugin = BasePlugin()

def onStart():
    global _plugin
    _plugin.onStart()

def onStop():
    global _plugin
    _plugin.onStop()

def onCommand(Unit, Command, Level, Hue):
    global _plugin
    _plugin.onCommand(Unit, Command, Level, Hue)

def onHeartbeat():
    global _plugin
    _plugin.onHeartbeat()

#############################################################################
#                   Device specific functions                     #
#############################################################################


# Generic helper functions


def DumpConfigToLog():
    for x in Parameters:
      if Parameters[x] != "":
          Domoticz.Debug( "'" + x + "':'" + str(Parameters[x]) + "'")
    Domoticz.Debug("Device count: " + str(len(Devices)))
    for x in Devices:
      Domoticz.Debug("Device:           " + str(x) + " - " + str(Devices[x]))
      Domoticz.Debug("Device ID:       '" + str(Devices[x].ID) + "'")
      Domoticz.Debug("Device Name:     '" + Devices[x].Name + "'")
      Domoticz.Debug("Device nValue:    " + str(Devices[x].nValue))
      Domoticz.Debug("Device sValue:   '" + Devices[x].sValue + "'")
      Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
    return

#
# Update Device
#

def UpdateDevice(Unit, nValue, sValue):

  # Make sure that the Domoticz device still exists before updating it.
  # It can be deleted or never created!
  if (Unit in Devices):

     Devices[Unit].Update(nValue, str(sValue))
     if Parameters["Mode4"] == "Debug":
        Domoticz.Debug("Update " + str(nValue) + ":'" + str(sValue) + "' (" + Devices[Unit].Name + ")")

#
# Get the Power Consumption information from http://api.xively.com
#

def getXivelyDataJSON(feed,datastream,key):

    url = 'http://api.xively.com/v2/feeds/'+str(feed)+'/datastreams/'+str(datastream)+'.json'

    if Parameters["Mode4"] == "Debug":
       Domoticz.Log('Retrieve CC data from ' + url)

    XiveHeader = {}
    XiveHeader["X-PachubeApiKey"] = key

    if Parameters["Mode4"] == "Debug":
       Domoticz.Log("X-PachubeApiKey:"+ XiveHeader["X-PachubeApiKey"])

    try:
        XiveReq = urllib.request.Request(url, headers=XiveHeader, method='GET')
    except urllib.error.HTTPError as err1:
        Domoticz.Error("HTTP Request error: " + str(err1) + " URL: " + url)
        return
    else:
        if Parameters["Mode4"] == "Debug":
            Domoticz.Log("URL Request Created")

        try:
            XMLresponse = urllib.request.urlopen(XiveReq, data=None, timeout = 30)
        except urllib.error.HTTPError as err2:
            Domoticz.Error("HTTP Request error: " + str(err2) + " URL: " + url)
            return
        else:

            if Parameters["Mode4"] == "Debug":
                Domoticz.Log("URLopen Completed")

            xml = XMLresponse.read()
            if Parameters["Mode4"] == "Debug":
                Domoticz.Log("XML:" + str(xml))
                Domoticz.Log("URL Response Read Completed")

            try:
                xml = xml.decode("utf-8")
            except urllib.error.HTTPError as err3:
                Domoticz.Error("HTTP Request error: " + str(err3) + " URL: " + url)
                return
            else:

                if Parameters["Mode4"] == "Debug":
                   Domoticz.Log("JSON Data:"+xml)

                #with xml as data_file:
                data = json.loads(xml)

                if Parameters["Mode4"] == "Debug":
                   Domoticz.Log("Data Loaded")

                return data


#
# Get the Power Consumption information from http://api.xively.com
#

def getXivelyDataJSON2(feed,datastream,key):

    url = 'http://api.xively.com/v2/feeds/'+str(feed)+'/datastreams/'+str(datastream)+'.json'

    try:

        if Parameters["Mode4"] == "Debug":
            Domoticz.Log('Retrieve CC data from ' + url)

        XiveReq = urllib2.request(url)

        if Parameters["Mode4"] == "Debug":
            Domoticz.Log("URL Request Created")

        XiveReq.add_header('X-PachubeApiKey', key)
        if Parameters["Mode4"] == "Debug":
            Domoticz.Log("X-PachubeApiKey:"+ XiveHeader["X-PachubeApiKey"])

        XMLresponse = urllib2.urlopen(XiveReq)

        if Parameters["Mode4"] == "Debug":
            Domoticz.Log("URLopen Completed")

        xml = XMLresponse.read()
        if Parameters["Mode4"] == "Debug":
            Domoticz.Log("URL Response Read Completed")
        xml = xml.decode("utf-8")

    except urllib2.error.HTTPError as e:
        Domoticz.Error("HTTP error: " + str(e) + " URL: " + url)
        return

    if Parameters["Mode4"] == "Debug":
        Domoticz.Log("JSON Data:"+xml)

    #with xml as data_file:
    data = json.loads(xml)
    if Parameters["Mode4"] == "Debug":
        Domoticz.Log("Data Loaded")

    return data






#
# Parse an int and return None if no int is given
#

def parseIntValue(s):

        try:
            return int(s)
        except:
            return None

#
# Parse a float and return None if no float is given
#

def parseFloatValue(s):

        try:
            return float(s)
        except:
            return None

#
# Calculate Energy
#

def CalculateEnergy(WattValue,Powerinterval):

    WattValueKW = int(WattValue)/1000
    if Parameters["Mode4"] == "Debug":
        Domoticz.Debug("WattValueKW: " + str(WattValueKW))

    Powerinterval = Powerinterval / 3600
    if Parameters["Mode4"] == "Debug":
        Domoticz.Debug("Power Interval: " + str(Powerinterval))

    usedEnergy = Powerinterval * float(WattValue)
    if Parameters["Mode4"] == "Debug":
        Domoticz.Debug("Used Energy (for this period): " + str(usedEnergy))

    return usedEnergy





Installation instructions:
- Create Plugin Folder "CCxiveReader" under "domoticz/plugin" folder
- Save this script as "plugin.py" on "CCxiveReader" folder
- Restart domoticz service.
- Add a new entry of this Hardware on your domoticz installation (Setup/Hardware/select and add "Current Cost EnvyR (via Xively)")

What am going to see?:
Plugin will auto-add
- one Power Meter on your "Utility" Section named "<Your Hardware Name>- Power".
- one Temperature Meter on your "Temperature" Section named "<Your Hardware Name>- Temp".

PS: I would like to thank ffes for inspiration and some snipets.....
http://www.domoticz.com/forum/viewtopic ... 65&t=16006
Last edited by ycahome on Monday 04 September 2017 10:32, edited 5 times in total.

User avatar
ycahome
Posts: 70
Joined: Sunday 12 February 2017 11:55
Target OS: Linux
Domoticz version: beta
Contact:

Re: Plugin - CurrentCost EnvyR (via Xively)

Post by ycahome » Saturday 25 February 2017 12:09

Am not 100% sure about Power calculations, so, any help will be appreciated....

User avatar
ycahome
Posts: 70
Joined: Sunday 12 February 2017 11:55
Target OS: Linux
Domoticz version: beta
Contact:

Re: Plugin - CurrentCost EnvyR (via Xively)

Post by ycahome » Monday 04 September 2017 10:33

#1st post updated with Version 1.0.2.

Enjoy

Post Reply

Who is online

Users browsing this forum: mozo78 and 2 guests