
Key takeaways:
If you've ever stared at a CAN bus message wondering how to extract that transmission state buried in bit 3, or needed to decode OBD-II fault codes from raw hexadecimal data, you know the pain. Until now, processing this binary-encoded telematics data meant writing custom parsers, maintaining external scripts, or settling for incomplete data interpretation.
That changes today.
Navixy IoT Logic just got a major upgrade with comprehensive bitwise and byte-level operations, transforming how telematics professionals handle complex vehicle data. Let's explore what this means for your telematics operations and why it's a game-changer for TSPs working with sophisticated fleet data.
Navixy IoT Logic expressions (based on Apache JEXL, Java Expression Language) can be used in two types of flow nodes: Initiate Attribute nodes and Logic nodes. The Initiate Attribute node allows you to create or transform data attributes using custom expressions (e.g. computing new values from raw device data). The Logic node evaluates a boolean expression to split the data flow based on conditions (IF/THEN logic).
In other words, you use expressions to either calculate new values or to define conditional rules in the IoT Logic workflow. For instance, you might compute a new parameter by combining bits from incoming data, or set up a rule that triggers only when specific bit flags are present in the data.
Initiate attribute node: This node lets you derive new attributes by writing JEXL expressions that operate on incoming data fields. Here you can use bitwise math to interpret raw values. For example, if a device sends a combined status byte, you could create separate attributes for each status bit using expressions (see examples below).
Logic node: This node introduces if-then branching based on a boolean expression. All logic node expressions must evaluate to true or false. Bit operations are often used here to check flags within a bit mask – for example, you can route data down the “True” path if a certain bit is set in a status value. This allows condition-based alerts and actions (like triggering an alarm if an engine fault bit is 1) to be configured in a low-code manner. The Logic node essentially implements server-side IF/ELSE logic: if a binary condition in the data is met, then do X, else do Y.
Navixy’s expression language supports the standard set of bitwise operators provided by JEXL. These operate at the binary bit level of integer values. You can use them in expressions to manipulate bits within numeric data (e.g. masking or toggling specific bits). The supported bitwise operators include:
Example:
33 & 4 evaluates to 0 because in binary 33 is 0010 0001 and 4 is 0000 0100; no bit positions overlap with 1, so result is 0000 0000. In IoT logic, io_status & 0x08 would isolate bit 3 of the io_status attribute (since 0x08 in binary is 0000 1000). If that expression is non-zero, it means that specific bit was 1.
Example:
33 | 4 yields 37 because 0010 0001 | 0000 0100 = 0010 0101 (binary for 37). This could merge flags from two values, though in telematics you’ll often OR a value with a mask to set a certain bit to 1.
Example:
33 ^ 4 yields 37 as well (0010 0001 ^ 0000 0100 = 0010 0101) because the bit that was set in 4 gets toggled on in 33, resulting in 37. (XOR is useful for toggling bits (flipping 0 ↔ 1) or checking difference in bit patterns.
Example:
~ 33 results in -34 in a 32-bit system. This is because 33 (0010 0001 in 8-bit for illustration) becomes 1101 1110 which represents -34 in two’s complement form. In practice, ~x can be used to invert a mask (e.g. x & ~0x0F would clear the lower 4 bits of x).
These operators allow fine-grained control over binary data. For instance, if a device sends a single integer where each bit represents a different sensor state (a bit mask), you can use & to test specific bits or extract subsets of bits. Navixy’s platform explicitly anticipates this use-case, as the ability to apply bit masking is a part of its data enhancement toolkit.
In addition to basic bitwise logic, you can shift bits left or right in JEXL. Bit shifts are crucial for combining or slicing multi-byte values. The supported shift operators are:
Example:
1 << 2 gives 4 (binary 0001 becomes 0100). In IoT Logic, if you have a high-byte and want to form a 16-bit value, you might do high_byte << 8 (shift it to the higher 8-bit positions).
Example: 4 >> 2 yields 1 (0100 >> 2 = 0001). If the value was negative, >> would keep it negative by extending the 1s. Right shifts are useful for extracting lower-order bits by pushing unwanted bits out to the right. For example, to drop the lowest 3 bits of a value (keeping the rest), you could do value >> 3.
Using shifts in combination with bit masks lets you target specific bytes or bits in a number.
Example: Say you have a 16-bit value and you need the high 8 bits and low 8 bits separately: you can obtain the high byte with (value>> 8) & 0xFF and the low byte with value & 0xFF. Here, >> 8 shifts the high byte into the lowest byte position, and 0xFF (255 in decimal) is a mask to isolate 8 bits.
In JEXL, you can write numeric literals in hexadecimal (prefix with 0x) for convenience when defining such masks. For example, 0xFF is the mask for 8 bits, 0xF for 4 bits, etc.
Many IoT and CAN bus parameters span multiple bytes or pack several fields into one number. Navixy’s IoT Logic allows you to handle these with bit and shift operations, essentially treating bytes within larger integers. Here are some common techniques for byte-wise manipulation:
(engine_rpm_high << 8) | engine_rpm_low
This shifts the high byte into the upper 8 bits and merges it with the low byte via bitwise OR. The result engine_rpm is a new 16-bit integer attribute. Similarly, you could combine 4 one-byte values into a 32-bit integer by shifting by 24, 16, 8, and 0 bits and OR’ing them together. This is useful for assembling IDs or composite sensor readings that come split into bytes.
Extracting bytes from a word. Conversely, you might get a single 32-bit value from a device but need to extract specific bytes (e.g. status codes or individual sensor bytes within it). Using masks and shifts:
Lowest byte: value & 0xFF gives the lowest 8 bits.
Next byte: (value >> 8) & 0xFF gives bits 8-15.
And so on: (value >> 16) & 0xFF for bits 16-23, (value >> 24) & 0xFF for bits 24-31.
Each time we right-shift the desired byte into the lowest 8-bit position, then mask. This way, you can break down a multi-byte field into separate components if needed for analysis or reporting.
Isolating and interpreting bit fields. Suppose within a byte, different bits or groups of bits carry different meanings (a common scenario with CAN bus status bytes). For example, imagine a single byte from an OBD-II message where: bit0 = MIL (engine warning light) on/off, bits1-3 = fuel system status (0–7), bit4 = some flag, etc. Using IoT Logic, you can isolate these:
mil_on = (status_byte & 0x1) == 1 – this checks the least significant bit. If equal to 1, the MIL indicator is on. Or using util extension: util:checkBit(status_byte, 0).
fuel_system_status = (status_byte >> 1) & 0x7 – this right shifts the byte down by 1 (so bit1 becomes the new LSB) and masks with 0x7 (0b111) to extract the next three bits as a number 0–7. Or using util extension: util:bits(status_byte, 1, 3).
flag = (status_byte & 0x10) != 0 – masks bit4 (0x10 is binary 00010000) and checks if it’s non-zero, resulting in a boolean true if that bit was 1. Or using util extension: util:checkBit(status_byte, 4).
By using these techniques, you can derive new attributes that represent meaningful states or values, instead of dealing with an opaque bitfield. Navixy’s IoT Logic essentially lets you create virtual sensors or calculated fields for any bit-level detail you need, all through expressions.
One of the most powerful aspects of having bit and byte operations in IoT Logic is the ability to drive conditional workflows based on binary signals. In the Logic node, you write an expression that must return true/false – and bitwise expressions fit right in, as long as you compare them to produce a boolean result. Here are a few examples of using bit operations in conditions:
A Logic node condition could be:
(can_status & 0x4) != 0
or using util extension:
util:checkBit(can_status, 2)
This expression uses & 0x4 (mask 0100 binary) to isolate bit 2, and checks if the result is non-zero (meaning bit 2 was 1). If true, the workflow will follow the THEN branch – perhaps raising an alert or recording an engine-overheat event. If false, it follows the ELSE branch or simply does nothing if no ELSE path is configured. This is a classic bit-test condition.
You could write:
(io_flags & 0x03) == 0x03
or using util extension:
util:bits(io_flags, 0, 1) == 0x03
Here 0x03 (binary 00000011) masks the lowest two bits and the expression compares the result to 0x03. It will be true only if both bits 0 and 1 were 1\. This kind of check yields a boolean suitable for the Logic node (true = both conditions met). Another example: using a bitwise OR in a condition – perhaps you want to trigger an action if any out of several bits is set. You could combine bit tests with logical OR (||), or simply mask and compare to zero. E.g. (errors & 0xF0) != 0 would check if _any_ of the upper 4 bits of errors is active (non-zero). This single condition effectively means “at least one of these error flags is present.” If that evaluates true, you might branch to send a diagnostic report.
Overall, using bitwise operations in conditions unlocks a powerful ability: you can create IF-THEN rules based on raw bit-level data coming from vehicles or sensors. Navixy’s documentation notes that JEXL can handle from basic arithmetic to complex logical expressions, and indeed the inclusion of bit masking logic means even low-level binary telemetry can drive high-level actions. Telematics service providers can set up rules like “If any tire-pressure sensor flag is low (from a bitfield) or if the emergency button bit is pressed, then send an alert” – all configured through an expression rather than writing a custom program.
In addition to bitwise operators, Navixy formulas also support a set of utility functions (util) that make it easier to work with numbers at the bit and byte level:
util:signed(Number n, int bytesAmount) [Long] – converts an unsigned number n of size bytesAmount bytes into a signed value. For example, util:signed(65535, 2) returns -1.
util:checkBit(Number n, int bitIndex) [Boolean] – checks whether the bit at position bitIndex in n is set. Returns true or false. For example, util:checkBit(4, 2) returns true.
util:bit(Number n, int bitIndex) [Integer] – returns the value of the bit at position bitIndex (either 1 or 0). For example, util:bit(4, 0) returns 0.
util:bits(Number n, int firstBit, int lastBitInclusive) [Long] – extracts a range of bits from firstBit to lastBitInclusive (inclusive). If lastBitInclusive is less than firstBit, the bits are read in reverse order. For example, util:bits(1321678, 0, 3) returns 14, while util:bits(1321678, 3, 0) returns 7.
util:bytes(Number n, int firstByte, int lastByteInclusive) [Long] – extracts a range of bytes fromfirstByte to lastByteInclusive (inclusive). If lastByteInclusive is less than firstByte, the bytes are read in reverse order. For example, util:bytes(1321678, 0, 1) returns 10958, and util:bytes(1321678, 1, 0) returns 52778.
These functions complement bitwise operators and are particularly useful for parsing custom device protocols or working with raw telemetry values.
Bit and byte operations in IoT Logic are especially valuable in advanced telematics and IoT scenarios, where devices output encoded data. Here are some contexts where you’ll apply these operations:
CAN bus data decoding. Modern GPS trackers with CAN bus interfaces often retrieve rich vehicle data (fuel level, engine RPM, door status, diagnostic codes, etc.). Many of these come as packed binary values. For example, a CAN message might contain several status flags in one byte or a 16-bit value where each bit signifies a different condition (seatbelt fastened, door open, ABS active, etc.). Using Navixy IoT Logic, you can decode such data on the fly. The official Navixy blog highlights that with built-in bitwise operations, integrators can “decode transmission states, detect error flags, or identify vehicle events encoded in binary signals” directly via expressions. This means you could take a raw can_status_word and, within your IoT Logic flow, split it into human-readable pieces (like seatbelt_fastened = true/false, gear_position = N, etc.) without external tools. These derived insights can then be fed to alerts, reports, or further processing in the platform.
OBD-II and vehicle diagnostics. OBD-II data often includes Diagnostic Trouble Codes (DTCs) and status bytes for various onboard tests. For instance, there’s a standard OBD-II PID that returns a bit field of completed/incomplete monitor tests for emissions. By applying bit masks, you could interpret which tests are done or which subsystems reported faults. Additionally, DTC codes themselves are encoded (the first byte contains a mix of bits for system and a numerical code). An advanced user could use shifts and masks to decode a DTC format if sending raw bytes. In practice, many devices parse DTCs for you, but IoT Logic gives you the flexibility to handle any custom or proprietary binary info from OBD devices.
Custom sensor protocols. Beyond vehicles, any IoT sensor that sends binary data (e.g., a pack of digital inputs in one number, or IoT devices that send a bit mask of active alarms) can be parsed with these operations. For example, if you have a temperature sensor that reports an 8-bit status where each bit corresponds to a threshold alarm, you can isolate which thresholds have been exceeded. This is crucial for telematics providers who integrate diverse hardware – IoT Logic acts as a normalization layer where you can interpret device-specific binary formats into unified, meaningful parameters.
Performance and without coding. All these bit/byte manipulations occur in Navixy’s server-side logic in real time, with no need to deploy custom code or firmware changes. The expressions are evaluated on incoming data streams as they arrive, and you can chain multiple operations. For example, you might compute a value from bits using an Initiate Attribute node, then immediately use that new value in a Logic node condition. This is done within milliseconds as data comes in, enabling responsive workflows (like instant alerts or data filtering) based on low-level signals. Navixy emphasizes that this approach requires “no complex coding” and is akin to writing formulas in a spreadsheet – making powerful data processing accessible to telematics engineers and analysts who may not be full-time programmers.
With Navixy's enhanced IoT Logic, you now have direct access to the binary heartbeat of your fleet operations. The bitwise operators (&, |, ^, ~) and bit shifts (<<, >>, >>>) that once required specialized coding expertise are now part of your everyday toolkit. Whether you're decoding CAN bus frames, interpreting custom sensor protocols, or extracting diagnostic flags from raw vehicle data, it all happens within your existing platform workflow.
This isn't just about technical convenience – it's about competitive advantage. While others maintain complex external processing pipelines, you're building responsive, low-code data processing rules that turn binary signals into business intelligence in real-time. Engine diagnostics, sensor statuses, fault detection, all extracted from existing hardware without writing a single line of external software.
The telematics industry has evolved to where handling bytes and bits determines how much value you can extract from IoT data. Navixy's commitment to advanced binary operations ensures you're not just keeping up with that evolution – you're leading it.
Ready to take your telematics data processing to the next level? Contact Sales and see how Navixy’s IoT Logic can transform your IoT workflows.