Personalizar o acelerador da solução de Monitoramento Remoto

Este artigo fornece informações sobre como acessar o código-fonte e personalizar a interface do usuário do acelerador da solução de Monitoramento Remoto.

Usar o Azure Cloud Shell

O Azure hospeda o Azure Cloud Shell, um ambiente de shell interativo que pode ser usado por meio do navegador. É possível usar o bash ou o PowerShell com o Cloud Shell para trabalhar com os serviços do Azure. É possível usar os comandos pré-instalados do Cloud Shell para executar o código neste artigo sem precisar instalar nada no seu ambiente local.

Para iniciar o Azure Cloud Shell:

Opção Exemplo/Link
Selecione Experimente no canto superior direito de um bloco de código. Selecionar Experimente não copia automaticamente o código para o Cloud Shell. Exemplo de “Experimente” no Azure Cloud Shell
Acesse https://shell.azure.com ou selecione o botão Iniciar o Cloud Shell para abri-lo no navegador. Inicie o Cloud Shell em uma nova janela
Selecione o botão Cloud Shell na barra de menus no canto superior direito do portal do Azure. Botão Cloud Shell no portal do Azure

Para executar o código neste artigo no Azure Cloud Shell:

  1. Inicie o Cloud Shell.

  2. Clique no botão Copiar no bloco de código para copiá-lo.

  3. Cole o código na sessão do Cloud Shell ao pressionar CtrlShiftV no Windows e no Linux ou CmdShiftV no macOS.

  4. Pressione Enter para executar o código.

Preparar um ambiente de desenvolvimento local para a interface do usuário

O código da interface do usuário do acelerador de solução de Monitoramento Remoto é implementado usando a estrutura React.js. Você pode encontrar o código-fonte no repositório azure-iot-pcs-remote-monitoring-webui do GitHub.

Para fazer alterações na interface do usuário, você pode executar uma cópia dela localmente. Para concluir ações, como recuperar a telemetria, a cópia local se conecta a uma instância implantada da solução.

As etapas a seguir descrevem o processo de configurar um ambiente local para o desenvolvimento da interface do usuário:

  1. Implante uma instância básica do acelerador de solução usando a CLI pcs. Anote o nome da sua implantação e as credenciais fornecidas para a máquina virtual. Para saber mais, veja Implantar usando a CLI.

  2. Para habilitar o acesso SSH à máquina virtual que hospeda os micros serviços na sua solução, use o portal do Azure Cloud Shell. Por exemplo:

    az network nsg rule update --name SSH --nsg-name {your solution name}-nsg --resource-group {your solution name} --access Allow
    

    Habilite somente o acesso de SSH durante o desenvolvimento e teste. Se você ativar o SSH, você deve desativá-lo assim que terminar de usá-lo.

  3. Use o portal do Azure Cloud Shell para encontrar o nome e o endereço IP público da sua máquina virtual. Por exemplo:

    az resource list --resource-group {your solution name} -o table
    az vm list-ip-addresses --name {your vm name from previous command} --resource-group {your solution name} -o table
    
  4. Use o SSH para se conectar à sua máquina virtual. Use o endereço IP da etapa anterior e as credenciais fornecidas quando você executou pcs para implementar a solução. O ssh comando está disponível no Azure Cloud Shell.

  5. Para permitir que o UX local se conecta, execute os seguintes comandos no shell bash na máquina virtual:

    cd /app
    sudo ./start.sh --unsafe
    
  6. Depois de ver que o comando foi concluído e o site da Web for iniciado, você poderá se desconectar da máquina virtual.

  7. Em sua cópia local do repositório azure-iot-pcs-remote-monitoring-webui, edite o arquivo .env para adicionar a URL da sua solução implantada:

    NODE_PATH = src/
    REACT_APP_BASE_SERVICE_URL=https://{your solution name}.azurewebsites.net/
    
  8. Em um prompt de comando, navegue até a cópia local da pasta azure-iot-pcs-remote-monitoring-webui.

  9. Para instalar as bibliotecas necessárias e executar a UI localmente, execute os seguintes comandos:

    npm install
    npm start
    
  10. O comando anterior executa a interface do usuário localmente em http://localhost:3000/dashboard. Você pode editar o código enquanto o site está em execução e vê-lo ser atualizado dinamicamente.

