Skip to content

Commit

Permalink
implemented MockObservations model
Browse files Browse the repository at this point in the history
  • Loading branch information
pazbardanl committed Jan 11, 2024
1 parent 040b8b3 commit bd9ed03
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './ccf';
export * from './teads-aws';
export * from './teads-curve';
export * from './watt-time';
export * from './mock-observations';
152 changes: 136 additions & 16 deletions src/lib/mock-observations/index.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,156 @@
// import axios from 'axios';
// import * as dayjs from 'dayjs';

// import {ERRORS} from '../../util/errors';
import {ERRORS} from '../../util/errors';
import {buildErrorMessage} from '../../util/helpers';

import {ModelParams} from '../../types/common';
import {ModelPluginInterface} from '../../interfaces';
import { ModelPluginInterface } from '../../interfaces';
import * as dayjs from 'dayjs';

import CommonGenerator from './helpers/CommonGenerator';
import RandIntGenerator from './helpers/RandIntGenerator';
import Generator from "./interfaces/index";

Check warning on line 11 in src/lib/mock-observations/index.ts

View workflow job for this annotation

GitHub Actions / build

Strings must use singlequote

// const {AuthorizationError, InputValidationError, APIRequestError} = ERRORS;
const { InputValidationError } = ERRORS;

export class MockObservations implements ModelPluginInterface {
// TODO PB - private members ?
staticParams: object | undefined;
errorBuilder = buildErrorMessage(MockObservations);
timestampFrom: dayjs.Dayjs | undefined;
timestampTo: dayjs.Dayjs | undefined;
duration: number = 0;
timeBuckets: dayjs.Dayjs[] = [];
components: Record<string, Record<string, string>> = {}
// components: object[] = [];
generatorConfigs: object = {};
dateList: dayjs.Dayjs[] = [];

async authenticate(authParams: object): Promise<void> {
// TODO PB -- remove dummy line
this.staticParams = authParams;
// return authParams;
}

async execute(inputs: ModelParams[]): Promise<ModelParams[]> {
// TODO PB -- remove dummy line
this.staticParams = inputs;
// TODO PB -- remove dummy line
return inputs;
async execute(inputs: ModelParams[] /* unused */): Promise<ModelParams[]> {
// TODO PB - remove dummy line, resolve issue of error TS6133: 'inputs' is declared but its value is never read.
console.log(inputs);
// TODO PB - consider making generators a member and creating them at config()
const generators = this.createGenerators(this.generatorConfigs);
let observations: ModelParams[] = []
for (const componentKey in this.components) {
if (this.components.hasOwnProperty(componentKey)) {
const component = this.components[componentKey];
for (const timeBucket of this.timeBuckets) {
let observation: ModelParams = {
timestamp: timeBucket.format('YYYY-MM-DD HH:mm:ss'),
// TODO PB -- this is not always true, the last timebucket might be shorter than the global duration. so duratio should be a property of timebucket (define a DTO for this)
duration: this.duration
};
// TODO PB -- consider this way to copy key-value pairs from component to observation, it looks like an overkill
for (const key in component) {
if (Object.prototype.hasOwnProperty.call(component, key)) {
observation[key] = component[key];
}
}
for (const generator of generators) {
// TODO PB - for future proofing, need to collecat historically generated data and pass it here
//const generated = generator.next([]);
const generated: Record<string, any> = generator.next([]);
// TODO PB -- consider this way to copy key-value pairs from component to observation, it looks like an overkill
for (const key in generated) {
if (Object.prototype.hasOwnProperty.call(generated, key)) {
observation[key] = generated[key];
}
}
}
observations.push(observation);
}
}
}
return observations;
}

// TODO PB - clean this code
async configure(
staticParams: object | undefined
): Promise<ModelPluginInterface> {
if (staticParams === undefined) {
throw new InputValidationError(
this.errorBuilder({ message: 'Input data is missing' })
);
}
if ('timestamp-from' in staticParams) {
this.timestampFrom = dayjs(staticParams['timestamp-from'] as string);
}
else {
throw new InputValidationError(
this.errorBuilder({ message: 'timestamp-from missing from input data' })
);
}
if ('timestamp-to' in staticParams) {
this.timestampTo = dayjs(staticParams['timestamp-to'] as string);
}
else {
throw new InputValidationError(
this.errorBuilder({ message: 'timestamp-to missing from input data' })
);
}
if ('duration' in staticParams) {
this.duration = staticParams['duration'] as number;
}
else {
throw new InputValidationError(
this.errorBuilder({ message: 'duration missing from input data' })
);
}
this.timeBuckets = this.createTimeBuckets(this.timestampFrom, this.timestampTo, this.duration);

if ('components' in staticParams) {
// TODO PB -- is this casting needed?
this.components = staticParams['components'] as Record<string, Record<string, string>>;
}
else {
throw new InputValidationError(
this.errorBuilder({ message: 'components missing from input data' })
);
}
if ('generators' in staticParams) {
// TODO PB -- is this casting needed?
this.generatorConfigs = staticParams['generators'] as object;
}
else {
throw new InputValidationError(
this.errorBuilder({ message: 'generators missing from input data' })
);
}


// TODO PB -- remove dummy line
this.staticParams = staticParams;
return this;
}

private createTimeBuckets(timestampFrom: dayjs.Dayjs, timestampTo: dayjs.Dayjs, duration: number): dayjs.Dayjs[] {
let timeBuckets: dayjs.Dayjs[] = []
let currTimestamp: dayjs.Dayjs = timestampFrom;
while (currTimestamp.isBefore(timestampTo) || currTimestamp.isSame(timestampTo, 'second')) {
timeBuckets.push(currTimestamp);
currTimestamp.add(duration, 'second');
}
return timeBuckets;
}

private createGenerators(generatorsConfig: object): Generator[] {
let generators: Generator[] = [];
Object.entries(generatorsConfig).forEach(([key, value]) => {
console.log(`generator name: ${key}, generator config: ${value}`);
if ('common' === key) {
const commonGenerator = new CommonGenerator();
commonGenerator.initialise("common-generator", value);

Check warning on line 143 in src/lib/mock-observations/index.ts

View workflow job for this annotation

GitHub Actions / build

Strings must use singlequote
generators.push(commonGenerator);
}
if ('randint' === key) {
const randIntGenerator = new RandIntGenerator();
randIntGenerator.initialise("randint-generator", value);

Check warning on line 148 in src/lib/mock-observations/index.ts

View workflow job for this annotation

GitHub Actions / build

Strings must use singlequote
generators.push(randIntGenerator);
}
});
return generators;
}
}

export default MockObservations;
3 changes: 2 additions & 1 deletion src/lib/mock-observations/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export interface Generator {
* generate the next value, optionally based on historical values
*/
next(historical: Object[]): Object;
}
}
export default Generator;

0 comments on commit bd9ed03

Please sign in to comment.