I’ve tried a thousand things, but can’t seem to turn “[3277.96X]” into “3277” - Anyone got a clue? Could this be achieved with a rule maybe?
Something like this maybe:
$[?(@.cid == PWER)].data[0].*[0]
Here’s a rule version of it for testing various combinations:
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
rule "JSON Test"
when
Time cron "0/10 * * * * ?"
then
var String json = '[{"cid":"PWER","data":[{"1444632753000":1642.085}],"sid":"555610","units":"kWm","age":34}]'
var String type = transform("JSONPATH", "$[?(@.cid == PWER)].data[0].*[0]", json)
logInfo("json", type)
end
It doesn’t eliminate the decimal point, but the output is like:
19:33:40.004 DEBUG o.o.m.r.i.e.ExecuteRuleJob[:53]- Executing scheduled rule 'JSON Test'
19:33:40.011 INFO org.openhab.model.script.json[:53]- 1642.085
The JSONPath Doc is here if you want to do something more complex:
Hi,
Any progress on this matter?
I’m also very interested to do so, but I use the other web which is
https://engage.efergy.com/
I do not konw how to get this specific numbers… could you help me to understand where to gather this info.
I only have my specific token code, but nothing else.
Thanks in advance, would be a nice Binding as item efergy engage hub is used for a lot of houseowners.
Regards,
Marc.
HUGE SUCCESS!
Thanks @guessed - your code did it… My http-binding now looks like:
<[http://www.energyhive.com/mobile_proxy/getCurrentValuesSummary?token=XXXX:60000:JSONPATH($[?(@.cid == PWER)].data[0].*[0])]
And it is logging -
2015-11-03 05:34:39 - Energy_Instant_House state updated to 1522.485
I haven’t used it yet, but at least it’s a number, so hopefully it will work out when I get some time… @mgalimany You should be able to use energyhive instead, they are the ones providing services for efergy. If I remember correctly the username/password from efergy works straight away on eneryghive - I think you can login and request an API token there. Replace XXXX above and you should be good to go!
Great! Glad to hear you got it tuned up.
Hello Marc, I also use Efergy, were you able to get this to work?
For anyone struggling to get this working in openHAB 2 since the JSONPATH behaviour has changed, the JS transform still works if you define the item like
Number Energy_Instant_House “Current energy use [%d W]” (Power) { http="<[http://www.energyhive.com/mobile_proxy/getCurrentValuesSummary?token=XXXX:60000:JS(efergy.js)]"}
and stick this in /etc/openhab2/transform/efergy.js
JSON.parse(input)[0].data[0][Object.keys(JSON.parse(input)[0].data[0])[0]];
Thanks so much for this post guys.
I have a question though. I get this JSON string as a reply
[{"cid":"PWER","data":[{"1536592326000":331}],"sid":"xxx","units":"kWm","age":2},{"cid":"PWER","data":[{"1536592322000":20}],"sid":"yyy","units":"kWm","age":6}]
as I have more than one sensors in my household. How can I extract the info based on the SID ?
Regards
Hi, I too have efergy (energyhive) power monitor with 2 x Data Points (one for 3-Phase consumption and one for Controlled (off peak) load). The following is what I get back from the efergy API reply:
[{“cid”:“PWER”,“data”:[{“1595114390000”:3734}],“sid”:“816022”,“units”:“W”,“age”:5},{“cid”:“PWER”,“data”:[{“1595114376000”:0}],“sid”:“816590”,“units”:“W”,“age”:19}]
Any suggestions on how to extract the following values from the string (eg)?:
3Phase = 3734
OffPeak = 0
Thanks
Nathan
So this works. It should also work regardless of how many Efergy / Energyhive monitors you have (I have two). If you have one remove the second VAL and postUpdate lines. If you have more than two then add additional ones and increment the $.[n] value (starting at 0).
Items:
Number myHousePower "Power [%.0f W]" <energy>
Number myOffPeakPower "Power [%.0f W]" <energy>
Rules:
rule "House Power Consumption"
when
Time cron "0 0/1 * 1/1 * ? *" // Run every Minute
then
var String tempJson = sendHttpGetRequest("http://www.energyhive.com/mobile_proxy/getCurrentValuesSummary?token=xxxxxx")
val tempMainPower = transform("JSONPATH", "$.[0].data[0].*", tempJson) // This will pull the 1st Data Point
val tempOffPeak = transform("JSONPATH", "$.[1].data[0].*", tempJson) // This will pull the 2nd Data Point if you have a 2nd monitor
myHousePower.postUpdate(tempMainPower)
myOffPeakPower.postUpdate(tempOffPeak)
end
It all updates values in the UI, and I can send alerts etc if myHousePower.state < 100 etc
Edit - Updated the code above with the comments below
postUpdate() can be funny about the type of object passed for the new state.
Passing a string usually overcomes snags, but the best way from a Number -
myOffPeakPower.postUpdate(tempOffPeak.toString)
Thanks - this removed the warning and did not seem to break anything I’ve updated my post above.
I was puzzling over why postUpdate(Number) seemed not to work, sure it usually does …
Thinking further on this … your variable won’t be a Number type at all.
Declaring types in rules is not strictly enforced. transform()
of any kind always returns a string. (If you wanted it as number you would have to parse it.)
So you can just pass to postUpdate() as it is.
myOffPeakPower.postUpdate(tempOffPeak)
and the openHAB framework will parse the given string to something suitable.
unrelated - i would add a timeout to your sendHttpGetRequest()
call, and perform a test for null
results in case of failure of the HTTP fetch for whatever reason.
Thanks - Tested with the following changes and they work so I updated the code in my post above:
- Removed “Number” declarations for tempMainPower / tempOffPeak
- Removed “.toString” from the postUpdates
I’ve not yet looked at adding a specific HTTP timeout as I thought there was a Global Default of 5000ms anyway??? I “think” I’ll be fine on a failure to get a null result but I’d have to test to be sure.
So long as you are aware, people often overlook.
Well, the rule will throw an error trying to process tempJson
as null input to the transform.
By testing if it is null first, you can avoid that and exit gracefully.
You might choose instead to update your Items to UNDEF to indicate unknown, depends what you want.
Thanks for all your help. I’ll drop my Internet Connection to test and report back (but I’ll need to find a time to do this when everyone is out).
So here is the latest with the addition of some error checking for both:
- No Result / timeout of the http request (null)
- Errors in the JSON result (such as Bad Token, or if the Web Site is up but the power monitors in the house are off line)
Rules
rule "House Power Consumption"
when
Time cron "0 0/1 * 1/1 * ? *" // Run every Minute
then
var String tempJson = sendHttpGetRequest("http://www.energyhive.com/mobile_proxy/getCurrentValuesSummary?token=b4sPDuDMwZinXhI_7GoHKAwcaeL2dSBq")
if ( tempJson === null || tempJson.contains ("error") ) { // Check to see if there is a response (and if it contains an error)
logInfo("HousePower", "Unable to Update Energy Use: Reponse from EnergyHive / Efergy - {}", tempJson)
myHousePower.postUpdate(UNDEF)
myOffPeakPower.postUpdate(UNDEF)
}
else {
val tempMainPower = transform("JSONPATH", "$.[0].data[0].*", tempJson) // This will pull the 1st Data Point
val tempOffPeak = transform("JSONPATH", "$.[1].data[0].*", tempJson) // This will pull the 2nd Data Point if you have a 2nd monitor
myHousePower.postUpdate(tempMainPower)
myOffPeakPower.postUpdate(tempOffPeak)
}
end
After few years of just reading my power instant values from the Efergy system with Energyhive account (thanks to this community page!), I decided to go a bit deeper in my energy consumption overview.
Unfortunately, doing calculations from instant values inside Openhab, using daily rules, is not working as well as desired, so the simple way is to get the desired values directly from the Energyhive API (which I could not find before).
Here I found interesting info for the API, to get the desired values: http://napi.hbcontent.com/document/index.php
Here some examples that allow me to simply read monthly energy consumption and monthly cost.
Items
String EnergyMonthHouse "Energia mese Casa [%s kWh]" <myicon> (G_EnergyM) { http="<[http://www.energyhive.com/mobile_proxy/getEnergy?token=XXXXXXXXXXX&period=month&offset=-60:60000:JSONPATH($.sum)]"}
String EnergyCostMonthHouse "Costo Energia mese Casa [%s EUR]" <myicon> (G_EnergyEUR) { http="<[http://www.energyhive.com/mobile_proxy/getCost?token=XXXXXXXXXXX&period=month&offset=-60:60000:JSONPATH($.sum)]"}
The period can be simply changed by using “day”, “week”, “year” instead of “month”.
Change the “getEnergy” or “getCost” with what you like in the API linked page to get different “channels”.
Obviously use your personal token instead of “XXXXX”.
I am not using transformation files or rules on these items, but see for yourself if you need them.
I hope it works for you too!
I am finally migrating my Efergy / Energyhive system to OH3.2.0 (manual installation of Build #2546).
Here my setup in short (not shown here: my second Efergy account and period channels “day” and “week”; offset is related to my timezone).
I am using a “hybrid” approach: Things in UI and Items in config file.
Things (HTTP Binding):
UID: http:url:HTTP_ENERGIA
label: HTTP Energia
thingTypeUID: http:url
configuration:
authMode: BASIC
ignoreSSLErrors: false
baseURL: http://www.energyhive.com/mobile_proxy
delay: 0
stateMethod: GET
refresh: 10
commandMethod: GET
contentType: text/plain
timeout: 60000
bufferSize: 2048
location: Home
channels:
- id: PowerHouse
channelTypeUID: http:string
label: Potenza assorbita Casa
description: null
configuration:
mode: READONLY
unit: W
stateExtension: /getCurrentValuesSummary?token=XXXXXXXXXXXXXXXXXXX
stateTransformation: JS:efergy.js
- id: EnergyMonthHouse
channelTypeUID: http:string
label: Energia mese Casa
description: null
configuration:
mode: READONLY
stateExtension: /getEnergy?token=XXXXXXXXXXXXXXXXXXX&period=month&offset=-60
stateTransformation: JSONPATH:$.sum
- id: EnergyCostMonthHouse
channelTypeUID: http:string
label: Costo Energia mese Casa
description: null
configuration:
mode: READONLY
unit: kWh
stateExtension: /getCost?token=XXXXXXXXXXXXXXXXXXX&period=month&offset=-60
stateTransformation: JSONPATH:$.sum
In the file efergy.js in “transform” folder:
JSON.parse(input)[0].data[0][Object.keys(JSON.parse(input)[0].data[0])[0]];
In Items file:
Number PowerHouse "Potenza assorbita Casa [%d W]" <energy> (G_Power, G_House) ["Point_Measurement","Property_Power"] {channel="http:url:HTTP_ENERGIA:PowerHouse"}
Number EnergyMonthHouse "Energia mese Casa [%.1f kWh]" <qualityofservice> (G_Power, G_House) ["Point_Measurement","Property_Power"] {channel="http:url:HTTP_ENERGIA:EnergyMonthHouse"}
Number EnergyCostMonthHouse "Costo Energia mese Casa [%.2f €]" <price> (G_Power,G_House) ["Point_Measurement","Property_Power"] {channel="http:url:HTTP_ENERGIA:EnergyCostMonthHouse"}
Works fine
Just to update that today I abandoned the Efergy/EnergyHive power metering system due to huge lack of reliability since several months.
Too many times the readings fail by huge amounts and/or freeze even in the Efergy and EnergyHive apps .
EnergyHive assistance do what they can, due they admit they stopped supporting this system.
I switched to Shelly, using ShellyEM for the mains of my apartment and Shelly1PM for the garage.
I then have several Shelly2.5s and ShellyPlugs for sub-loads.
These are currently good solutions, although the Shelly app still has few bugs there is great and easy integration with Openhab (3.4.2).
Take your considerations.