Personalizar o layout

Cada página na solução de Monitoramento Remoto é composta de um conjunto de controles, conhecido como painéis no código-fonte. A página Painel é composta por cinco painéis: Visão geral, Mapa, Alertas, Telemetria e Análise. Você pode encontrar o código-fonte que define cada página e seus painéis no repositório pcs-remote-monitoring-webui do GitHub. Por exemplo, o código que define a página Painel, seu layout e os painéis na página está localizado na pasta src/components/pages/dashboard.

Como os painéis gerenciam seus próprios layout e dimensionamento, você pode modificar facilmente o layout de uma página. Faça as seguintes alterações no elemento PageContent no arquivo src/components/pages/dashboard/dashboard.js para:

  • Troque as posições do mapa e dos painéis de telemetria.
  • Altere as larguras relativas dos painéis de mapa e análise.
<PageContent className="dashboard-container">
  <Grid>
    <Cell className="col-1 devices-overview-cell">
      <OverviewPanel
        activeDeviceGroup={activeDeviceGroup}
        openWarningCount={openWarningCount}
        openCriticalCount={openCriticalCount}
        onlineDeviceCount={onlineDeviceCount}
        offlineDeviceCount={offlineDeviceCount}
        isPending={analyticsIsPending || devicesIsPending}
        error={deviceGroupError || devicesError || analyticsError}
        t={t} />
    </Cell>
    <Cell className="col-6">
      <TelemetryPanel
        timeSeriesExplorerUrl={timeSeriesParamUrl}
        telemetry={telemetry}
        isPending={telemetryIsPending}
        lastRefreshed={lastRefreshed}
        error={deviceGroupError || telemetryError}
        theme={theme}
        colors={chartColorObjects}
        t={t} />
    </Cell>
    <Cell className="col-3">
      <AlertsPanel
        alerts={currentActiveAlertsWithName}
        isPending={analyticsIsPending || rulesIsPending}
        error={rulesError || analyticsError}
        t={t}
        deviceGroups={deviceGroups} />
    </Cell>
    <Cell className="col-4">
      <PanelErrorBoundary msg={t('dashboard.panels.map.runtimeError')}>
        <MapPanel
          analyticsVersion={analyticsVersion}
          azureMapsKey={azureMapsKey}
          devices={devices}
          devicesInAlert={devicesInAlert}
          mapKeyIsPending={azureMapsKeyIsPending}
          isPending={devicesIsPending || analyticsIsPending}
          error={azureMapsKeyError || devicesError || analyticsError}
          t={t} />
      </PanelErrorBoundary>
    </Cell>
    <Cell className="col-6">
      <AnalyticsPanel
        timeSeriesExplorerUrl={timeSeriesParamUrl}
        topAlerts={topAlertsWithName}
        alertsPerDeviceId={alertsPerDeviceType}
        criticalAlertsChange={criticalAlertsChange}
        isPending={analyticsIsPending || rulesIsPending || devicesIsPending}
        error={devicesError || rulesError || analyticsError}
        theme={theme}
        colors={chartColorObjects}
        t={t} />
    </Cell>
    {
      Config.showWalkthroughExamples &&
      <Cell className="col-4">
        <ExamplePanel t={t} />
      </Cell>
    }
  </Grid>
</PageContent>

Alterar layout do painel

Você também pode adicionar várias instâncias do mesmo painel, ou várias versões, se você duplicar e personalizar um painel. O exemplo a seguir mostra como adicionar duas instâncias do painel de telemetria. Para fazer essas alterações, edite o arquivo src/components/pages/dashboard/dashboard.js:

<PageContent className="dashboard-container">
  <Grid>
    <Cell className="col-1 devices-overview-cell">
      <OverviewPanel
        activeDeviceGroup={activeDeviceGroup}
        openWarningCount={openWarningCount}
        openCriticalCount={openCriticalCount}
        onlineDeviceCount={onlineDeviceCount}
        offlineDeviceCount={offlineDeviceCount}
        isPending={analyticsIsPending || devicesIsPending}
        error={deviceGroupError || devicesError || analyticsError}
        t={t} />
    </Cell>
    <Cell className="col-3">
      <TelemetryPanel
        timeSeriesExplorerUrl={timeSeriesParamUrl}
        telemetry={telemetry}
        isPending={telemetryIsPending}
        lastRefreshed={lastRefreshed}
        error={deviceGroupError || telemetryError}
        theme={theme}
        colors={chartColorObjects}
        t={t} />
    </Cell>
    <Cell className="col-3">
      <TelemetryPanel
        timeSeriesExplorerUrl={timeSeriesParamUrl}
        telemetry={telemetry}
        isPending={telemetryIsPending}
        lastRefreshed={lastRefreshed}
        error={deviceGroupError || telemetryError}
        theme={theme}
        colors={chartColorObjects}
        t={t} />
    </Cell>
    <Cell className="col-3">
      <AlertsPanel
        alerts={currentActiveAlertsWithName}
        isPending={analyticsIsPending || rulesIsPending}
        error={rulesError || analyticsError}
        t={t}
        deviceGroups={deviceGroups} />
    </Cell>
    <Cell className="col-4">
      <PanelErrorBoundary msg={t('dashboard.panels.map.runtimeError')}>
        <MapPanel
          analyticsVersion={analyticsVersion}
          azureMapsKey={azureMapsKey}
          devices={devices}
          devicesInAlert={devicesInAlert}
          mapKeyIsPending={azureMapsKeyIsPending}
          isPending={devicesIsPending || analyticsIsPending}
          error={azureMapsKeyError || devicesError || analyticsError}
          t={t} />
      </PanelErrorBoundary>
    </Cell>
    <Cell className="col-6">
      <AnalyticsPanel
        timeSeriesExplorerUrl={timeSeriesParamUrl}
        topAlerts={topAlertsWithName}
        alertsPerDeviceId={alertsPerDeviceType}
        criticalAlertsChange={criticalAlertsChange}
        isPending={analyticsIsPending || rulesIsPending || devicesIsPending}
        error={devicesError || rulesError || analyticsError}
        theme={theme}
        colors={chartColorObjects}
        t={t} />
    </Cell>
    {
      Config.showWalkthroughExamples &&
      <Cell className="col-4">
        <ExamplePanel t={t} />
      </Cell>
    }
  </Grid>
</PageContent>

Você pode exibir telemetria diferente em cada painel:

Vários painéis de telemetria

Duplicar e personalizar um controle existente

