This C example uses the code generated from TransSECS using the NativeWrapper deployment option.

1. Start TransSECS and load the GEMTool Sample Project. Generate the code with the NativeWrapper option selected for deployment. The code will be generated in the GEMTool\NativeWrapper folder. If you used the default installation location this will be at C:\Users\Public\ErgoTech\TransSECSProgrammaticTrial\Projects\GEMTool\NativeWrapper. You may copy the GEMToolRuntime.jar into your project structure or provide a full path when creating the wrapper (see example below):

    new_wrapper_with_classpath("GEMToolRuntime.jar", &wrapper);

2. The header file (transsecs.h) is available here: Download transsecs.h

3 . The dll (transsecs.dll) is available here: Download transsecs.dll. This is standard Windows dll and so will need to be on the executable PATH when the application is run. For Linux (X86-64) the libtranssecs.so is here Download libtranssecs.so (If you need other architectures, such as ARM, please let us know the platform).

To prepare for testing this example, please load the SECSTester provided with TransSECS or load GEMHost Sample Project and generate the code so that TransSECS Builder in run/test mode can be used as a test Host.

Here's the full C code example:

#include "transsecs.h"
 
#include <unistd.h>
#include <stdio.h>
#include <string.h>
 
 // The library wrapper
TransSecsWrapper* wrapper;
 
// Buffer size for getting values from the wrapper
#define BUFFER_SIZE 1024
 
// Define a simple callback function
void start_json_callback(const char* topic, struct ValueObject* valueObject) {
    const char* value = get_object_string_value(valueObject);
    printf("Received json: %s\n", value);
    // You could parse the json here, but for this example we will use the cpvalue
    char cpvalue_buffer[BUFFER_SIZE];
    uintptr_t read = get_topic_string(wrapper, "gemtool/hostcommandstart/cpvalue", cpvalue_buffer, BUFFER_SIZE);
    if (read > 0) {
        printf("Received cpvalue: %s\n", cpvalue_buffer);
        if (strcmp(cpvalue_buffer, "valid_recipe_name") == 0) {
            printf("Valid recipe name\n");
            // Must send a response. Anything published to the sendmessage tag will send the message.
            publish_json(wrapper, "gemtool/hostcommandreply/sendmessage", "");
 
            // do something with the start command here...
        } else {
            printf("Invalid recipe name\n");
            // Set a parameter on the rejection
            publish_string(wrapper, "gemtool/hostcommandrejectedbadparam/cpname", "Bad recipe name");
            // Send the response
            publish_json(wrapper, "gemtool/hostcommandrejectedbadparam/sendmessage", "");
        }
    } else {
        printf("Failed to read cpvalue\n");
        // Even if it goes wrong, we must send a response. In a real application, you would want to send an error response
        // that you have defined instead, but for this example this should be impossible to reach
        publish_json(wrapper, "gemtool/hostcommandreply/sendmessage", "");
    }
}
 
int main() {
    // This should be set to the path of your tool (native) runtime jar file.
    // If you get errors (such as ClassNotFoundException) when running the tool, make sure the path is correct and that you have
    // built a native (IE "C++/Native") deployment type in TransSecs.
    new_wrapper_with_classpath("GEMToolRuntime.jar", &wrapper);
 
    // Optional if the port was set properly when the runtime jar was created
    int port = 5010;
    publish_int(wrapper, "gemtool/configuration/port", port);
 
    u128 listener_uuid; // The listener uuid can be used to unsubscribe later
    subscribe(wrapper, "gemtool/hostcommandstart/json", start_json_callback, &listener_uuid);
 
    wrapper_start_main(wrapper, "GEMTool");
 
    double gasflow = 1.0;
    while (1) {
        // Publish a test float value to the wrapper
        publish_float(wrapper, "gemtool/vids/gasflow", gasflow);
        gasflow += 1.0;
        // Trigger the "LOADED" ceid event
        trigger(wrapper, "loaded", "");
        // Trigger an alarm - to guarantee that the alarm is triggered, for this example we set it to false, then true
        transsecs_alarm(wrapper, "gasflowproblem", false);
        transsecs_alarm(wrapper, "gasflowproblem", true);
        sleep(10);
    }    
    return 0;
}