Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a REST API #62

Open
tukusejssirs opened this issue Sep 1, 2022 · 2 comments
Open

Implement a REST API #62

tukusejssirs opened this issue Sep 1, 2022 · 2 comments
Labels
enhancement New feature or request

Comments

@tukusejssirs
Copy link
Contributor

tukusejssirs commented Sep 1, 2022

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).
@ottobolyos
Copy link

@MRIIOT, while REST API (with all endpoints specified in the issue description) would be preferred, how about adding some MQTT control topics to add and remove a machine to/from the monitored machines list at runtime?

I’d remove machine.config.yaml and and use fanuc/add/:machineId with the machine config as JSON payload and fanuc-driver would start monitoring the machine. Similarly, when I publish fanuc/remove/:machineId with no payload, fanuc-driver would stop monitoring the machine.

This way, no web server nor database would be required for this to accomplish.

WDYT? 🤔

@MRIIOT
Copy link
Contributor

MRIIOT commented Jan 13, 2024

If anyone wants to sponsor this then of course.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants