Skip to content
Snippets Groups Projects
fluidService.ts 5.18 KiB
Newer Older
  • Learn to ignore specific revisions
  • Hugo NOUTS's avatar
    Hugo NOUTS committed
    import { Client } from 'cozy-client'
    import _ from 'lodash'
    import { DateTime } from 'luxon'
    import { FluidType } from 'enum/fluid.enum'
    import { getPercentage, sum } from 'utils/math'
    import { getDoctype } from 'utils/utils'
    
    export type ProcessedData = {
      consumptionValue: number
      weeklyCompareValue: number
      euclideanComparator: string
    }
    
    export default class FluidService {
      public client: Client
      constructor(client: Client) {
        this.client = client
      }
    
      private getTimeQueryPredicate(
        startingdateTime: DateTime,
        endingdateTime: DateTime
      ) {
        return {
          year: {
            $lte: Math.max(startingdateTime.year, endingdateTime.year),
            $gte: Math.min(startingdateTime.year, endingdateTime.year),
          },
          month: {
            $lte: Math.max(startingdateTime.month, endingdateTime.month),
            $gte: Math.min(startingdateTime.month, endingdateTime.month),
          },
          day: {
            $lte: Math.max(startingdateTime.day, endingdateTime.day),
            $gte: Math.min(startingdateTime.day, endingdateTime.day),
          },
        }
      }
    
      /**
       * Query last 2 week data for grdf energy data
       */
      public getLastTwoWeeks(fluid: FluidType) {
        //const now = DateTime.local(2018, 4, 1)
        const now = DateTime.local()
        const twoWeekBefore = now.minus({
          week: 2,
        })
        return this.client.query(
          this.getClientQuery(
            getDoctype(fluid),
            now,
            twoWeekBefore,
            ['year', 'month', 'day'],
            14
          )
        )
      }
    
      /**
       * Build client query
       * @param doctype doctype name
       * @param startingTime start date for query
       * @param endingTime end date for query
       * @param indexFields fields needed to be indexed
       * @param recordsNumber number or return values
       */
      private getClientQuery(
        doctype: string,
        startingTime: DateTime,
        endingTime: DateTime,
        indexFields: string[],
        recordsNumber: number
      ) {
        return this.client
          .find(doctype)
          .where(this.getTimeQueryPredicate(startingTime, endingTime))
          .indexFields(indexFields)
          .limitBy(recordsNumber)
      }
    
      /**
       * Wrap up data needed for electrical indicators
       * @param {array} toBeProcessedData
       * @return {object} {consumptionValue: number, weeklyCompareValue: number, euclideanComparator: string}
       */
      public processElectricityData(toBeProcessedData: []) {
        const consumptionValue = sum(
          _.slice(_.map(toBeProcessedData, 'load'), 7, 14)
        )
        const weeklyCompareValue = getPercentage(
          _.slice(_.map(toBeProcessedData, 'load'), 7, 14),
          _.slice(_.map(toBeProcessedData, 'load'), 0, 7)
        )
    
        const euclideanComparator = this.getRelevantMetric(
          FluidType.ELECTRICITY,
          consumptionValue
        )
        return {
          consumptionValue: consumptionValue,
          weeklyCompareValue: weeklyCompareValue,
          euclideanComparator: euclideanComparator,
        }
      }
    
      /**
       * Wrap up data needed for gas indicators
       * @param {array} toBeProcessedData
       * @return {object} {consumptionValue: number, weeklyCompareValue: number, euclideanComparator: string}
       */
      public processGasData(toBeProcessedData: []) {
        // Remove last element in order to have pair number of value.
        toBeProcessedData.pop()
        const consumptionValue = sum(
          _.slice(_.map(toBeProcessedData, 'load'), 0, 7)
        )
        const weeklyCompareValue = getPercentage(
          _.slice(_.map(toBeProcessedData, 'load'), 0, 7),
          _.slice(_.map(toBeProcessedData, 'load'), 7, 14)
        )
        const euclideanComparator = this.getRelevantMetric(
          FluidType.GAS,
          consumptionValue
        )
        return {
          consumptionValue: consumptionValue,
          weeklyCompareValue: weeklyCompareValue,
          euclideanComparator: euclideanComparator,
        }
      }
      /**
       * Wrap up data needed for water indicators
       * @param {array} toBeProcessedData
       * @return {object} {consumptionValue: number, weeklyCompareValue: number, euclideanComparator: string}
       */
      public processWaterData(toBeProcessedData: []) {
        const consumptionValue = sum(
          _.slice(_.map(toBeProcessedData, 'load'), 0, 7)
        )
        const weeklyCompareValue = getPercentage(
          _.slice(_.map(toBeProcessedData, 'load'), 0, 7),
          _.slice(_.map(toBeProcessedData, 'load'), 7, 14)
        )
        const euclideanComparator = this.getRelevantMetric(
          FluidType.WATER,
          consumptionValue
        )
        return {
          consumptionValue: consumptionValue,
          weeklyCompareValue: weeklyCompareValue,
          euclideanComparator: euclideanComparator,
        }
      }
    
      /**
       * Return a relevant metric string according to a fluid type and a value
       * @param {FluidType} fluid
       * @param {number} value
       * @return {string} relevantValue
       */
      public getRelevantMetric(fluid: FluidType, value: number) {
        //TODO: When data is ready get it from db or locales
        switch (fluid) {
          case FluidType.ELECTRICITY:
            if (value > 100) {
              return "Vous avez consommé un max d'ampoules !"
            } else {
              return 'Une console de jeu fonctionnant 2 h par jour consomme 1,75 kWh en 1 semaine'
            }
          case FluidType.GAS:
            return 'Ca fait pas un peu trop de gas'
          case FluidType.WATER:
            return '3 piscines du rhône'
          default:
            return 'Pas de comparaison trouvée'
        }
      }
    }