データソースからノードred modbusノードを介してデータを読み取りたい。範囲は-20000〜20000ですが、ノードは負の数を処理できないため、それらを2進数(DWORD)に変換し、下位ワードと上位ワードに分割して、これらのワードを整数に戻す必要がありました。
var low
function dec2bin(dec){
return (dec >>> 0).toString(2);
}
var a = msg.payload
if (a >= 0){
a = dec2bin(a);
a = parseInt(a,2);
} else {
a = dec2bin(a);
a = a.substr(16);
a = parseInt(a,2);
}
low = { payload: a };
return low;
視覚化のためにダッシュボードノードを使用したいのですが、2つのバイナリ文字列を結合してintに変換する必要があります。
問題:
ノードredはそれらをqwordとして変換するため、2進数1111 1111 1111 1111 1111 1100 0001 1000は、-1000ではなく、4.294.966.296と見なされます。しかし、次の残りを1ライムで満たす場合:1111 1111 1111 1111 1111 1111 1111 1111 1111 1100 0001 1000は18446744073709552000を出力します
ありがとう
まず、関数ノードで新しいmsg
オブジェクトを作成するのは本当に悪い習慣です。msg.payload
値を更新して元のオブジェクトを渡すだけです。
次にこれを行う最も簡単な方法は、バッファーを操作することです
例えば.
var b = Buffer(4)
b.writeUInt32BE(msg.playload)
msg.payload = b.readInt32BE()
return msg;
手動モードの結合ノードは、2つの小さいバッファーを結合して、長さが16ビットの1つにすることができます。
ええと、JavaScriptはこれを行う強力な型がないため、現時点では不十分です。おそらく最善ではありませんが、これを行う方法の1つは、カスタムInt
クラスを作成することです。
class Int {
constructor(length, binaryStr) {
const cleanBinary = "0".repeat(length - binaryStr.length) + binaryStr
if (cleanBinary.startsWith("1")) {
const invertedBinary = cleanBinary.split("")
.map(char => char === "1" ? "0": "1")
.join("")
this.decValue = -parseInt(invertedBinary, 2) - 1
} else {
this.decValue = parseInt(cleanBinary, 2)
}
}
}
そんな感じ
new Int(8, "11111100")
> Int {decValue: -4}
strBin = "11111111111111111111110000011000";
new Int(strBin.length, strBin)
> Int {decValue: -1000}
これはより高度なものに発展する可能性があり、ブラウザでも使用できます。