generated from Green-Software-Foundation/if-plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create storage read write plugin to estimate energy used when reading…
… and writing data to storages devices
- Loading branch information
1 parent
4cf1f02
commit 6ef0a9c
Showing
5 changed files
with
154 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}; | ||
}; |