Accessing XTdb data

James Sentman james at sentman.com
Sat Jul 22 12:47:13 EDT 2017


Absolutely you can do this :) And if you are running a relatively recent version of XTension you don’t even need to ask XTdb for it. If your XTension version has the advanced tab of the Edit Unit dialog then you have access to the last few values directly from XTension. In the advanced tab of the unit dialog for the unit you want to access have a look at that advanced tab and find the “Average the last [] values” entry. You do not have to turn this on in order for it to be saving the last few values. The default is the last 5 values and you should see them in the text field there separated by commas. 

you can get those out with the xtPreviousValues property of the xUnit class. that will return a standard list of the values. They are in reverse order though so the oldest one will be item 1.

set myListOfValues to xtPreviousValues of xUnit “name of your power unit”
set theFifthValue to item 1 of myListOfValues — again, is backwards, I should probably reverse that in a future version.

and now you have the value from 5 updates ago. I think I understand that is what you want to do?

Now you want to get that data via the JSON server, this is also possible pretty simply! Any HTTP request from the JSON server that isn’t directly linked to a hard coded action like on or off or set value will be passed to the on JSONRequest handler of the unit. So you need a JSON server interface running if you don’t already have one, and a tag configured on it that you can enter into the web request. Then you need to create a new unit on that JSON interface which will serve as the receiver for these requests. Assign the new unit to the interface and give it a simple address something like “OLDVALUE” You will use this address as part of the path to talk to the unit from your JSON device.
 
The unit name isn’t important, call is something like “JSON History Handler” but you will need this name in the script, you cannot use thisUnit due to a bug I just found in some of the verbs necessary, the thisUnit is going to get lost and we will need to reset it in the script before we can send the reply to the request.

in the ON script of that OLDVALUE unit assigned to the JSON server create a handler something like this:

on JSONRequest(formData, JSONData)
	
	set WorkingUnit to unit of formData
	write log "request for historical data from unit: " & WorkingUnit
	
	set myData to xtPreviousValues of xUnit WorkingUnit
	set myValue to item 1 of myData
	
	-- NOTE the call to get the xtPreviousValues causes the (thisUnit) reference to get 
	-- reset to that unit and it does not revert back to this JSON unit. We must do the same thing
	-- calling to this unit to get thisUnit set back to the correct value or the send reply verb 
	-- will not work. This next line has no function in the script logically, it just uses the same bug
	-- to reset the thisUnit reference to this unit so we can send the reply below.
	set myData to xtPreviousValues of xUnit “JSON History Handler"
	
	send reply (myValue as text) return code 200
	
end JSONRequest


While this technically works with safari as well for testing I would use CURL from the command line as safari and it’s autocomplete just makes it hard to enter such things and it’s caching means it won’t update if it thinks the value hasn’t changed and such. so use curl from the command line do something like:


curl “http://ip.of.your.xtension:port of JSON server/[THE TAG]/OLDVALUE?unit=the%20name%20of%20the%20unit”

and you should receive back the 5th value of the unit.

the path has 2 parts THE TAG which is the tag you created for this in the setup of the JSON server, and the address of the unit assigned to the JSON interface who’s on script we want to talk to. Then we add a query string for unit=the name of the unit. But you have to manually escape any spaces in it by changing them to %20 if you’re doing it from curl. (and the entire link must be in quotes like in my example or the ? will blow up the shell)

Any form variables that you pass either as GET or POST variables will be inside the “formData” record that is passed to the JSONRequest. If you’d rather POST a json object then any values you include in that will be in the JSONData record passed to the script, the access will be exactly the same just say set myUnitName to unit of JSONData. Or if not “unit” then whatever name you give it in the form or the JSON.

That just returns the value, if you need the value to be in a JSON object that you can access from whatever you’ll need to manually construct that in the script and return it as a string, but that should be simple enough, also change the default mime type to tell the receiver that it’s a proper JSON reply. Something like this:

send reply “{\“value\”:” & (myValue as text) & “}” content type “application/json” return code 200

applescript makes you escape extra quotes like that what you’re really sending back then would be a simple JSON object with just one value in it named “value” it would look like:

{“value”:2453.0}

more info on the JSON server and what you can do with the JSONRequest handler is at:

http://machomeautomation.com/doku.php/supported_hardware/json

It should be completely possible to write an entire JSON RPC server in the ON script of the receiver unit to get or set any unit values in the entire database ;) I am going to write an example of that eventually, but this is pretty similar.

If you only ever need to get the data from the one unit you don’t even really have to mess with getting form data and the rest of it, just hard code the unit name you’re getting the 5th value from and don’t worry about passing it a form variable with the unit name in it at all. but I wanted to show that so you could all see what you might be able to do with that.

> On Jul 22, 2017, at 5:09 AM, ard jonker <ard.jonker at xs4all.nl> wrote:
> 
> (looks like this message didn't reach the list, sorry if it does twice).
> 
> Hi James,
> 
> On 8 Feb 2015, at 15:16, James Sentman <james at sentman.com <mailto:james at sentman.com>> wrote:
>> But what exactly are you going to do with it? Just better graphing? I know that everyone wants to graph for longer periods of time and do other sorts of things. XTdb needs some love and some new features, excite me about new things I could do with it so I spend some time working on it ;)
> 
> Coming back to this old thread, I am trying to retrieve the fifth but most recent entry in the xtdb database. My power meter is pushing out a few measurements in under a minute and if I hook up the electric car, it takes a minute or so to settle. If within one minute the power draw increases more than 2.2 kW, I know the car is connected.
> 
> So is there a simple query that retrieves (via a json interface??) the fifth but last entry from xtdb for a certain unit?
> 
> Cheers,
> ard
> 

Thanks,
 James


James Sentman                       http://www.PlanetaryGear.org		http://MacHomeAutomation.com




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.machomeautomation.com/pipermail/xtensionlist/attachments/20170722/7b9dc91b/attachment.html>


More information about the XTensionList mailing list