Skip to content

Implement a REST API #62

@tukusejssirs

Description

@tukusejssirs

Here is my suggestion how the REST API could look like.

We could also consider to add an endpoint to configure log path(s).

Later, we could even consder to create endpoints to get some data gathered from machines (like machine metadata/information, such as machine vendor, model, type).

  • config.yml would be used as initial configuration if that file exists (if not, don’t error out):
    • later, we might want to consider using a kind of configuration persistance (like into a database or even simply updating the config.yml file);
    • when the API is fully featured and functional, we should consider deprecating config.yml and use API requests to configure everything;
  • I suggest to use JSON for both HTTP body and for returned value;
  • notes:
    • in configuration objects, I use TypeScript types:
      • all property values are property data types;
      • when a question mark is placed before colon, that means that the property is optional;
  • consider disabling management (CRUD operations) of transport and create some predefined tranforts that could be used by a machine:
    • reasoning: fanuc-driver only supports predefined transportation values, therefore there is no need to define/configure them by users;
    • transport in machine configuration could be configured to a string like null, mqtt, influx, shdr, spb;
    • TODO: where to put transport-related config like host or port?
  • suggested API endpoints:
    • GET /app/version:

      • get fanuc-driver version;

      • something like this:

        {
           commit: string,  // Git hash
           isDev: boolean,  // Whether the version is a dev version
           version: string  // Version number
        }
    • PUT /app/exit:

      • exit fanuc-driver;
      • this stops monitoring of all machines before actually exitting fanuc-driver;
    • GET /machine:

      • get configuration of all machines;
      • it would be an array of machine configuration objects;
    • POST /machine:

      • add a new machine to monitor;

      • a machine configuration object could look something like this:

        {
           id: string,  // Unique machine ID
           enabled: boolean,  // Whether the monitoring of the machine should be enabled
        
           // TODO: add machine type property, e.g. `type`
           // - possible values would be, e.g., `fanuc`/`focas`, `mazak`/`mtconnect`;
           // - based on the value, `fanuc-driver` would choose appropriate driver/connector/protocol to gather the data from machine;
           type: string,  // `FanucMachine` (or `fanuc`); later even `MazakMachine` (or `mazak`)
           strategy: string,  // `FanucMultiStrategy` (or `multiStrategy`)
           handler: string,  // `fanucOne` (or `one`)
        
           changeFilter?: {
              fanucOne: {
                 changeOnly?: boolean,
                 skipInternal?: boolean
              }
           },
        
           noFilter?: {  // TODO: Is this actually needed? This is kind of duplicate of `changeFilter`.
              fanucOne: {
                 changeOnly?: boolean,
                 skipInternal?: boolean
              }
           },
        
           sources: source_id[],  // Array of target IDs
        
           // Array of collector names (they should be static and defined by `fanuc-driver`); e.g. `['ParameterDump', 'DiagnosisDump', 'PmcDump']` or `['MachineInfo', 'Alarms', 'Messages', 'StateData', 'ToolData', 'ProductionData', 'GCodeData', 'AxisData', 'SpindleData']`
           collectors: string[],
        
           targets: target_id[],  // Array of target IDs
        }
      • if a machine ID is already used, don't create a new machine, but return an error (400);

      • I suggest that all config items (properties of the object above) should have default value but id;

    • DELETE /machine:

      • delete all machines;
    • PUT /machine/start:

      • start monitoring of all machines;
    • PUT /machine/stop:

      • stop monitoring of all machines;
      • when no machine is being monitored, fanuc-driver should be in a stand-by state;
    • GET /machine/:machine:

      • get configuration of a machine;
    • PATCH /machine/:machine:

      • update/modify configuration of a machine;
    • DELETE /machine/:machine:

      • delete a machine (and stop its monitoring);
    • PUT /machine/:machine/start:

      • start monitoring of a machine;
    • PUT /machine/:machine/stop:

      • stop monitoring of a machine;
      • when no machine is being monitored, fanuc-driver should be in a stand-by state;
    • GET /target:

      • get configuration of all targets;
    • POST /target:

      • create a new target;

      • a target configuration object could look something like this:

        {
           id: string,  // Unique target ID
           transport: string,  // One of `null/undefined | 'mqtt' | 'influx' | 'spb'`
           enabled: boolean,  // Whether the target should be enabled
        
           // MQTT
           // TODO: transport-base-mqtt
           topicFormat?: string,
           net?: {
              type: string,
              ip: string,
              port: number
           },
           anonymous?: boolean,
           user?: string,
           password?: string,
        
           // Influx
           // TODO: default-influx-transformers
           host?: string,
           token?: string,
           org?: string,
           bucket?: string,
        
           // SPB
           net?: {
              type: tcp,
              ip: string,
              port: number
           },
           anonymous?: boolean,
           user?: string,
           password?: string,
        
           // SHDR
           // TODO: default-shdr-transformers
           // TODO: default-shdr-model-genny
           deviceName?: string,
           net?: {
              port: number,
              heartbeat: number,
              iterval: number
           }
        }
      • when the value of transport is undefined or null (or potentially when it is omitted), it should be considered as set to null;

      • currently, we use l99.driver.fanuc.transports.MQTT, fanuc for transport in config.yml, however, I think it is too complicated and too verbose:

        • I suggest that transport property value in object above (e.g. set to mqtt) should automatically use l99.driver.fanuc.transports.MQTT, fanuc;
        • I have no idea if fanuc in l99.driver.fanuc.transports.MQTT, fanuc has any special meaning (fanuc is already a substring of l99.driver.fanuc.transports.MQTT), however, if we need to know the machine type (fanuc, mazak, whatever), it should be defined in machine configuration;
      • consider removing enabled source config and consider all sources associated with a particular machine as enabled (i.e. in order to deactivate/disable a source, a user would need to update the machine configuration);

    • DELETE /target:

      • delete all targets;
      • when a target is deleted, either automatically update all machines that use that particular target (i.e. remove the target from machine configuration) or simply reject the request to delete target with a list of machines that use a particular target (an array of targets with array of machines);
    • GET /target/:target:

      • get configuration of a target;
    • PATCH /target/:target:

      • modify configuration of a target;
      • when a target is enabled/disabled, it should be automatically reflected in machine configuration (e.g. when a target is enabled, all machines associated with that target should start using that target);
    • DELETE /target/:target:

      • delete a targget;
      • when a target is deleted, either automatically update all machines that use that particular target (i.e. remove the target from machine configuration) or simply reject the request to delete target with a list of machines that use a particular target (an array of machines);
    • GET /source:

      • get configuration of all sources;
    • POST /source:

      • create a new source;

      • a source configuration object could look something like this:

        {
           id: string,  // Unique source ID
           someName: string,  // For example: `FanucMachine`; I have no idea how to name this property
           sweep: number,  // In milliseconds
           net: {
              ip: string,
              port: number,
              timeout: number  // In seconds; consider changing this to milliseconds
           }
        }
    • DELETE /source:

      • delete all sources;
      • when a source is deleted, either automatically update all machines that use that particular source (i.e. remove the source from machine configuration) or simply reject the request to delete source with a list of machines that use a particular source (an array of sources with array of machines);
    • GET /source/:source:

      • get configuration of a source;
    • PATCH /source/:source:

      • modify configuration of a source;
    • DELETE /source/:source:

      • delete a targget;
      • when a source is deleted, either automatically update all machines that use that particular source (i.e. remove the source from machine configuration) or simply reject the request to delete source with a list of machines that use a particular source (an array of machines).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions