ecosystem-signal.js

// used to append interfaces to omnicore sdk so that created app and AppStudio can use
import API from './ecosystem-base.js';
import {Logger} from './../function/log-helper.js';
import {ErrorCode} from './../exception/exceptionDesc.js';
import {InfoType, WarningType} from '../information/informationCode.js';

const factoryApiSignalMonitor = function (es) {
  const logModule = 'ecosystem-signal';

  /**
   * The API.SIGNALMONITOR namespace provides a set of interfaces for easily and quickly adds signal monitoring and processing transactions.
   * @alias API.SIGNALMONITOR
   * @namespace
   */
  es.SIGNALMONITOR = new (function () {
    /**
     * Enum for monitor resources
     */
    this.MonitorResources = {
      'digital-signal': 'digital-signal',
    };

    const subscribeRes = async function (signal, func) {
      if (es.isSubscriptionBlocked) {
        Logger.w(WarningType.RWSSubscriptionBlocked, 'API.Signal: Subscription disabled when trying to monitor signal');
        return;
      }
      signal.addCallbackOnChanged(func);
      await signal.subscribe();
    };

    /**
     * Subscribes to a digital signal.
     * @alias monitorDigitalSignal
     * @memberof API.SIGNALMONITOR
     * @param {object} [variableObj] The signal attributes including the signal name and other necessary information.
     * @param {function} [callback] The callback function that is called when the signal changes.
     *
     * @example
     * API.SIGNALMONITOR.monitorDigitalSignal(
     *  {type: 'digitalsignal', name: 'ManualMode'},
     *  (v)=>{
     *    console.log(v);
     *  }
     * )
     */
    this.monitorDigitalSignal = async function (
      signalObj = {type: 'digitalsignal', name: 'ManualMode'},
      callback = null,
    ) {
      const resourceName = `${signalObj.type}-${signalObj.name}`;

      if (es.isFetchControllerBlocked) {
        Logger.w(
          WarningType.RWSRequestBlocked,
          `API.SIGNALMONITOR: HttpRequest disabled when trying to monitor signal ${resourceName}`,
        );
        return;
      }

      //read the state the first time
      try {
        var signalData = await API.SIGNAL.getSignal(signalObj.name);
        typeof callback === 'function' && callback(await signalData.signal.getValue());
      } catch (e) {
        return API.rejectWithStatus(
          `Failed to get signal ${signalObj.name}'s value before subscription`,
          e,
          ErrorCode.FailedToGetSignalValue,
          logModule,
        );
      }

      if (es.isSubscriptionBlocked) {
        Logger.w(
          WarningType.RWSSubscriptionBlocked,
          `API.SIGNALMONITOR: Subscription disabled when trying to monitor signal ${resourceName}`,
        );
        return;
      }

      if (this[resourceName] === undefined) {
        try {
          //Remind:这一块是为了修复初始化时候一个信号被订阅了多次的bug,因为没有赋值,会在初始化的时候重复订阅
          this[resourceName] = 'initialize value';
          const cbDigitalSignal = function (data) {
            Logger.i(logModule, `Signal value:${data}`);
            this[resourceName] = data.toString() || '';
            es._events.trigger(resourceName, this[resourceName]);
            Logger.i(
              InfoType.RobotOperation,
              `Triggered signal value:${this[resourceName]}. The new value is ${data.toString()}`,
            );
          };
          Logger.i(InfoType.RobotOperation, `Signal subscribed:${resourceName}`);
          subscribeRes(signalData.signal, cbDigitalSignal.bind(this));
        } catch (e) {
          return API.rejectWithStatus(
            `Failed to subscribe signal ${signalObj.name}`,
            e,
            ErrorCode.FailedToSubscribeSignal,
            logModule,
          );
        }
      }
      es._events.on(resourceName, callback);
    };
  })();

  es.constructedSignalMonitor = true;
};

if (typeof API.constructedSignalMonitor === 'undefined') {
  factoryApiSignalMonitor(API);
}

export default API;
export {factoryApiSignalMonitor};