As etapas a seguir descrevem como duplicar um painel existente, modificá-lo e usar a versão modificada. As etapas usam o painel alertas como um exemplo:

  1. Na sua cópia local do repositório, faça uma cópia da pasta alertas na pasta src/components/pages/dashboard/panels. Nomeie a nova cópia cust_alerts.

  2. No arquivo alertsPanel.js na pasta cust_alerts, edite o nome da classe como CustAlertsPanel:

    export class CustAlertsPanel extends Component {
    
  3. Adicione a seguinte linha ao arquivo src/components/pages/dashboard/panels/index.js :

    export * from './cust_alerts';
    
  4. Substituir alertsPanel por CustAlertsPanel no arquivo src/components/pages/dashboard/dashboard.js:

    import {
      OverviewPanel,
      CustAlertsPanel,
      TelemetryPanel,
      KpisPanel,
      MapPanel,
      transformTelemetryResponse,
      chartColors
    } from './panels';
    
    ...
    
    <Cell className="col-3">
      <CustAlertsPanel
        alerts={currentActivealertsWithName}
        isPending={kpisIsPending || rulesIsPending}
        error={rulesError || kpisError}
        t={t} />
    </Cell>
    

Agora você substituiu o painel de alertas original por uma cópia chamada CustAlerts. Esta cópia é igual à original. Agora você pode modificar a cópia. Por exemplo, para alterar a ordenação das colunas no painel alertas:

  1. Abra o arquivo src/components/pages/dashboard/panels/cust_alerts/alertsPanel.js .

  2. Modifique as definições de coluna conforme mostrado no seguinte snippet de código:

    this.columnDefs = [
      rulesColumnDefs.severity,
      {
        headerName: 'rules.grid.count',
        field: 'count'
      },
      {
        ...rulesColumnDefs.ruleName,
        minWidth: 200
      },
      rulesColumnDefs.explore
    ];
    

A captura de tela a seguir mostra a nova versão do painel alertas:

Painel de alertas atualizado

Personalizar o gráfico de telemetria

Os arquivos na pasta src/components/pages/dashboard/panels/telemtry definem o gráfico de telemetria na página Dashboard. A interface do usuário recupera a telemetria de back-end da solução no arquivo src/services/telemetryService.js. As etapas a seguir mostram como alterar o período de tempo exibido no gráfico de telemetria de 15 a 5 minutos:

  1. No arquivo src/services/telemetryService.js, localize a função chamada getTelemetryByDeviceIdP15M. Faça uma cópia dessa função e modifique a cópia da seguinte maneira:

    static getTelemetryByDeviceIdP5M(devices = []) {
      return TelemetryService.getTelemetryByMessages({
        from: 'NOW-PT5M',
        to: 'NOW',
        order: 'desc',
        devices
      });
    }
    
  2. Para usar essa nova função para popular o gráfico de telemetria, abra o arquivo src/components/pages/dashboard/dashboard.js. Localize a linha que inicia o fluxo de telemetria e modifique-o da seguinte maneira:

    const getTelemetryStream = ({ deviceIds = [] }) => TelemetryService.getTelemetryByDeviceIdP5M(deviceIds)
    

O gráfico de telemetria agora mostra os cinco minutos de dados de telemetria:

Gráfico de telemetria mostrando um dia

Adicionar um novo KPI

A página Painel exibe KPIs no painel Analytics. Esses KPIs são calculados no arquivo src/components/pages/dashboard/dashboard.js. Os KPIs são renderizados pelo arquivo src/components/pages/dashboard/panels/analytics/analyticsPanel.js. As etapas a seguir descrevem como calcular e processar um novo valor de KPI na página Painel. O exemplo mostrado é para adicionar uma nova alteração percentual ao KPI de alarmes de aviso:

  1. Abra o arquivo src/components/pages/dashboard/dashboard.js . Modifique o objeto initialState para incluir uma propriedade warningAlertsChange da seguinte forma:

    const initialState = {
      ...
    
      // Analytics data
      analyticsVersion: 0,
      currentActiveAlerts: [],
      topAlerts: [],
      alertsPerDeviceId: {},
      criticalAlertsChange: 0,
      warningAlertsChange: 0,
      analyticsIsPending: true,
      analyticsError: null
    
      ...
    };
    
  2. Modifique o objeto currentAlertsStats para incluir totalWarningCount como uma propriedade:

    return {
      openWarningCount: (acc.openWarningCount || 0) + (isWarning && isOpen ? 1 : 0),
      openCriticalCount: (acc.openCriticalCount || 0) + (isCritical && isOpen ? 1 : 0),
      totalWarningCount: (acc.totalWarningCount || 0) + (isWarning ? 1 : 0),
      totalCriticalCount: (acc.totalCriticalCount || 0) + (isCritical ? 1 : 0),
      alertsPerDeviceId: updatedAlertsPerDeviceId
    };
    
  3. Calcule o novo KPI. Encontre o cálculo da contagem de alertas críticos. Duplique o código e modifique a cópia da seguinte maneira:

    // ================== Warning Alerts Count - START
    const currentWarningAlerts = currentAlertsStats.totalWarningCount;
    const previousWarningAlerts = previousAlerts.reduce(
      (cnt, { severity }) => severity === Config.ruleSeverity.warning ? cnt + 1 : cnt,
      0
    );
    const warningAlertsChange = ((currentWarningAlerts - previousWarningAlerts) / currentWarningAlerts * 100).toFixed(2);
    // ================== Warning Alerts Count - END
    
  4. Inclua o novo KPI warningAlertsChange no fluxo do KPI:

    return ({
      analyticsIsPending: false,
      analyticsVersion: this.state.analyticsVersion + 1,
    
      // Analytics data
      currentActiveAlerts,
      topAlerts,
      criticalAlertsChange,
      warningAlertsChange,
      alertsPerDeviceId: currentAlertsStats.alertsPerDeviceId,
    
      ...
    });
    
  5. Incluir as novas warningAlertsChange KPI nos dados de estado usados para renderizar a interface do usuário:

    const {
      ...
    
      analyticsVersion,
      currentActiveAlerts,
      topAlerts,
      alertsPerDeviceId,
      criticalAlertsChange,
      warningAlertsChange,
      analyticsIsPending,
      analyticsError,
    
      ...
    } = this.state;
    
  6. Atualize os dados passados para o painel de KPIs:

    <AnalyticsPanel
      timeSeriesExplorerUrl={timeSeriesParamUrl}
      topAlerts={topAlertsWithName}
      alertsPerDeviceId={alertsPerDeviceType}
      criticalAlertsChange={criticalAlertsChange}
      warningAlertsChange={warningAlertsChange}
      isPending={analyticsIsPending || rulesIsPending || devicesIsPending}
      error={devicesError || rulesError || analyticsError}
      theme={theme}
      colors={chartColorObjects}
      t={t} />
    

Agora você terminou as alterações no arquivo src/components/pages/dashboard/dashboard.js. As etapas a seguir descrevem as alterações a fazer no arquivo src/components/pages/dashboard/panels/analytics/analyticsPanel.js para exibir o novo KPI:

  1. Modifique a linha de código a seguir para recuperar o novo valor de KPI da seguinte maneira:

    const { t, isPending, criticalAlertsChange, warningAlertsChange, alertsPerDeviceId, topAlerts, timeSeriesExplorerUrl, error } = this.props;
    
  2. Modifique a marcação para exibir o novo valor do KPI da seguinte maneira:

    <div className="analytics-cell">
      <div className="analytics-header">{t('dashboard.panels.analytics.criticalAlerts')}</div>
      <div className="critical-alerts">
        {
          !showOverlay &&
            <div className="analytics-percentage-container">
              <div className="analytics-value">{ !isNaN(criticalAlertsChange) ? criticalAlertsChange : 0 }</div>
              <div className="analytics-percentage-sign">%</div>
            </div>
        }
      </div>
      <div className="critical-alerts">
        {
          !showOverlay &&
            <div className="analytics-percentage-container">
              <div className="analytics-value">{ !isNaN(warningAlertsChange) ? warningAlertsChange : 0 }</div>
              <div className="analytics-percentage-sign">%</div>
            </div>
        }
      </div>
    </div>
    

A página Painel agora exibe o novo valor de KPI:

KPI de aviso

Personalizar o mapa

Consulte a página Personalizar mapa no GitHub para obter detalhes sobre os componentes de mapa na solução.

Outras opções de personalização

Para modificar ainda mais a camada de apresentação e de visualizações na solução de Monitoramento Remoto, você pode editar o código. Os repositórios do GitHub relevantes são:

Próximas etapas

Neste artigo, você aprendeu sobre os recursos disponíveis para ajudá-lo a personalizar a interface do usuário da Web no acelerador de solução de Monitoramento Remoto. Para saber mais sobre como personalizar a interface do usuário, consulte os seguintes artigos:

Para obter mais informações conceituais sobre o acelerador da solução de Monitoramento Remoto, veja Arquitetura de Monitoramento Remoto

Para obter mais informações sobre como personalizar os microsserviços de solução de monitoramento remoto, consulte Personalizar e reimplantar um microsserviço.