Basically you cannot represent 30.03 exactly in binary.
The publisher is sending the raw value of the data point, which is represented by a Java double as the value you are seeing sent out 30.029...
When using a TextRenderer (which only happens for display purposes) you can set it to round the value via the pattern on it. That is why in the UI it looks correct but it is actually stored as 30.029....
(11110.00000111101011100001)₂ = (1 × 2⁴) + (1 × 2³) + (1 × 2²) + (1 × 2¹) + (0 × 2⁰) + (0 × 2⁻¹) + (0 × 2⁻²) + (0 × 2⁻³) + (0 × 2⁻⁴) + (0 × 2⁻⁵) + (1 × 2⁻⁶) + (1 × 2⁻⁷) + (1 × 2⁻⁸) + (1 × 2⁻⁹) + (0 × 2⁻¹⁰) + (1 × 2⁻¹¹) + (0 × 2⁻¹²) + (1 × 2⁻¹³) + (1 × 2⁻¹⁴) + (1 × 2⁻¹⁵) + (0 × 2⁻¹⁶) + (0 × 2⁻¹⁷) + (0 × 2⁻¹⁸) + (0 × 2⁻¹⁹) + (1 × 2⁻²⁰) = (30.02999973297119140625)₁₀