SHOP JSON Standard#

JSON is a new alternative to YAML and ASCII. JSON is the primary method to interacting with SHOP Server.

JSON schema#

Similar to YAML, there are 4 root nodes:

  • time - map

  • model - map

  • connections - list

  • commands - list

A basic overview. This listing represents the basic root structure of a JSON model.

{
  "time": {
  },
  "model": {
  },
  "connections": [
  ],
  "commands": [
  ]
}

Time#

Global simulation settings. Even though the string format "2024-01-01T00:00:00Z" includes a timezone specifier, SHOP does not use that information.

{
  "time": {
    "start_time": "2024-01-01T00:00:00Z",
    "end_time": "2024-01-02T00:00:00Z",
    "time_unit": "minute",
    "time_resolution": {
      "timestamps": [
        "2024-01-00T00:00:00Z"
      ],
      "values": [
        [
          60
        ]
      ]
    }
  }
}

Model#

The model structure is model / object-type / object-name / object-attributes.

Look at object table for all allowed objects.

{
  "model": {
    "reservoir": {
    },
    "plant": {
    },
    "generator": {
    },
    "tunnel": {
    },
    "river": {
    }
  }
}

Connections#

All fields are required.

{
  "connections": [
    {
      "relation_type": "default",
      "relation_direction": "both",
      "from_type": "reservoir",
      "from": "upper_rsv",
      "to_type": "river",
      "to": "upper_river"
    },
  ]
}

Commands#

The command table lists all available commands in SHOP, they have the following JSON format:

{
  "commands": [
    {
      "command": "log file",
      "options": [],
      "values": [
        "logfile.log"
      ]
    }
  ]
}

JSON Attribute Datatypes#

Int#

{
  "model": {
    "plant": {
      "Plant1": {
        "time_delay": 0
      }
    }
  }
}

Int array#

Array of ints.

{
  "model": {
    "plant": {
      "Plant1": {
        "gen_priority": 
          [
            1, 2, 3, 4
          ]
      }
    }
  }
}

Double#

{
  "model": {
    "reservoir": {
      "Lower": {
        "max_vol": 100.0,
        "lrl": 1050.50,
        "hrl": 1550.90
      }
    }
  }
}

Double array#

A list of doubles.

{
    "model": {
        "generator": {
            "Gen1": {
                "discrete_droop_values": [
                    0.1,
                    0.5,
                    1.5
                ]
            }
        }
    }
}

NaN values (not-a-number) can be used for certain attributes, and is the literal case-insensitive string "NaN".

[
  0.0,
  0.1,
  0.2,
  0.3,
  "NaN",
  0.5,
  "NaN",
  0.6,
  0.7,
  0.8,
  0.1
]

String#

{
  "model": {
    "plant": {
      "Plant1": {
        "reserve_type_name": "FCR_N_UP"
      }
    }
  }
}

String array#

Array of strings. Currently only used for output.

Xy#

{
  "model": {
    "reservoir": {
      "Lower": {
        "vol_head": {
          "x_values": [
            0.0,
            5.5,
            10.6,
            15.2,
            20.6
          ],
          "y_values": [
            1000.0,
            1001.5,
            1003.0,
            1010.0,
            1015.42
          ]
        }
      }
    }
  }
}

Ref defaults to 0.0. To explicitly set ref, see the following example.

"vol_head": {
  "ref": 42.0,
  "x_values": [
    0.0,
    5.5,
    10.6,
    15.2,
    20.6
  ],
  "y_values": [
    1000.0,
    1001.5,
    1003.0,
    1010.0,
    1015.42
  ]
}

Xy array#

Array of XYs.

{
  "model": {
    "generator": {
      "plant1_plant2": {
        "turb_eff_curves": {
          "170": {
            "x_values": [
              10.5,
              30.5
            ],
            "y_values": [
              20.5,
              35.0
            ]
          },
          "200": {
            "x_values": [
              50.1,
              60.4
            ],
            "y_values": [
              95.0,
              99.9
            ]
          },
          "230": {
            "x_values": [
              1.0,
              2.2
            ],
            "y_values": [
              20.0,
              22.2
            ]
          }
        }
      }
    }
  }
}

Txy#

With classic SHOP (ASCII, YAML) there is a difference between non-stochastic and stochastic Txy-variables. Txy in JSON are always stochastic. The non-stochastic case is a stochastic with only 1 dimension.

{
  "model": {
    "reservoir": {
      "Lower": {
        "tactical_limit_min": {
          "name": "TacticalLevelMin",
          "timestamps": [
            "2024-01-01T00:00:00Z"
          ],
          "values": [
            [
              2.0
            ]
          ]
        },
        "tactical_limit_max": {
          "name": "TacticalLevelMax",
          "timestamps": [
            "2024-01-01T00:00:00Z"
          ],
          "values": [
            [
              100.0
            ]
          ]
        }
      }
    }
  }
}

Example of a stochastic txy variable in JSON. All value dimensions must be of same size.

"stockastic_example": {
  "name": "Stocastic",
  "timestamps": [
    "2024-01-01T00:00:00Z",
    "2024-02-01T00:00:00Z"
  ],
  "values": [
    [
      100.0, 110.0, 120.0, 130.0
    ],
    [
      200.0, 210.0, 220.0, 230.0
    ],    
  ]
}

Xyt#

Array of XYs where the reference value are time stamps.

{
  "model": {
    "reservoir": {
      "rsv1": {
        "average_level_rolling_ramping_up": {
          "2000-01-01T06:36:00Z": {
            "x_values": [
              1.0,
              2.0,
              3.0
            ],
            "y_values": [
              4.0,
              5.0,
              6.0
            ]
          },
          "2009-12-31T16:48:00Z": {
            "x_values": [
              10.0,
              20.0,
              30.0
            ],
            "y_values": [
              40.0,
              50.0,
              60.0
            ]
          }
        }
      }
    }
  }
}

Sy#

The sy datatype is a list of string-double-pairs.

Some attributes expect the string to be a timestamp. Internally SHOP uses SHOP-timestamp. For an improved user experience, SHOP JSON API will convert any JSON timestamps to SHOP timestamps for all string values, if possible. If the string does not correspond to a timestamp, nothing will be transformed and the string will be sent to SHOP core as is.

When fetching sy data through the JSON interface, the SHOP timestamp will be converted to JSON timestamp format.

{
  "model": {
    "reservoir": {
      "rsv1": {
        "average_level_period_ramping_up_offset": [
          [
            "2000-01-01T06:36:00Z",
            10.0
          ],
          [
            "2005-01-01T06:36:00Z",
            500.0
          ]
        ]
      }
    }
  }
}