Comments (23)
In which line exactly do you think the 1 is written?
data.writeUInt8(firstByte,1);
uses writeUInt8(value, offset)
, so it is writing the firstByte
in position 1 of [0,1,2] of the buffer data
However, I am not completely sure that I understood the sendADPU right. I think the length byte is generated here in connection.js:
https://github.com/andreek/node-eibd/blob/master/lib/connection.js#L179
Connection.prototype.sendRequest = function(input, callback) {
var self = this;
var data = new Array(input.length+2);
data[0] = (input.length>>8) &0xff;
data[1] = input.length & 0xff;
for(var i = 2; i < data.length; i++) {
data[i] = input[i-2];
}
var buf = tools.pack(data);
self.socket.write(buf, callback);
from node-eibd.
And by the way, it works perfectly with DPT9 messages.
from node-eibd.
Well, I think I found the issue. Take a look here: https://github.com/andreek/node-eibd/blob/master/lib/creator.js#L25
(...)
} else if(DPTType.indexOf('DPT1') === 0
|| DPTType.indexOf('DPT2') === 0
|| DPTType.indexOf('DPT3') === 0) {
//Small payload to or with action
data.writeUInt8(firstByte | payload.readUInt8(0) , 1);
} else {
...the DPTType.indexOf('DPT1') === 0
is true
even for DPT10 and DPT11 :)
We have the same problem here: https://github.com/andreek/node-eibd/blob/master/lib/encoder.js#L151
I can do a PR later, if you agree.
from node-eibd.
You're right, the String.indexOf()
is probably not the best way to distinguish between DPT1 and DPT10...
@andreek + @3sv : Is there a reason why you did not directly compare to the DPTType? Are there other things in the same string which need to be ignored? Was that to handle DPT subtypes (which are ignored techically? Like DPT1.001?)
from node-eibd.
@marcopiraccini I agree with you.
@snowdd1 I don't think there is a reason to not compare directly. But maybe we can get an answer from @3sv. I've overlooked this bug in PR.
from node-eibd.
Don't remember the reason to use the indexOf, but supporting the subtypes is probably the reason indeed. Some unit tests are using subtypes to test the support for that.
Seems like the unit test that is added when DPT-10 support was implemented is not testing that part of the code. It is executing .encodeDPT10 directly instead of the .encode with string to indicate the type.
5a7f4f4
The easiest fix is probably to include the "." in the indexOf part, indexOf("DPT1.") ? Maybe a good idea to also test this part from the unit test?
from node-eibd.
I see, the testing pattern breaks in line 85
5a7f4f4#diff-92cb61ffc51758a499f774504820ba8cR85
within the DPT9 tests.
You're thinking of something like (DPTType+".").indexOf('DPT1.')
to catch both DPT1 and DPT1.001 but not DPT10?
from node-eibd.
Fixed here: #22
I dont' have fixed the DPT9 test, since this call buffer = enc.encodeDPT9(20.2, 4);
has two params, but here: https://github.com/andreek/node-eibd/blob/master/lib/encoder.js#L160 the call is:
} else if(DPTType.indexOf('DPT9') === 0) {
return this.encodeDPT9(value);
}
...so the second parameter will not arrive to the encodeDPT9
call (it's a bug???)
from node-eibd.
We can add the exponent parameter to the encode function.
Encoder.prototype.encode = function(DPTType, value, exp) {
if(DPTType.indexOf('DPT1') === 0) {
return this.encodeDPT1(value);
}
.......
} else if(DPTType.indexOf('DPT9') === 0) {
return this.encodeDPT9(value, exp);
}
......
return undefined;
};
Or we force the use of encodeDPT9 to give the data with one parameter.
var value = "x^n"
encodeDPT9(value);
The encodeDPT9 would split this value on "^" to get the two params.
I can't say which solution I prefer at the moment. Your opinions? Other solutions?
from node-eibd.
Did I get it right, it is currently not auto-adjusting the exponent, but needs to be given one as a parameter? Which would mean it fails for values with mantissa over 2^11 (11 bits mantissa), which would mean values passed over 81,88 (81,88 * 100 / (1 << 2) = 81,88 * 25 = 2047 = 0b11111111111)?
If that is the case we should better work on a wrapper that determines the exponent fitting to the value ranges automatically.
I didn't notice any of this as my installation sends only room temperatures from node, which usually are in the range of exponent 2.
EDIT: Typo: not 1047 but 2047 is 0b11111111111
from node-eibd.
+1 for calculating the mantissa/exp automatically from the float. So we maintain the encodeDPT9(value);
but the encode implementation will convert the value
to mantissa/exp
from node-eibd.
This is what datatype specifications says on DPT9:
FloatValue = (0,01_M)_2^E
E = [0,15](4 bit)
M = [-2048,2047](integer 2-complements, 12 bit)
...so it's possible to write:
V = convertToFloat(M,E)
: (0,01_M)_2^E
[M,E] = convertFromFloat(V)
: This is trickier, but that should work (inspired by an answer on stackoverflow I cannot find anymore :)):
{
x = V /0.01
positive = true;
var exp
if (x<0) {
positive =false; x=-x;
};
while (x > 2) {
x/=2; exp++;
};
while (x < 1) {
x*=2; exp--;
}
var M = (V / 0.01 * 2^exp)
if (!positive) {
M = -M
}
return [M, exp]
}
from node-eibd.
Sorry didn't get it, what's b
in your (pseudo)code?
from node-eibd.
The base, now edited to "2"
from node-eibd.
(not sure it works, I'm trying to implement it right now :))
from node-eibd.
what about exp = max(log(value*100,2)-10, 0) ?
2 being the base.
the max avoiding negative exponents.
from node-eibd.
Ahh, and we need to round it down to the next integer.
And get rid of the sign before. So it is abs(value)!
from node-eibd.
so that would make it
exp = Math.max(Math.log(Math.abs(value)*100)/Math.log(2)-10,0)
The remainder of encodeDPT9 would stay as it is, as the matissa is already adapted to the base in
https://github.com/andreek/node-eibd/blob/master/lib/encoder.js#L54
So this could replace line 51.
EDIT: forgot the 10 digit shift.
from node-eibd.
Ok, much better :). Implementing it now.
from node-eibd.
Hi Marco,
I forgot the Math.floor() around it, to round it DOWN to the next integer value.
I guess you have noticed during testing, but I wanted to spare you the work to figure that out.
I am just working on a way to verify my formula, I'll give you an OK if it REALLY works.
Raoul
from node-eibd.
Too late, I've already implemented it :D (I'm travelling in train, so I have time :)).
See/try the updated PR.
I only had to change some of the DPT9 test asserted values, since these where correct only with exp=2 (which was the default).
from node-eibd.
So I've just encoded and decoded the following values. It shows very nicely the "half precision" of 3 and half decimals digit, so the forth significant digit should be in the ballpark of the original, fifth and following are just digital litter:
Encoding 1.234 results in decoded 1.23
Encoding 12.34 results in decoded 12.34
Encoding 123.4 results in decoded 123.36
Encoding 1234 results in decoded 1233.92
Encoding 12340 results in decoded 12339.2
Encoding 123400 results in decoded 123371.52
Encoding 1234000 results in decoded 18.82
Encoding 640000 results in decoded 639959.04
Encoding -1.234 results in decoded -1.23
Encoding -12.34 results in decoded -12.34
Encoding -123.4 results in decoded -123.36
Encoding -1234 results in decoded -1233.92
Encoding -12340 results in decoded -12339.2
Encoding -123400 results in decoded -123371.52
Encoding -640000 results in decoded -639959.04
And with 1,234,000 it shows an exponent overflow. So it would be probably a good idea to -at least- log a warning if exp>15, wouldn't it?
You can find my testing code here: https://gist.github.com/snowdd1/d41b7032c5f8aaaf3211#file-testingdpt9-js
from node-eibd.
(I moved the convert functions to tools.js
for a better testability, see ./test/tools.js
.
You can also run it (and and more tests) to verify the formula.
from node-eibd.
Related Issues (20)
- KNX "software" devices HOT 4
- Error when running example code HOT 10
- command line apps have no error handlers HOT 3
- groupsocketlisten with conn_sep branch of knxd HOT 3
- Documentation link dead HOT 2
- knx connection HOT 5
- DPT232 HOT 1
- Cannot connect HOT 3
- Missing DPT in telegram HOT 2
- When sending a read message, the response contains the wrong value HOT 2
- 16 bit group addresses HOT 4
- Mandatory closing of connection after sending APDU HOT 3
- groupread executable broken for non-socket reads HOT 5
- [Enhancement] Use a generic telegram decoder to be able to parse all telegrams HOT 2
- DPT14 for thermostat HOT 1
- npm install eibd could't set HOT 2
- /usr/bin/env: βnode\rβ: No such file or directory HOT 1
- Buffer Constructor is deprecated in Node.js 10
- trouble getting groupread response HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from node-eibd.