@t006: sorry for not replying didn't read that last post, however I'm fullfilling two of your requests in this post

Offcourse you guys can request, I'll put it on my to-do list then!
As promised I would publish some information about the power buffers.
<b>Circle information request</b>
You can read some information about the plugwise device, some values are unknown. But, I already want to share this because it's needed for power buffer reading.
Let's analyze the information request:
- The first 4 bits represent the function code, which is in this case "0023"
- The next 16 bits represent the MAC address of the device, which is in this case "000D6F00002366BB"
- The last 4 bits represent the CRC16 checksum value, in this case "231B"
Let's analyze the information response:
Code: Select all
0024 000D6F00002366BB00003681 000457C8 01 8500000473000748B4253801F74D
Note: the spaces have been included for readability.
The first 4 characters represent the function code, in this case information response.
The next string is the mac address.
Now for the interesting part:
- 000457C8 represents the last logaddress value hexadecimal. This logaddress is used for power buffer information.
To get the logaddress in nice decimal format, do the following:
1) Convert the hexadecimal value to integer.
2) Substract 278528 from the outcome.
3) Divide that outcome by 32.
The result will be the latest log address of the power buffers.
My calculation looks like this:
Code: Select all
(self.hexToInt(data) - 278528) / 32
These logaddresses are also visible in the plugwise database.
- 01 represents the current relay state of the device (01=ON, 00=OFF)
The other values are yet unknown. Also because I wasn't interested in these values yet.
<b>Power buffer information</b>
The circle's hold an internal buffer of power usage. This way you can safely close the source software and read that information later on. I have succeeded in reading this without using the source.
Let's analyze the power buffer request:
Code: Select all
0048 000D6F0000236317 00045640 439B
- The first 4 bits represent the function code, which is in this case "0048"
- The next 16 bits represent the MAC address of the device, which is in this case "000D6F0000236317"
- The next 8 bits represent the log address of the power buffer you want to fetch, remember we read the latest buffer address with the information request? You can use this to determine the buffers you are missing in your program, for example if the latest log address is 160 and the last processed buffer in your program is 150 you are missing 10 buffers starting from 150 (so you would do a read request here for 151, 152 etc.)
The log address requires some ca****ation (again) In this case the log address is:
- 00045640 to decimal 284224
- 284224 - 278528
- 5696 / 32 = 178
So the log address is 178.
To calculate the hexadecimal for a log address one would just reverse the formula:
The log address is 178.
278528 + (32 * 178) = 284224
Converting this to hexadecimal is: 00045640
- The last 4 bits represent the CRC16 checksum value, in this case "439B"
Let's analyze the power buffer response:
Code: Select all
0049 000D6F0000236317 000036B1 0000ABAA 000036B2 0000AB72 000036B3 0000AB66 000036B4 0000ABAD 00045620 758F
This is a huge one [:)]
- The first 4 bits represent the function code, which is in this case "0049"
- The next 16 bits represent the MAC address of the device, which is in this case "000D6F0000236317"
- The next 8 bits represent the hour of the <i>first</i> buffer in abshour format (got this name from the access database

) more about this abshour format later.
- The next 8 bits represent the usage in pulses for the <i>first</i> hour.
- The next 8 bits represent the hour of the <i>second</i> buffer in abshour format (got this name from the access database

) more about this abshour format later.
- The next 8 bits represent the usage in pulses for the <i>second</i> hour.
- The next 8 bits represent the hour of the <i>third</i> buffer in abshour format (got this name from the access database

) more about this abshour format later.
- The next 8 bits represent the usage in pulses for the <i>third</i> hour.
- The next 8 bits represent the hour of the <i>fourth</i> buffer in abshour format (got this name from the access database

) more about this abshour format later.
- The next 8 bits represent the usage in pulses for the <i>fourth</i> hour.
- The next 8 bits represent logaddress of the buffer, this is the same log address as explained before.
- The last 4 bits represent the CRC16 checksum value, in this case "758F"
<i>The abshour format</i>
Let's pick the first buffer address as example: 000036B1
The decimal value of this abshour value is 14001
This value was a real brain cracker, after comparing the values I figured out the following.
For illustration let's convert the next abshour value (000036B2) to decimal: 14002
Aha! It increases by one all the time, so there must be a constant in these values. Then I substracted this value as hours from the current date (as it states abshour I was figuring it had something to do with hoours) this brought me to the following date:
1-6-2007
So if you add the number of hours to that date you'll get the datetime of that buffer.
Example in python:
Code: Select all
>>> import datetime
>>> timestart = datetime.datetime(2007, 6, 1, 2)
>>> dif = datetime.timedelta(hours=14001)
>>> datetime = timestart + dif
>>> datetime
datetime.datetime(2009, 1, 4, 11, 0)
So the date and time of this buffer request is:
4-1-2009 11:00
<i>The pulses</i>
I have explained these pulses before in a post. The pulses here are exactly the same pulses, however there is one difference.
The formula must be changed from:
1.0 * (((pow(value + offruis, 2.0) * gain_b) + ((value + offruis) * gain_a)) + offtot)
To:
3600 * (((pow(value + offruis, 2.0) * gain_b) + ((value + offruis) * gain_a)) + offtot)
Also you need to divide the pulses value by 3600.
This is needed because the pulses are now logged for an entire hour rather then a second.
I use a generic function now for the pulsecorrection:
Code: Select all
def PulseCorrection(self, pulses, id, timespan):
"""
Corrects plugwise pulses using calibration information from plug.
"""
device = Device.get(int(id))
value = pulses / timespan;
out = timespan * (((pow(value + device.extension.offruis, 2.0) *\
device.extension.gainb) + ((value + device.extension.offruis) * \
device.extension.gaina)) + device.extension.offtot)
return out
Phew.. this is gotten a really long post, I hope it's clear enough and that it's usefull for you. If you have any questions don't hesitate to ask.
--
Maarten Damen
www.maartendamen.com