Customize the application output

In the previous tutorials, we considered applications that return scalar values as output, such as:

HUX_DECLARE_PROCESSING(app_output, input_channel, {

    float acc_x = ... ;

    HUX_DECLARE_OUTPUT_VALUE(result, Float, "acc_x", acc_x);
    return result;
});

HUX_REGISTER_OUTPUT(app_output);

which produces a simulation output of the following form:

{
    "acc_x":0.23
}

{
    "acc_x":0.12
}
...

Overall, the HUX_DECLARE_OUTPUT_VALUE construct supports the following scalar schemas:

  • Float: an output whose value is of C++ type float

  • Double: an output whose value is of C++ type double

  • Integer: an output whose value is of type hux::int32_t

  • Long: an output whose value is of type hux::int64_t

  • Boolean: an output whose value is of C++ type bool

  • String: an output whose value is of type hux::string

However, in many contexts, an application might need to return more than a single field. For this purpose, the HUX_DECLARE_OUTPUT_VALUE construct allows to declare output values having Object schema. An output value with Object schema is a container for one or more output values. As an example, we could output the X, Y and Z accelerations from an inertial sensor:

HUX_DECLARE_PROCESSING(app_output, input_channel, {

    float acc_x = ... ;
    float acc_y = ... ;
    float acc_z = ... ;

    HUX_DECLARE_OUTPUT_VALUE(x_out, Float, "x", acc_x);
    HUX_DECLARE_OUTPUT_VALUE(y_out, Float, "y", acc_y);
    HUX_DECLARE_OUTPUT_VALUE(z_out, Float, "z", acc_z);

    HUX_DECLARE_OUTPUT_VALUE(xyz_out, Object, "acceleration", x_out, y_out, z_out);

    return xyz_out;
});

HUX_REGISTER_OUTPUT(app_output);

which produces an output of the following form:

{
    "acceleration":{
        "x":0.26,
        "y":0.11,
        "z":-1.01
    }
}

{
    "acceleration":{
        "x":0.25,
        "y":0.17,
        "z":0.98
    }
}
...

It is also possible to include an output value having Object schema within another output value with Object schema:

HUX_DECLARE_PROCESSING(app_output, input_channel, {

    float acc_x = ... ;
    float acc_y = ... ;
    float acc_z = ... ;

    bool alarm_active = ... ;
    hux::uint64_t alarm_ts = ... ;

    HUX_DECLARE_OUTPUT_VALUE(x_out, Float, "x", acc_x);
    HUX_DECLARE_OUTPUT_VALUE(y_out, Float, "y", acc_y);
    HUX_DECLARE_OUTPUT_VALUE(z_out, Float, "z", acc_z);
    HUX_DECLARE_OUTPUT_VALUE(xyz_out, Object, "acceleration", x_out, y_out, z_out);

    HUX_DECLARE_OUTPUT_VALUE(alarm_active_out, Boolean, "active", alarm_active);
    HUX_DECLARE_OUTPUT_VALUE(alarm_ts_out, Long, "timestamp", alarm_ts);
    HUX_DECLARE_OUTPUT_VALUE(alarm_out, Object, "alarm", alarm_active_out, alarm_ts_out);

    HUX_DECLARE_OUTPUT_VALUE(monitoring_out, Object, "monitoring", xyz_out, alarm_out);

    return monitoring_out;
});

HUX_REGISTER_OUTPUT(app_output);

which produces an output of the following form:

{
    "monitoring":{
        "acceleration":{
            "x":0.25,
            "y":0.11,
            "z":1.01
        },
        "alarm":{
            "active":true,
            "timestamp":1656955471200
        }
    }
}
...