Skip to content

Commit

Permalink
Create storage read write plugin to estimate energy used when reading…
Browse files Browse the repository at this point in the history
… and writing data to storages devices
  • Loading branch information
jmain-scottlogic committed Apr 2, 2024
1 parent 4cf1f02 commit 6ef0a9c
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 0 deletions.
32 changes: 32 additions & 0 deletions examples/storage-read-write-energy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: basic storage read/write energy example
description: Uses minimal mock data to run the plugin
tags: null
initialize:
plugins:
import-data:
path: '@grnsft/if-plugins'
method: MockObservations
global-config:
timestamp-from: 2024-03-05T00:00
timestamp-to: 2024-03-05T01:00
duration: 300
components:
- name: storage-1
generators:
randint:
storage/data-transfer:
min: 100
max: 20000
storage/drive-read-write-power:
min: 15
max: 20
storage/drive-read-write-speed:
min: 1
max: 6
object-storage-read-write:
method: StorageReadWriteEnergy
path: 'if-carbon-hack-plugin'
tree:
pipeline:
- import-data
- object-storage-read-write
32 changes: 32 additions & 0 deletions src/__tests__/unit/lib/storage-read-write-energy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {StorageReadWriteEnergy} from '../../../lib/storage-read-write-energy';

describe('lib/storage-read-write-energy: ', () => {
describe('StorageReadWriteEnergy(): ', () => {
it('has metadata field.', () => {
const pluginInstance = StorageReadWriteEnergy();

expect(pluginInstance).toHaveProperty('metadata');
expect(pluginInstance).toHaveProperty('execute');
expect(pluginInstance.metadata).toHaveProperty('kind');
expect(typeof pluginInstance.execute).toBe('function');
});

describe('execute(): ', () => {
it('calculates kWh of read/write of 1TB of data, at a speed of 5Gb/s, to storage device', async () => {
const pluginInstance = StorageReadWriteEnergy();
const inputs = [
{
duration: 200,
'storage/drive-read-write-power': 20,
'storage/drive-read-write-speed': 5,
'storage/data-transfer': 1000,
},
];

const response = await pluginInstance.execute(inputs, {});
expect(response[0]).toHaveProperty('storage/energy');
expect(response[0]['storage/energy']).toBeCloseTo(0.00111, 5);
});
});
});
});
1 change: 1 addition & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export {CloudStorageMetadata} from './cloud-storage-metadata';
export {ObjectStorage} from './object-storage';
export {RambollResilio} from './ramboll-resilio';
export {StorageEnergy} from './storage-energy';
export {StorageReadWriteEnergy} from './storage-read-write-energy';
38 changes: 38 additions & 0 deletions src/lib/storage-read-write-energy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Storage Read Write Energy

This plugin allows you to estimate the energy required to read/write data to a storage device, amount of data and drive type

## Parameters

## Plugin Config

Not Needed

### Inputs

- `duration`: Length of time the it will take to read/write the data
- `storage/drive-read-write-power`: Power of the drive(s), when reading/writing, used in Watts
- `storage/drive-read-write-speed`: Read/write speed of storage device used in Gb/s
- `storage/data-transfer`: Amount of data to be read/written in Gb

## Returns

An array containing:

- `duration`: Length of time the it will take to read/write the data
- `storage/drive-read-write-power`: Power of the drive(s), when reading/writing, used in Watts
- `storage/drive-read-write-speed`: Read/write speed of storage device used in Gb/s
- `storage/data-transfer`: Amount of data to be read/written in Gb
- `storage/energy`: The energy apportioned to reading/writing data in kWh

## IF Implementation

To avoid tying the plugin to any point in time data, it requires the individual drive details to be passed in.Calculates the minimum time that that data could be written/read in, using:

$$drive\text-read\text-write\text-speed \times data\text-transfer = min \space time$$

If this is less than the provided duration it will use this instead. The formula for energy estimation is then:

$$\frac{drive\text-read\text-write\text-power}{1000} \times \frac{duration}{60 \times 60} = energy$$

Where $\frac{drive\text-read\text-write\text-power}{1000}$ gives a figure for kW and $\frac{duration}{60 \times 60}$ gives the time in hours.
51 changes: 51 additions & 0 deletions src/lib/storage-read-write-energy/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {z} from 'zod';
import {PluginInterface, PluginParams} from '../types/interface';
import {validate} from '../util/validations';
import {SECONDS_IN_HOUR} from '../constants';

export const StorageReadWriteEnergy = (): PluginInterface => {
const metadata = {
kind: 'execute',
};

/**
* Execute's strategy description here.
*/
const execute = async (inputs: PluginParams[]): Promise<PluginParams[]> => {
return inputs.map(input => {
const safeInput = validateInput(input);
const minTime = Math.ceil(
safeInput['storage/data-transfer'] /
safeInput['storage/drive-read-write-speed']
);

const duration = Math.max(safeInput.duration, minTime);
const kW = safeInput['storage/drive-read-write-power'] / 1000;
const durationInHours = duration / SECONDS_IN_HOUR;

return {
...input,
'storage/energy': kW * durationInHours,
};
});
};

/**
* Checks for required fields in input.
*/
const validateInput = (input: PluginParams) => {
const schema = z.object({
duration: z.number().positive(),
'storage/drive-read-write-power': z.number().positive(),
'storage/drive-read-write-speed': z.number().positive(),
'storage/data-transfer': z.number().positive(),
});

return validate<z.infer<typeof schema>>(schema, input);
};

return {
metadata,
execute,
};
};

0 comments on commit 6ef0a9c

Please sign in to comment.