Newts Parading Majestically

    node-vscp

    1.1.23 • Public • Published

    node-vscp

    License Node.js CI

    Utility and constant package for VSCP programming with node.js

    If you are new to VSCP you can find more info here.

    Install

    Install with

    npm install node-vscp

    optionally with '--save' to save dependency in the package.json file.

    Test

    Run

    npm test

    to run the tests.

    Usage

    Reference the module in the beginning of your file like this

    const vscp = require("node-vscp");

    if you want to work with constants instead of magical numbers then the vscp-class and vscp-type module is also useful. Bring them all in like this

    const vscp_class = require('node-vscp-class');
    const vscp_type = require('node-vscp-type');
    
    const vscp = require("node-vscp");

    You can also just import the part of the module you are interested in

    const {priority} = require("node-vscp");

    or more than one

    const {priority, Event} = require("node-vscp");

    and change there names

    const {priority: ttt} = require("node-vscp");

    Constants

    version

    This is the version of the node-vscp module

    • version.major - Major version number
    • version.minor - Minor version number
    • version.release - Release version number

    Example*

    const vscp = require("node-vscp");
    console.log("Module version: " + 
                    vscp.version.major + "." + 
                    vscp.version.minor + "." + 
                    vscp.version.release);

    priority

    This is the type of priority for this event. THis can be a value between 0-7. Lower value is higher priority.

    • priority.PRIORITY_0 - Highest priority for an event.
    • priority.PRIORITY_HIGH - Highest priority for an event.
    • priority.PRIORITY_1 - Priority 1
    • priority.PRIORITY_2 - Priority 2
    • priority.PRIORITY_3 - Priority 3 = Normal
    • priority.PRIORITY_NORMAL - Normal priority 1
    • priority.PRIORITY_4 - Priority 4
    • priority.PRIORITY_5 - Priority 5
    • priority.PRIORITY_6 - Priority 6
    • priority.PRIORITY_7 - Priority 7 - Lowest priority
    • priority.PRIORITY_LOW - Priority low
    const {priority} = require("node-vscp");
    ev = new Event();
    // Set highest priority
    ev.setPriority(priority.PRIORITY_HIGH);
    console.log(priority.PRIORITY_HIGH);
    console.log(priority.PRIORITY_LOW);

    guidtype

    This is what type of GUID this event carries.

    • guidtype.GUIDTYPE_0 - Standard GUID
    • guidtype.GUIDTYPE_STANDARD - Standard GUID
    • guidtype.GUIDTYPE_1 - GUID is IP.v6 address
    • guidtype.GUIDTYPE_IPV6 - GUID is IP.v6 address
    • guidtype.GUIDTYPE_2 - GUID is RFC 4122 Version 1
    • guidtype.GUIDTYPE_RFC4122_1 - GUID is RFC 4122 Version 1,
    • guidtype.GUIDTYPE_3 - GUID is RFC 4122 Version 4
    • guidtype.GUIDTYPE_RFC4122_4 - GUID is RFC 4122 Version 4
    const {priority} = require("node-vscp");
    var h1 = 0;
    console.log("Is standard GUID?",  
        (h1 === vscp.guidtype.GUIDTYPE_STANDARD ) ? "yes" : "no");

    hostCapability

    This is the capabilities of the remote host/server.

    • hostCapability.REMOTE_VARIABLE - Remote variables are supported.
    • hostCapability.DECISION_MATRIX - Decision Matrix is available.
    • hostCapability.INTERFACE - Interfaces available.
    • hostCapability.TCPIP - tcp/ip supported.
    • hostCapability.UDP - udp supported.
    • hostCapability.MULTICAST_ANNOUNCE - Multicast announce supported.
    • hostCapability.RAWETH - Raw ethernet supported.
    • hostCapability.WEB - Web interface available.
    • hostCapability.WEBSOCKET - Websocket interface supported.
    • hostCapability.REST - REST interface supported.
    • hostCapability.MULTICAST_CHANNEL - Multicast channels available.
    • hostCapability.IP6 - IPv6 support.
    • hostCapability.IP4 - IPv4 support.
    • hostCapability.SSL - TLS/SSL support.
    • hostCapability.TWO_CONNECTIONS - Host allow for two or more connections.
    • hostCapability.AES256 - aes256 encryption support.
    • hostCapability.AES192 - aes192 encryption support.
    • hostCapability.AES128 - aes128 encryption support.
    const vscp = require("node-vscp");
    // what_can_you_do is fetched from server to
    // know what capabilities it have
    var what_can_you_do = 0x000f;
    console.log( "Does server accept more than one connection? ", 
    (what_can_you_do & vscp.hostCapability.TWO_CONNECTIONS) ? "yes" : no );

    measurementDataCodingMask

    Measurement data format masks

    • measurementDataCodingMask.MASK_DATACODING_TYPE - Mask for measurement type. Bits 5,6,7
    • measurementDataCodingMask.MASK_DATACODING_UNIT - mask for measurement unit. Bits 3,4
    • measurementDataCodingMask.MASK_DATACODING_INDEX - mask for sensor index. Bits 0,1,2
    const vscp = require("node-vscp");
    // Value = -2.92 C
    var d = [0x89,0x82,0xFE,0xDC];
    console.log("Measurement type",
        (d[0] & vscp.measurementDataCodingMask.MASK_DATACODING_TYPE) >> 5 );
    console.log("Measurement unit",
        (d[0] & vscp.measurementDataCodingMask.MASK_DATACODING_UNIT) >> 3 );
    console.log("Measurement sensor index",
        d[0] & vscp.measurementDataCodingMask.MASK_DATACODING_INDEX );

    measurementDataCoding

    • measurementDataCoding.DATACODING_BIT - measurement data is a bit field.
    • measurementDataCoding.DATACODING_BYTE - measurement data is an array of bytes
    • measurementDataCoding.DATACODING_STRING - measurement data is a string
    • measurementDataCoding.DATACODING_INTEGER - measurement data is an integer (MSB first)
    • measurementDataCoding.DATACODING_NORMALIZED - measurement data is a normalized integer
    • measurementDataCoding.DATACODING_SINGLE - measurement data is a single precision floating point value
    • measurementDataCoding.DATACODING_DOUBLE - measurement data is a double precision floating point value
    • **DATACODING_RESERVED2 .reserved for future use
    const vscp = require("node-vscp");
    // Value = -2.92 C
    var d = [0x89,0x82,0xFE,0xDC];
    console.log("Is this a normalized integer",
        (d[0] & vscp.measurementDataCodingMask.MASK_DATACODING_TYPE) === 
        vscp.measurementDataCoding.DATACODING_NORMALIZED );   

    the VSCP Event class

    This is a helper class that defines a VSCP event. You can use it in the following way

    // Define event with object in constructor and data in array
    e2 = new vscp.Event({
        vscpHead: 0,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });

    or

    // Define event with members
    e2 = new vscp.Event();
    e2.vscpClass = 10;
    e2.vscpType = 6;
    e2.data = [1,2,3,4,5];

    or

    // Define event from text form
    e2 = new vscp.Event({
        text : '3,10,6,4,2020-02-11T17:00:02Z,4074759495,FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01,0x48,0x35,0x31,0x2E,0x39,0x32'
    });
    console.log(e2);

    see setFromString below.

    The full definitions is like this

     * @param {object} options | string                     - Options object or event on string form
     * @param {number} options.vscpHead                     - Event head
     * @param {boolean} options.guidIsIpV6Addr              - GUID is a IPv6 address
     * @param {boolean} options.dumbNode                    - Node is a dumb node
     * @param {number} options.vscpPriority                 - Priority
     * @param {number} options.vscpGuidType                 - GuidType
     * @param {boolean} options.vscpHardCoded               - Hard coded node id
     * @param {boolean} options.vscpCalcCRC                 - Calculate CRC
     * @param {number} options.vscpClass                    - VSCP class
     * @param {number} options.vscpType                     - VSCP type
     * @param {number} options.vscpObId                     - Object id
     * @param {string} options.vscpDateTime                 - ISO UTC Date + time  
     * @param {number} options.vscpTimeStamp                - Timestamp
     * @param {string} options.vscpGuid                     - GUID string
     * @param {(number[]|string)} options.vscpData
     text
     * @param {string} options.text

    Constructors

    Option object

    var ev = new vscp.Event();
    ev.vscpHead = 0x0007;
    ev.vscpClass = 10;
    ev.vscpType = 6;
    ev.vscpData = [1,2,3,4,5];
    ev.vscpGuid = "FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01"

    or

    var ev = new vscp.Event( {
        "vscpHead": 0x0007,
        "vscpClass": 10,
        "vscpType": 6,
        "vscpData": [1,2,3,4,5],
        "vscpGuid": "FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01"
    });

    String

    var ev = new vscp.Event('3,10,6,4,2020-02-11T17:00:02Z,4074759495,FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01,0x48,0x35,0x31,0x2E,0x39,0x32');
    var ev = new vscp.Event({
        text : '3,10,6,4,2020-02-11T17:00:02Z,4074759495,FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01,0x48,0x35,0x31,0x2E,0x39,0x32'
    });

    Methods

    setPriority

    Set priority for the event (0-7). Lower value is higher priority.

    Example

    e5 = new vscp.Event({
        vscpHead: 6 << 5,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log("Priority is", e5.getPriority()  );
    e5.setPriority(vscp.priority.PRIORITY_NORMAL);
    console.log("Priority is", e5.getPriority()  );

    getPriority

    Get priority for event (0-7). Lower value is higher priority.

    Example

    e5 = new vscp.Event({
        vscpHead: 6 << 5,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log("Priority is", e5.getPriority()  );
    e5.setPriority(vscp.priority.PRIORITY_NORMAL);
    console.log("Priority is", e5.getPriority()  );

    setGuidType

    Set GUID type for the event (0-7).

    Example

    e4 = new vscp.Event({
        vscpHead: 6 << 5,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log("GUID type is", e5.getGuidType()  );
    e5.setGuidType(vscp.priority.PRIORITY_NORMAL);
    console.log("GUID type is", e5.getGuidType()  );

    getGuidType

    Get GUID type for event (0-7).

    Example

    e4 = new vscp.Event({
        vscpHead: 6 << 5,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log("GUID type is", e5.getGuidType()  );
    e5.setGuidType(vscp.priority.PRIORITY_NORMAL);
    console.log("GUID type is", e5.getGuidType()  );

    setIPV6Addr

    Set bit in header that mark GUID as IP v6 address

    Example

    e4 = new vscp.Event({
        vscpHead: 0,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log("\nisIPV6Addr");
    console.log("IP v6 address :", 
                (e4.isIPV6Addr() ? "yes" : "no" ), " - vscpHead", 
                e4.vscpHead );
    e4.setIPV6Addr();
    console.log("IP v6 address :", 
                (e4.isIPV6Addr() ? "yes" : "no" ), " - vscpHead", 
                e4.vscpHead );

    isIPV6Addr

    Check if GUID for this event is a IP v6 address or not. Return {boolean}true if it is.

    Example

    e4 = new vscp.Event({
        vscpHead: 0,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log("\nisIPV6Addr");
    console.log("IP v6 address :", 
                (e4.isIPV6Addr() ? "yes" : "no" ), " - vscpHead", 
                e4.vscpHead );
    e4.setIPV6Addr();
    console.log("IP v6 address :", 
                (e4.isIPV6Addr() ? "yes" : "no" ), " - vscpHead", 
                e4.vscpHead );

    setDumbNode

    Set bit that mark this event as coming from a dumb node (No MDF, registers, nothing).

    Example

    e4 = new vscp.Event({
        vscpHead: 0,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log("Dumb node :", 
                (e5.isDumbNode() ? "yes" : "no" ), " - vscpHead", 
                e5.vscpHead );
    e5.setDumbNode();
    console.log("Dumb node :", 
                (e5.isDumbNode() ? "yes" : "no" ), " - vscpHead", 
                e5.vscpHead );

    isDumbNode

    Check if this event is marked as coming from a dumb node. Return {boolean} true if it is.

    Example

    e4 = new vscp.Event({
        vscpHead: 0,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log("Dumb node :", 
                (e5.isDumbNode() ? "yes" : "no" ), " - vscpHead", 
                e5.vscpHead );
    e5.setDumbNode();
    console.log("Dumb node :", 
                (e5.isDumbNode() ? "yes" : "no" ), " - vscpHead", 
                e5.vscpHead );

    setHardCodedAddr

    Set bit that mark this event as a hardcoded address.

    Example

    e4 = new vscp.Event({
        vscpHead: 0,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log(\isHardCodedAddr);
    console.log("Hardcoded address :",
                  (e5.isHardCodedAddr() ? "yes" : "no" ), " - vscpHead", 
                  e5.vscpHead );
    e5.setHardCodedAddr();
    console.log("Hardcoded address :", 
                  (e5.isHardCodedAddr() ? "yes" : "no" ), " - vscpHead", 
                  e5.vscpHead );

    isHardCodedAddr

    Check if hardcoded address.

    Example

    e4 = new vscp.Event({
        vscpHead: 0,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log(\isHardCodedAddr);
    console.log("Hardcoded address :",
                  (e5.isHardCodedAddr() ? "yes" : "no" ), " - vscpHead", 
                  e5.vscpHead );
    e5.setHardCodedAddr();
    console.log("Hardcoded address :", 
                  (e5.isHardCodedAddr() ? "yes" : "no" ), " - vscpHead", 
                  e5.vscpHead );

    setDoNotCalcCRC

    Set bit that mark that no CRC calculations should be done. Typically used by some wireless nodes.

    Example

    e4 = new vscp.Event({
        vscpHead: 0,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log("Calculate CRC :", 
                  (e4.isDoNotCalcCRC() ? "yes" : "no" ), " - vscpHead", 
                  e4.vscpHead );
    e4.setDoNotCalcCRC();
    console.log("Calculate CRC :", 
                  (e4.isDoNotCalcCRC() ? "yes" : "no" ), " - vscpHead", 
                  e4.vscpHead );

    isDoNotCalcCRC

    Return {boolean} true if no CRC calculations should be performed. Typically used by some wireless nodes.

    Example

    e4 = new vscp.Event({
        vscpHead: 0,
        vscpClass: 10,
        vscpType: 6,
        vscpData: [15,14,13,12,11,10,9,8,7,6,5,4,3,2,0,0,1,35]
    });
    
    console.log("Calculate CRC :", 
                  (e4.isDoNotCalcCRC() ? "yes" : "no" ), " - vscpHead", 
                  e4.vscpHead );
    e4.setDoNotCalcCRC();
    console.log("Calculate CRC :", 
                  (e4.isDoNotCalcCRC() ? "yes" : "no" ), " - vscpHead", 
                  e4.vscpHead );

    getAsString

    Get event in string form on the following format

    "vscpHead,vscpClass,vscpType,vscpObId,vscpDateTime,vscpTimeStamp,vscpGuid,vspData"

    This is the standard form to send events in the VSCP tcp/ip link interface.

    Example

    // Define event with object in constructor and data defined 
    // as string. 
    // Also with symbolic class/type
    // Unit=1 Celsius
    // Sensor = 1
    // Format: Normalized integer
    // Value = -2.92 C
    e5 = new vscp.Event({
        vscpHead: 3,
        vscpClass: vscp_class.VSCP_CLASS1_MEASUREMENT,
        vscpType: vscp_type.VSCP_TYPE_MEASUREMENT_TEMPERATURE,
        vscpGuid: "FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01",
        vscpsizeData: 4,
        vscpData: [0x89,0x82,0xFE,0xDC]
    });
    console.log(e5);
    console.log("Event on string form: ", e5.getAsString());
    console.log("Type of:" + typeof e5.vscpDateTime);

    toString

    See getAsString

    setFromString

    Set the event data from a text string on the following format

    "vscpHead,vscpClass,vscpType,vscpObId,vscpDateTime,vscpTimeStamp,vscpGuid,vspData"

    Example

    // Define event by setting from a string
    e = new vscp.Event();
    if (true === (e instanceof vscp.Event)) {
        console.log("YES! e is an instance of Event.");
    }
    e.setFromString('3,10,6,4,2020-02-11T17:00:02Z,4074759495,FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01,0x48,0x35,0x31,0x2E,0x39,0x32');
    console.log(e);

    toJSONObj

    Get event as a JSON object on the form

    {
      vscpHead: 80,
      vscpClass: 10,
      vscpType: 6,
      vscpGuid: '00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:2a',
      vscpObId: 0,
      vscpTimeStamp: 34565634,
      vscpDateTime: 2020-02-24T11:10:59.807Z,
      vscpData: [ 11, 22, 33, 44, 55 ]
    }

    Example

    var e = new Event('3,10,6,4,2020-02-11T17:00:02Z,4074759495,FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01,0x48,0x35,0x31,0x2E,0x39,0x32');
    console.log(e.toJSONObj());

    Other functionality

    readValue

    Read a hex, binary, octal or decimal value {string }and return as an integer {number}.

    Example

    console.log("readValue(\"77\")",vscp.readValue("77"));
    console.log("readValue(\"0x77\")",vscp.readValue("0x77"));
    console.log("readValue(\"0b1010\")",vscp.readValue("0b1010"));
    console.log("readValue(\"0o77\")",vscp.readValue("0o77"));
    console.log("readValue(\"0y77\")",vscp.readValue("0y77"));

    getTime

    Utility function which returns the current time in the following format 'hh:mm:ss.us'

    Example

    console.log(vscp.getTime());

    guidToStr({number}[])

    Converts a GUID number array to a GUID string.

    Example

    var guid = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
    console.log(vscp.guidToStr(guid));

    strToGuid

    Converts a GUID string to a GUID number array.

    Example

    var strguid = "00:01:02:02:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f";
    console.log(vscp.strToGuid(strguid));

    isGuidZero

    Check if a GUID is all zeros and return true if so.

    Example

    var strguid1 = "00:01:02:02:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f";
    var strguid2 = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00";
    console.log("Check GUID str 1 - "+vscp.isGuidZero(strguid1));
    console.log("Check GUID str 2 - "+vscp.isGuidZero(strguid2));
    
    var guid1 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
    var guid2 = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00];
    console.log("Check GUID array 1 - "+vscp.isGuidZero(guid1));
    console.log("Check GUID array 2 - "+vscp.isGuidZero(guid2));

    getNodeId

    Get the node id from a GUID. The node id is a 16-bit id constructed from the two least significant bytes of the GUID.

    For can4vscp the id is just eight bits and GUID byte 14 is always zero for such a node.

    Example

    var strguid1 = "00:01:02:02:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f";
    console.log("Nodeid - ",vscp.getNodeId(strguid1),vscp.getNickName(strguid1));

    getNickname

    This is another function name for getNodeId

    setNodeId(guid,nodeid)

    Set node id on a GUID string.

    Example

    console.log(vscp.setNodeId(strguid1,255));

    setNickName(guid,nodeid)

    See setNodeId (this is a copy of that function)

    b64EncodeUnicode(str)

    Encode a string to base64 unicode safe.

    Example

    console.log(vscp.b64EncodeUnicode("This is a test string"));

    b64DecodeUnicode

    Decode base64 unicode safe.

    Example

    console.log(vscp.b64DecodeUnicode("Q2FycGUgRGllbQo="));

    isGuidIpv6(vscpHead)

    Check if a node use an IPv6 address as it's GUID.

    isDumbNode(vscpHead)

    Check if a node is a dumb node.

    isHardCoded(vscpHead)

    Return true if node GUID is hardcoded.

    isNoCrc(vscpHeader)

    Return true if no CRC should be checked. This is tyically for wireless VSCP nodes.

    getPriority(vscpHead)

    Get priority

    getGuidType(vscpHead)

    Get GUID type

    getRollingIndex(vscpHead)

    Get rolling index (0-7) for a node.

    Measurement event helpers

    toFixed

    var value = 999,678;
    toFixed(value);

    Round a value to fixed precision and output as a string.

    Example This will output "1.2"

    console.log(vscp.toFixed(1.234, 1));

    varInt2BigInt(data)

    varInt2BigInt(data);

    Convert VSCP data bytes to a bigint value. The data that make up the bigint is stored in a byte array with MSB to LSB storage order.

    If you want to convert a bigint to a number use number(bigint-value). So

    console.log(vscp.varInt2BigInt([123]));

    and

    console.log(number(vscp.varInt2BigInt([123])));

    will both output 123 but in the first case it is a bugint (123n) amd in the second case a standard JavaScript number (123).

    Example This will output -292

    console.log(vscp.varInt2BigInt([0xFE,0xDC]));

    Example This will output -1

    console.log(vscp.varInt2BigInt([0xFF]));

    Example This will output 0x7fffffffffffffff

    console.log(vscp.varInt2BigInt([0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff]));

    getDataCoding(code)

    getDataCoding(code);

    Get data coding from a measurement coding byte. The data coding tells how the measurement is encoded in the VSCP databytes. See measurementDataCoding above for possible return values.

    Example This will output 4 which is a normalized integer.

    // Value = -2.92 C
    var d = [0x89,0x82,0xFE,0xDC];
    console.log("Datacoding: ",
        vscp.getDataCoding(d[0]));

    getDataCodingStr

    Returns a descriptive string for the data coding.

    // Value = -2.92 C
    var d = [0x89,0x82,0xFE,0xDC];
    console.log("Datacoding: ",
        vscp.getDataCodingStr(d[0])); // "Datacoding: Normalized integer"

    getUnit

    getUnit(code);

    Get the measurement unit from data coding byte. This is is the encoded measurement unit. See the specification for encodings.

    Example

    // Value = -2.92 C
    var d = [0x89,0x82,0xFE,0xDC];
    console.log("Unit: ",
        vscp.getUnit(d[0]));

    will return 1 for degrees Celsius.

    getSensorIndex

    getSensorIndex(code);

    Get sensor index from the data coding byte. The returned value is 0-7 and is the index for an onboard sensor from which the measurement is originated.

    // Value = -2.92 C
    var d = [0x89,0x82,0xFE,0xDC];
    console.log("Sensor index: ",
        vscp.getSensorIndex(d[0]));

    isMeasurement

    isMeasurement(vscpClass)

    Check if a VSCP class is a measurement class and returns true if it is.

    decodeMeasurementClass10

    // var data = [1,2,3...];
    // var data = Buffer.from([1,2,3...]);
    decodeMeasurementClass10(data);

    Decode a CLASS1.MEASUREMENT (class=10) measurement. What the function return will vary on the coding of the measurement as below

    Coding Return value
    Bytes Array of byte values
    Bits Array with logical values for the bits (MSB -> LSB)
    Integer BigInt
    Normalized Number
    String Number
    Single Number

    data parameter can be array or buffer.

    Also decodes measurement data for CLASS1.MEASUREMENTX1, CLASS1.MEASUREMENTX2, CLASS1.MEASUREMENTX3 and CLASS1.MEASUREMENTX4

    Example

    Will output a floating point value of -2.92

    // Value = -2.92 C
    var d = [0x89,0x82,0xFE,0xDC];
    console.log("Measurement data [0x89,0x82,0xFE,0xDC]is ",
                 vscp.decodeMeasurementClass10(d));

    Example

    The returned value 0x55aa55aa55aa55n is as bigint.

    var data = [0x60,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55];
    var val = vscp.decodeMeasurementClass10(data);
    assert(val === 0x55aa55aa55aa55n);

    Example

    The returned value 0x55aa55aa55aa55n is a bigint.

    var data = [0x60,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55];
    var val = vscp.decodeMeasurementClass10(data);
    assert(val === 0x55aa55aa55aa55n);

    Example

    The returned value 9.909819 as a number.

    var data = [0xA0,65,30,142,158];
    var val = vscp.decodeMeasurementClass10(data);
    assert.equal(vscp.toFixed(val,6),9.909819);

    decodeMeasurementClass60

    // var data = [1,2,3...];
    // var data = Buffer.from([1,2,3...]);
    decodeMeasurementClass60(data);

    Decode a CLASS1.MEASUREMENT64 (class=60) measurement (64-bit double precision floating point value) stored MSB first (big endian). Return value is a number.

    Also decodes measurement data for CLASS1.MEASUREMENT64X1, CLASS1.MEASUREMENT64X2, CLASS1.MEASUREMENT64X3 and CLASS1.MEASUREMENT64X4

    Example

    Return 124.372 as number.

    var data = [64,95,23,206,217,22,135,43];
    var val = vscp.decodeMeasurementClass60(data);
    assert.equal(vscp.toFixed(val,3), 124.372);

    decodeMeasurementClass65

    // var data = [1,2,3...];
    // var data = Buffer.from([1,2,3...]);
    decodeMeasurementClass65(data);

    Decode a CLASS1.MEASUREZONE (class=65) measurement (measurement with zone). Return value is the same as for decodeMeasurementClass10 above.

    Also decodes measurement data for CLASS1.MEASUREZONEX1, CLASS1.MEASUREZONEX2, CLASS1.MEASUREZONEX3 and CLASS1.MEASUREZONEX4

    Example

    Return array with 16 elements true,false....

    var data = [0,1,2,0x00,0xAA,0xAA];
    var bitarray = vscp.decodeMeasurementClass65(data);
    assert.equal(bitarray[0], true);
    assert.equal(bitarray[1], false);
    assert.equal(bitarray[2], true);
    assert.equal(bitarray[3], false);
    assert.equal(bitarray[4], true);
    assert.equal(bitarray[5], false);
    assert.equal(bitarray[6], true);
    assert.equal(bitarray[7], false);
    assert.equal(bitarray[8], true);
    assert.equal(bitarray[9], false);
    assert.equal(bitarray[10], true);
    assert.equal(bitarray[11], false);
    assert.equal(bitarray[12], true);
    assert.equal(bitarray[13], false);
    assert.equal(bitarray[14], true);
    assert.equal(bitarray[15], false);

    Example

    Return two bytes 0xAA and 0+x55

    var data = [0,1,2,0x20,0xAA,0x55];
    var bitarray = vscp.decodeMeasurementClass65(data);
    assert.equal(bitarray[0], 0xAA);
    assert.equal(bitarray[1], 0x55);

    Example

    Return 10.8 as number.

    var data = [0,1,2,0x40,0x31,0x30,0x2e,0x38];
    var val = vscp.decodeMeasurementClass65(data);
    assert(val === 10.8);

    decodeMeasurementClass70

    // var data = [1,2,3...];
    // var data = Buffer.from([1,2,3...]);
    decodeMeasurementClass70(data);

    Decode a CLASS1.MEASUREMENT32 (class=70) measurement (32-bit single precision floating point value) stored MSB first (big endian). Return value is a number.

    Also decodes measurement data for CLASS1.MEASUREMENT32X1, CLASS1.MEASUREMENT32X2, CLASS1.MEASUREMENT32X3 and CLASS1.MEASUREMENT32X4

    Example

    Return 9.909819 as number.

    var data = [65,30,142,158];
    var val = vscp.decodeMeasurementClass70(data);
    assert.equal(vscp.toFixed(val,6),9.909819);

    decodeMeasurementClass85

    // var data = [1,2,3...];
    // var data = Buffer.from([1,2,3...]);
    decodeMeasurementClass85(data);

    Decode a CLASS1.SETVALUEZONE (class=85) measurement (set value with zone). Return value is the same as for decodeMeasurementClass10 above.

    Also decodes measurement data for CLASS1.SETVALUEZONEX1, CLASS1.SETVALUEZONEX2, CLASS1.SETVALUEZONEX3 and CLASS1.SETVALUEZONEX4

    Example

    Return 10.8 as number.

    var data = [0,1,2,0x40,0x31,0x30,0x2e,0x38];
    var val = vscp.decodeMeasurementClass85(data);
    assert(val === 10.8);

    decodeMeasurementClass1040

    // var data = [1,2,3...];
    // var data = Buffer.from([1,2,3...]);
    decodeMeasurementClass1040(data);

    Decode a CLASS2.MEASUREMENT_STR (class=1040) measurement, string representing a floating point value. Return value is a number.

    Example

    Return 12345678.9 as number.

    var data = [0,1,2,0,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x2E,0x39];
    var val = vscp.decodeMeasurementClass1040(data);
    assert.equal(val, 12345678.9);

    decodeMeasurementClass1060

    // var data = [1,2,3...];
    // var data = Buffer.from([1,2,3...]);
    decodeMeasurementClass1060(data);

    Decode a CLASS2.MEASUREMENT_FLOAT (class=1060) measurement 64-bit double precision floating point value stored MSB first (big endian). Return value is a number

    Example

    Return -876.12 as number.

    var data = [0,1,2,0,192,139,96,245,194,143,92,41];
    var val = vscp.decodeMeasurementClass1060(data);
    assert.equal(vscp.toFixed(val,2), -876.12);

    getMeasurementData(event)

    var e = new vscp.Event({
                    vscpClass : vscp_class.VSCP_CLASS1_SETVALUEZONE,
                    vscpType : vscp_type.VSCP_TYPE_MEASUREMENT_TEMPERATURE,
                    vscpData : [0,1,2,0x40,0x30]
                });
    var rv = vscp.getMeasurementData(e);

    This method combine all the decode methods above into one. A measurement event is given as the argument and the result is an object with measurement data on the following form

    {
        datacoding: {number},
        unit: {number},
        sensorindex: {number},
        index: {number},
        zone: {number},
        subzone: {number},
        value: {number | array | bigint}
    }

    value, datacoding, unit and sensorindex is always present and set to defaults if they are not part of the event information.

    datacoding holds information about the origin of value while the value itself is a Javascript number value in the absolute majority of cases, BigInt in one case, an array of booleans in one case and an array of bytes in one case.

    Example

    Return

    {
        index: 0,
        zone: 1,
        subzone: 2,
        sensorindex: 33,
        unit: 0,
        value: 12345678.9
    }

    in rvobj.

    Note that the VSCP_CLASS2_MEASUREMENT_STR class have sensorindex in byte, 0 NOT index (they are different things). index is set to it's default value (0).

    var e = new vscp.Event({
            vscpClass : vscp_class.VSCP_CLASS2_MEASUREMENT_STR,
            vscpType : vscp_type.VSCP_TYPE_MEASUREMENT_TEMPERATURE,
            vscpData : [33,1,2,0,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x2E,0x39]
        });
    var rv = vscp.getMeasurementData(e);
    assert.equal(rv.value, 12345678.9);

    CANAL <--> VSCP conversions

    vscp_getVscpHeadFromCANALid(canid)

    Get VSCP head from extended CAN id.

    getVscpClassFromCANALid(canid)

    Get VSCP class from extended CAN id.

    getVscpTypeFromCANALid

    Get VSCP type from extended CAN id.

    getNicknameFromCANALid(canid)

    Get node id / nickname from CAN id.

    getCANALid(vscpHead, vscpClass, vscpType)

    Get extened canid from VSCP data.

    Note that node id is not added to the canid at this point.

    convertEventToCanMsg(event)

    Convert a level I VSCP event to a CAN message.

    A level I event have a class that is less than 512, a type that is less than 256 and not more than eight data bytes.

    Output is an object with the following format

    {
      "canid": 656897,
      "flags": 1,
      "timestamp": 0,
      "obid": 0,
      "data": [ 137, 130, 254, 220 ]
    }

    {event} convertCanMsgToEvent(canmsg)

    Convert a canmsg to a level I VSCP event.

    A canmsg is an object with the following format

    {
      "id": 656897,
      "timestamp": 0,
      "flags": 1,
      "obid": 0,
      "timestamp": 0,
      "data": [ 137, 130, 254, 220 ]
    }

    data can be string, array, buffer or null. ext should always be true and rtr always false for a VSCP event.

    If timestamp is not given it will get sensible default.

    The resulting GUID will be all nills with the nickname in the LSB.

    Example

    console.log( vscp.convertCanMsgToEvent(
      {
       "id": vscp.getCANALid(7,10,6)+42,
       "ext": true,
       "rtr": false,
       "dlc": 4,
       "data": new Buffer.from([1,2,3,4])
      }
    ));

    Using with node-red

    Node red allows for import of modules that can be then used in the function node. node-vscp is perfect for this.

    First install the module (go to the .node-red folder)

    npm install node-vscp

    Add the module to the settings.js file (also in the .node-red folder).

    functionGlobalContext: {
        vscp:require('node-vscp')
    }

    The vscp before ':' is the name the imported module will be known as in the system

    Now restart node-red with

    systemctl restart nodered
    

    When node-red comes up again you are ready to make node functions that use the vscp helper code. One of the functions in the module is readValue which accepts a string coded as a decimal, hex, octal or binary number and output the result as a decimal number.

    var val = global.get('vscp').readValue(msg.payload)
    msg.payload = val;
    return msg;

    will convert anything that is inputted into the node (must be a string).

    We can now use an inject node and input hex values (preceded with '0x'. octal values (preceded with 0o), binary values (preceded with 0b) or decimal values as they are (but on string form).

    Flow example

    The output is sent to a debug node so we can investigate the result.

    This flow is defined as

    [
        {
            "id": "e12ba6da.b3f8e",
            "type": "tab",
            "label": "Flow 2",
            "disabled": false,
            "info": ""
        },
        {
            "id": "5be7bfca.2fd2d",
            "type": "function",
            "z": "e12ba6da.b3f8e",
            "name": "",
            "func": "var val = global.get('vscp').readValue(msg.payload)\nmsg.payload = val;\nreturn msg;",
            "outputs": 1,
            "noerr": 0,
            "x": 290,
            "y": 160,
            "wires": [
                [
                    "d5c9e3bb.0ea208"
                ]
            ]
        },
        {
            "id": "d5c9e3bb.0ea208",
            "type": "debug",
            "z": "e12ba6da.b3f8e",
            "name": "",
            "active": true,
            "tosidebar": true,
            "console": false,
            "tostatus": false,
            "complete": "false",
            "x": 430,
            "y": 160,
            "wires": []
        },
        {
            "id": "587eb6fe.02125",
            "type": "inject",
            "z": "e12ba6da.b3f8e",
            "name": "",
            "topic": "",
            "payload": "0x99",
            "payloadType": "str",
            "repeat": "",
            "crontab": "",
            "once": false,
            "onceDelay": 0.1,
            "x": 130,
            "y": 160,
            "wires": [
                [
                    "5be7bfca.2fd2d"
                ]
            ]
        },
        {
            "id": "a281b107.456158",
            "type": "inject",
            "z": "e12ba6da.b3f8e",
            "name": "",
            "topic": "",
            "payload": "0o77",
            "payloadType": "str",
            "repeat": "",
            "crontab": "",
            "once": false,
            "onceDelay": 0.1,
            "x": 130,
            "y": 200,
            "wires": [
                [
                    "5be7bfca.2fd2d"
                ]
            ]
        },
        {
            "id": "ba40637f.166d08",
            "type": "inject",
            "z": "e12ba6da.b3f8e",
            "name": "",
            "topic": "",
            "payload": "0b10000001",
            "payloadType": "str",
            "repeat": "",
            "crontab": "",
            "once": false,
            "onceDelay": 0.1,
            "x": 110,
            "y": 240,
            "wires": [
                [
                    "5be7bfca.2fd2d"
                ]
            ]
        },
        {
            "id": "e7d02888.b2e228",
            "type": "inject",
            "z": "e12ba6da.b3f8e",
            "name": "",
            "topic": "",
            "payload": "88",
            "payloadType": "str",
            "repeat": "",
            "crontab": "",
            "once": false,
            "onceDelay": 0.1,
            "x": 130,
            "y": 120,
            "wires": [
                [
                    "5be7bfca.2fd2d"
                ]
            ]
        }
    ]

    well this is not so revolutionary code by you probably get what can be done.

    Using the Event class

    Send VSCP event

    Import also the class/type symbolic files to your project

    npm install node-vscp-class
    npm install node-vscp-class

    and add to

    functionGlobalContext: {
        vscp:require('node-vscp')
        vscpclass:require('node-vscp-class')
        vscptype:require('node-vscp-type')
    }

    The two extra modules are needed because we want to use symbols instead of numbers for VSCP class/type definitions.

    The code for the flow is

    [
        {
            "id": "180fcbf0.3b2644",
            "type": "inject",
            "z": "e12ba6da.b3f8e",
            "name": "Send event",
            "topic": "",
            "payload": "",
            "payloadType": "date",
            "repeat": "",
            "crontab": "",
            "once": false,
            "onceDelay": 0.1,
            "x": 130,
            "y": 340,
            "wires": [
                [
                    "4feb88c6.c208f"
                ]
            ]
        },
        {
            "id": "4feb88c6.c208f",
            "type": "function",
            "z": "e12ba6da.b3f8e",
            "name": "Send VSCP Event",
            "func": "var ev = new (global.get('vscp')).Event({\n    vscpHead: global.get('vscp').priority.PRIORITY_6 << 5,\n    vscpClass: global.get('vscpclass').VSCP_CLASS1_MEASUREMENT,\n    vscpType: global.get('vscptype').VSCP_TYPE_MEASUREMENT_TEMPERATURE,\n    vscpGuid: \"FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01\",\n    vscpsizeData: 4,\n    vscpData: [0x89,0x82,0xFE,0xDC]\n});\nmsg.payload = ev;\nreturn msg;",
            "outputs": 1,
            "noerr": 0,
            "x": 320,
            "y": 340,
            "wires": [
                [
                    "d82c7d24.d6d0b8"
                ]
            ]
        },
        {
            "id": "d82c7d24.d6d0b8",
            "type": "debug",
            "z": "e12ba6da.b3f8e",
            "name": "",
            "active": true,
            "tosidebar": true,
            "console": false,
            "tostatus": false,
            "complete": "payload",
            "targetType": "msg",
            "x": 450,
            "y": 400,
            "wires": []
        }
    ]

    If you look at the code in the function node you see

    var ev = new (global.get('vscp')).Event({
        vscpHead: global.get('vscp').priority.PRIORITY_6 << 5,
        vscpClass: global.get('vscpclass').VSCP_CLASS1_MEASUREMENT,
        vscpType: global.get('vscptype').VSCP_TYPE_MEASUREMENT_TEMPERATURE,
        vscpGuid: "FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01",
        vscpsizeData: 4,
        vscpData: [0x89,0x82,0xFE,0xDC]
    });
    msg.payload = ev;
    return msg;

    Here a new event is defined. Then the ebent is filled with data.

    The event data is set symbolic instead of numeric to be self doucumenting.

    Last the event object is returned and the debug node prints the object when the inject button is pressed.

    In a real world example the debug node would be a VSCP send node such as the output node found in [node-red-contrib-vscp-tcp](https://www.npmjs.com/package/ node-red-contib-vscp-tcp). By defining

    var ev = new (global.get('vscp')).Event({
        vscpHead: global.get('vscp').priority.PRIORITY_6 << 5,
        vscpClass: global.get('vscpclass').VSCP_CLASS1_CONTROL,
        vscpType: global.get('vscptype').VSCP_TYPE_CONTROL_ALL_LAMPS,
        vscpGuid: "FF:FF:FF:FF:FF:FF:FF:FE:B8:27:EB:40:59:96:00:01",
        vscpsizeData: 4,
        vscpData: [0x00,0x11,0x01]
    });
    msg.payload = ev;
    return msg;

    we could turn of all lamps in zone=17, subzone=1


    This package is part of the VSCP(Very Simple Control Protocol) IoT framework.

    Install

    npm i node-vscp

    DownloadsWeekly Downloads

    26

    Version

    1.1.23

    License

    MIT

    Unpacked Size

    324 kB

    Total Files

    15

    Last publish

    Collaborators

    • akhe