Skip to content

Commit

Permalink
Merge pull request #17 from octue/v0.0.5
Browse files Browse the repository at this point in the history
v0.0.5
  • Loading branch information
thclark authored Jan 7, 2020
2 parents 577d155 + f783e0d commit ad45f8f
Show file tree
Hide file tree
Showing 31 changed files with 997 additions and 40 deletions.
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,53 @@ A library to help digital twins talk to one another. Read more at [twined.readth
[![codecov](https://codecov.io/gh/octue/twined/branch/master/graph/badge.svg)](https://codecov.io/gh/octue/twined)
[![Documentation Status](https://readthedocs.org/projects/twined/badge/?version=latest)](https://twined.readthedocs.io/en/latest/?badge=latest)

## Developer notes

**You don't need to pay attention to this unless you plan to develop Twined.**

### Contributing

- Please raise an issue on the board (or add your $0.02 to an existing issue) so the maintainers know
what's happening and can advise / steer you.

- Create a fork of twined, undertake your changes on a new branch (call it whatever you want).

- Ask the `twined` maintainers *where* to make your pull request. We'll create a version branch, according to the
roadmap, into which you can make your PR. We'll help review the changes and improve the PR.

- Once checks have passed, test coverage of the new code is >=95%, documentation is updated and the Review is passed, we'll merge into the version branch.

- Once all the roadmapped features for that version are done, we'll release.


### Release process

The process for creating a new release is as follows:

1. Check out a branch for the next version, called `vX.Y.Z`
2. Create a Pull Request into the `master` branch.
3. Undertake your changes, committing and pushing to branch `vX.Y.Z`
4. Ensure that documentation is updated to match changes, and increment the changelog. **Pull requests which do not update documentation will be refused.**
5. Ensure that test coverage is sufficient. **Pull requests that decrease test coverage will be refused.**
6. Ensure code meets style guidelines (flake8 tests will fail otherwise)
7. Address Review Comments on the PR
8. Ensure the version in `setup.py` is correct and matches the branch version.
9. Merge to master. Successful test, doc build, flake8 and a new version number will automatically create the release on pypi.
10. Go to code > releases and create a new release on GitHub at the same SHA.


### Building documents locally

**You don't need to do this unless you plan to develop Twined.**

- Install `doxgen`. On a mac, that's `brew install doxygen`; other systems may differ.

- Install sphinx and other requirements for building the docs
```
pip install -r docs/requirements.txt
```

- Run the build process
```
sphinx-build -b html docs/source docs/build
```
92 changes: 83 additions & 9 deletions docs/source/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,95 @@
Examples
========

Here, we look at example use cases for the library, and show how to use it in python. Many of these are
Here, we look at example use cases for the library, and show how to use it in python.

It's also well worth looking at the unit test cases
copied straight from the unit test cases, so you can always check there to see how everything hooks up.


.. _example_schema:
.. _example_equipment_installation_cost:

Example Schema
==============
[Simple] Equipment installation cost
====================================

.. tabs::

.. code-tab:: py
.. group-tab:: Scenario

You need to provide your team with an estimate for installation cost of an equipment foundation.

It's a straightforward calculation for you, but the Logistics Team keeps changing the installation position, to
try and optimise the overall project logistics.

Each time the locations change, the GIS team gives you an updated embedment depth, which is what you use
(along with steel cost and foundation type), to calculate cost and report it back.

This twine allows you to define to create a wrapper around your scripts that communicates to the GIS team what you
need as an input, communicate to the logistics team what they can expect as an output.

When deployed as a digital twin, the calculation gets automatically updated, leaving you free to get on with
all the other work!

.. group-tab:: Twine

We specify the ``steel_cost`` and ``foundation_type`` as ``configuration`` values, which you can set on startup of the twin.

Once the twin is running, it requires the ``embedment_depth`` as an ``input_value`` from the GIS team. A member
of the GIS team can use your twin to get ``foundation_cost`` directly.

import numpy as np
import es
.. code-block:: javascript
def main():
pass
{
"title": "Foundation Cost Model",
"description": "This twine helps compute the cost of an installed foundation.",
"children": [
],
"configuration_schema": {
"$schema": "http://json-schema.org/2019-09/schema#",
"title": "Foundation cost twin configuration",
"description": "Set config parameters and constants at startup of the twin.",
"type": "object",
"properties": {
"steel_cost": {
"description": "The cost of steel in GBP/m^3. To get a better predictive model, you could add an economic twin that forecasts the cost of steel using the project timetable.",
"type": "number",
"minimum": 0,
"default": 3000
},
"foundation_type": {
"description": "The type of foundation being used.",
"type": "string",
"pattern": "^(monopile|twisted-jacket)$",
"default": "monopile"
}
}
},
"input_values_schema": {
"$schema": "http://json-schema.org/2019-09/schema#",
"title": "Input Values schema for the foundation cost twin",
"description": "These values are supplied to the twin asynchronously over a web socket. So as these values change, the twin can reply with an update.",
"type": "object",
"properties": {
"embedment_depth": {
"description": "Embedment depth in metres",
"type": "number",
"minimum": 10,
"maximum": 500
}
}
},
"output_manifest": [
],
"output_values_schema": {
"title": "Output Values schema for the foundation cost twin",
"description": "The response supplied to a change in input values will always conform to this schema.",
"type": "object",
"properties": {
"foundation_cost": {
"description": "The foundation cost.",
"type": "integer",
"minimum": 2
}
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/source/images/digital_twin_hierarchy_extended.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 13 additions & 7 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ Twined

A digital twin is a virtual representation of a real life being - a physical asset like a wind turbine or car - or even
a human. Like real things, digital twins need to interact, so can be connected together, but need a common communication
framework to do so. This is what is provided by **twined**.
framework to do so.

**twined** helps you to define a single file, a "twine", that defines a digital twin, specifying its data
interfaces, connections to other twins, and other requirements.

Any person, or any computer, can read a twine and understand *what-goes-in* and *what-comes-out*.

.. figure:: images/digital_twin_hierarchy.svg
:width: 350px
Expand All @@ -41,7 +46,7 @@ framework to do so. This is what is provided by **twined**.
Aims
====

**twined** provides a toolkit to help create and validate ":ref:`schema`" - descriptions of a digital twin, what data it
**twined** provides a toolkit to help create and validate "twines" - descriptions of a digital twin, what data it
requires, what it does and how it works.

The goals of **twined** are as follows:
Expand All @@ -50,8 +55,9 @@ The goals of **twined** are as follows:
- Provide functions to check that a schema itself is valid
- Provide (or direct you to) tools to create schema describing what you require

Using :ref:`schema`, we can describe how digital twins connect and interact... building them together in hierarchies and
networks.
In :ref:`schema`, we describe the different parts of a twine (examining how digital twins connect and interact...
building them together in hierarchies and networks). But you may prefer to dive straight in with the :ref:`quick_start`
guide.

The scope of **twined** is not large. Many other libraries will deal with hosting and deploying digital twins, still
more will deal with the actual analyses done within them. **twined** purely deals with parsing and checking the
Expand Down Expand Up @@ -107,12 +113,12 @@ and are willing to consider sponsorship of development and maintenance of that l

.. toctree::
:maxdepth: 2
:hidden:

self
digital_twins
schema
installation
quick_start
examples
digital_twins
schema
license
version_history
95 changes: 95 additions & 0 deletions docs/source/quick_start.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
.. _quick_start:

============
Quick Start
============

.. _create_a_twine:

Create your first twine
=======================

Let's say we want a digital twin that accepts two values, uses them to make a calculation, then gives the result. Anyone connecting to the twin will need to know what values it requires, and what it responds with.

First, create a blank text file, call it `twine.json`. We'll give the twin a title and description.
Paste in the following:

.. code-block:: javascript
{
"title": "My first digital twin... of an atomising discombobulator",
"description": "A simple example... estimates the `foz` value of an atomising discombobulator."
}
Now, let's define an input values strand, to specify what values are required by the twin. For this we use a json schema
(you can read more about them in :ref:`introducing_json_schema`). Add the ``input_values`` field, so your twine looks like this:

.. code-block:: javascript
{
"title": "My first digital twin",
"description": "A simple example to build on..."
"input_values_schema": {
"$schema": "http://json-schema.org/2019-09/schema#",
"title": "Input Values schema for my first digital twin",
"description": "These values are supplied to the twin by another program (often over a websocket, depending on your integration provider). So as these values change, the twin can reply with an update.",
"type": "object",
"properties": {
"foo": {
"description": "The foo value... speed of the discombobulator's input bobulation module, in m/s",
"type": "number",
"minimum": 10,
"maximum": 500
},
"baz": {
"description": "The baz value... period of the discombobulator's recombulation unit, in s",
"type": "number",
"minimum": 0,
"maximum": 1000
}
}
}
}
Finally, let's define an output values strand, to define what kind of data is returned by the twin:

.. code-block:: javascript
"output_values_schema": {
"$schema": "http://json-schema.org/2019-09/schema#",
"title": "Output Values schema for my first digital twin",
"description": "The twin will output data that matches this schema",
"type": "object",
"properties": {
"foz": {
"description": "Estimate of the foz value... efficiency of the discombobulator in %",
"type": "number",
"minimum": 10,
"maximum": 500
}
}
}
.. _load_the_twine:

Load the twine
==============

**twined** provides a `Twine()` class to load a twine (from a file or a json string).
The loading process checks the twine is valid. It's as simple as:

.. code-block:: py
from twined import Twine
my_twine = Twine(file='twine.json')
.. _validate_some_inputs:

Validate some inputs
====================

.. ATTENTION::
LIBRARY IS UNDER CONSTRUCTION! WATCH THIS SPACE!
11 changes: 7 additions & 4 deletions docs/source/schema.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
.. _schema:

======
Schema
======
=====================
About Twines (Schema)
=====================

This is the core of **twined**, whose whole purpose is to provide and use schemas for digital twins..
The core of **twined** is to provide and use schemas for digital twins.

Below, we set out requirements and a framework for creating a *schema* to represent a digital twin.
We call these schema "twines". To just get started building a **twine**, check out the :ref:`_quick_start`.


.. _requirements:
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@

setup(
name='twined',
version='0.0.4',
version='0.0.5',
py_modules=[],
install_requires=[],
install_requires=['jsonschema ~= 3.2.0'],
url='https://www.github.com/octue/twined',
license=license_text,
author='Octue (github: octue)',
Expand Down
33 changes: 33 additions & 0 deletions tests/data/empty_app/twine.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"children": [
],
"configuration_schema": {
"$schema": "http://json-schema.org/2019-09/schema#",
"title": "The example configuration form",
"description": "The configuration strand of an example twine",
"type": "object",
"properties": {
}
},
"credentials": [
],
"input_manifest": [
],
"input_values_schema": {
"$schema": "http://json-schema.org/2019-09/schema#",
"title": "Input Values",
"description": "The input values strand of an example twine",
"type": "object",
"properties": {
}
},
"output_manifest": [
],
"output_values_schema": {
"title": "Output Values",
"description": "The output values strand of an example twine",
"type": "object",
"properties": {
}
}
}
3 changes: 3 additions & 0 deletions tests/data/example_app/input/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"n_iterations": 16
}
Loading

0 comments on commit ad45f8f

Please sign in to comment.