{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "twin serve simulations",
  "description": "A TESS tag's simulations in twin serve, the sim list in its twin block: functions, each a mapping of its name to its parameters. Generated from twin's functions (internal/serve/sim); tess passes them to twin as written.",
  "type": "array",
  "items": {
    "oneOf": [
      {
        "title": "all",
        "description": "Sets the tag true while every tag in of is true, once that has held for delay, and false otherwise; not sets the opposite. (generator)",
        "type": "object",
        "properties": {
          "all": {
            "type": "object",
            "properties": {
              "delay": {
                "description": "How long it holds before the tag goes true; it goes false at once. Default 0s. A duration such as 1s, 500ms or 1m30s, or {tag: path} for a tag's number of milliseconds, as a Siemens TIME counts.",
                "oneOf": [
                  {
                    "type": "string",
                    "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "not": {
                "description": "Sets the opposite, as Normal is true while no alarm is. Default false.",
                "type": "boolean"
              },
              "of": {
                "description": "The Boolean tags it follows, by their Ignition paths, such as ../States/Alarm HH and ../States/Alarm LL.",
                "type": "array",
                "items": {
                  "type": "string"
                },
                "minItems": 1,
                "uniqueItems": true
              },
              "when": {
                "description": "Acts only while each of these tags, by its Ignition path (absolute, or relative to the tag's folder), has its value: a command only in Manual mode, {../States/Manual: true}. A generator leaves the value meanwhile, to another whose when asks the same tag for a different value; a timer counts while it holds and goes back to 0 after. A command is reset without acting, as a PLC does one it ignores.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "type": [
                    "boolean",
                    "number",
                    "string"
                  ]
                }
              }
            },
            "required": [
              "of"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "all"
        ],
        "additionalProperties": false
      },
      {
        "title": "any",
        "description": "Sets the tag true while any tag in of is true, once that has held for delay, and false otherwise; not sets the opposite. (generator)",
        "type": "object",
        "properties": {
          "any": {
            "type": "object",
            "properties": {
              "delay": {
                "description": "How long it holds before the tag goes true; it goes false at once. Default 0s. A duration such as 1s, 500ms or 1m30s, or {tag: path} for a tag's number of milliseconds, as a Siemens TIME counts.",
                "oneOf": [
                  {
                    "type": "string",
                    "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "not": {
                "description": "Sets the opposite, as Normal is true while no alarm is. Default false.",
                "type": "boolean"
              },
              "of": {
                "description": "The Boolean tags it follows, by their Ignition paths, such as ../States/Alarm HH and ../States/Alarm LL.",
                "type": "array",
                "items": {
                  "type": "string"
                },
                "minItems": 1,
                "uniqueItems": true
              },
              "when": {
                "description": "Acts only while each of these tags, by its Ignition path (absolute, or relative to the tag's folder), has its value: a command only in Manual mode, {../States/Manual: true}. A generator leaves the value meanwhile, to another whose when asks the same tag for a different value; a timer counts while it holds and goes back to 0 after. A command is reset without acting, as a PLC does one it ignores.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "type": [
                    "boolean",
                    "number",
                    "string"
                  ]
                }
              }
            },
            "required": [
              "of"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "any"
        ],
        "additionalProperties": false
      },
      {
        "title": "controls",
        "description": "A command: when the tag becomes true, sets each tag in set to its value, turns each Boolean in flip over and adds to each number in add, then sets the tag back to false after resetAfter; with after and then, sets each tag in then once after has passed, as a valve arrives. (reaction)",
        "type": "object",
        "properties": {
          "controls": {
            "type": "object",
            "properties": {
              "add": {
                "description": "The numbers the command steps, by their Ignition paths, each with what it adds, negative to subtract: a number, or {tag: path}, as Increase setpoint adds a step.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "description": "What it adds. A number, or {tag: path} for a tag's value as the simulation acts.",
                  "oneOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "tag": {
                          "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "tag"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              },
              "after": {
                "description": "How long after the command acts then sets its values: a valve's travel time. A duration such as 1s, 500ms or 1m30s, or {tag: path} for a tag's number of milliseconds, as a Siemens TIME counts.",
                "oneOf": [
                  {
                    "type": "string",
                    "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "flip": {
                "description": "The Boolean tags the command turns over, by their Ignition paths, as Toggle block turns ../States/Blocked over.",
                "type": "array",
                "items": {
                  "type": "string"
                },
                "minItems": 1,
                "uniqueItems": true
              },
              "max": {
                "description": "The most add leaves a number at, such as {tag: ../Values/Max auto setpoint}. A number, or {tag: path} for a tag's value as the simulation acts.",
                "oneOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "min": {
                "description": "The least add leaves a number at. A number, or {tag: path} for a tag's value as the simulation acts.",
                "oneOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "resetAfter": {
                "description": "How long the command stays true before it's set back to false, so Ignition sees the pulse. Default 500ms. A duration such as 1s, 500ms or 1m30s.",
                "type": "string",
                "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
              },
              "set": {
                "description": "The tags the command controls, by their Ignition paths (absolute, or relative to the tag's folder: ../States/Auto), each with the value it sets: a constant, or {tag: path} for another tag's value, as Emergency high sets the output to {tag: ../Values/Max control value}.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "oneOf": [
                    {
                      "type": [
                        "boolean",
                        "number",
                        "string"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "tag": {
                          "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "tag"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              },
              "then": {
                "description": "The tags set once after has passed, by their Ignition paths, each with its value: a constant, or {tag: path}, as High feedback goes true and Transit high false once a valve has travelled; not if what the command acted on has changed meanwhile.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "oneOf": [
                    {
                      "type": [
                        "boolean",
                        "number",
                        "string"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "tag": {
                          "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "tag"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              },
              "when": {
                "description": "Acts only while each of these tags, by its Ignition path (absolute, or relative to the tag's folder), has its value: a command only in Manual mode, {../States/Manual: true}. A generator leaves the value meanwhile, to another whose when asks the same tag for a different value; a timer counts while it holds and goes back to 0 after. A command is reset without acting, as a PLC does one it ignores.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "type": [
                    "boolean",
                    "number",
                    "string"
                  ]
                }
              }
            },
            "additionalProperties": false,
            "anyOf": [
              {
                "required": [
                  "set"
                ]
              },
              {
                "required": [
                  "flip"
                ]
              },
              {
                "required": [
                  "add"
                ]
              }
            ]
          }
        },
        "required": [
          "controls"
        ],
        "additionalProperties": false
      },
      {
        "title": "counter",
        "description": "A heartbeat: counts up by step every every, starting at from; past max, or past the largest value the tag's node holds, it starts again at from. (generator)",
        "type": "object",
        "properties": {
          "counter": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "every": {
                "description": "How often it counts. Default 1s. A duration such as 1s, 500ms or 1m30s.",
                "type": "string",
                "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
              },
              "from": {
                "description": "The value it starts at, on each push and after max. Default 0.",
                "type": "number"
              },
              "max": {
                "description": "The largest value it reaches. Default: the largest the node holds, 65535 for a UInt16.",
                "type": "number"
              },
              "step": {
                "description": "What it adds each time. Default 1.",
                "type": "number"
              },
              "when": {
                "description": "Acts only while each of these tags, by its Ignition path (absolute, or relative to the tag's folder), has its value: a command only in Manual mode, {../States/Manual: true}. A generator leaves the value meanwhile, to another whose when asks the same tag for a different value; a timer counts while it holds and goes back to 0 after. A command is reset without acting, as a PLC does one it ignores.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "type": [
                    "boolean",
                    "number",
                    "string"
                  ]
                }
              }
            },
            "additionalProperties": false
          }
        },
        "required": [
          "counter"
        ],
        "additionalProperties": false
      },
      {
        "title": "follows",
        "description": "Moves the tag's value toward target × scale + offset, at most rate per second, or at once without a rate; a Boolean target counts 1 or 0, and a Boolean value follows a Boolean. (generator)",
        "type": "object",
        "properties": {
          "follows": {
            "type": "object",
            "properties": {
              "every": {
                "description": "How often it moves. Default 1s. A duration such as 1s, 500ms or 1m30s.",
                "type": "string",
                "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
              },
              "noise": {
                "description": "How far each move lands off its mark at most, either way, as a measurement jitters. Default 0.",
                "type": "number"
              },
              "offset": {
                "description": "What is added to target × scale. Default 0. A number, or {tag: path} for a tag's value as the simulation acts.",
                "oneOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "rate": {
                "description": "How far it moves each second, in the value's units. From a tag, 0 or less moves it at once, as a light's ramping rate of 0 turns ramping off. Default: all the way at once. A number, or {tag: path} for a tag's value as the simulation acts.",
                "oneOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "scale": {
                "description": "What target is multiplied by. Default 1. A number, or {tag: path} for a tag's value as the simulation acts.",
                "oneOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "target": {
                "description": "The value it moves toward: a number, true or false for a Boolean value, or {tag: path} for a tag's value, such as {tag: ../Values/Raw output}.",
                "oneOf": [
                  {
                    "type": [
                      "boolean",
                      "number"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "when": {
                "description": "Acts only while each of these tags, by its Ignition path (absolute, or relative to the tag's folder), has its value: a command only in Manual mode, {../States/Manual: true}. A generator leaves the value meanwhile, to another whose when asks the same tag for a different value; a timer counts while it holds and goes back to 0 after. A command is reset without acting, as a PLC does one it ignores.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "type": [
                    "boolean",
                    "number",
                    "string"
                  ]
                }
              }
            },
            "required": [
              "target"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "follows"
        ],
        "additionalProperties": false
      },
      {
        "title": "limit",
        "description": "An alarm: while the tag's value is above (or below) the limit, for delay, sets each tag in set true, and false once it's back; with from, it compares the value's distance from from. (reaction)",
        "type": "object",
        "properties": {
          "limit": {
            "type": "object",
            "properties": {
              "above": {
                "description": "The limit the value goes above to alarm, such as {tag: ../Setpoints/Alarm H threshold}. A number, or {tag: path} for a tag's value as the simulation acts.",
                "oneOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "below": {
                "description": "The limit the value goes below to alarm. A number, or {tag: path} for a tag's value as the simulation acts.",
                "oneOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "delay": {
                "description": "How long the value stays beyond the limit before the alarm. Default 0s. A duration such as 1s, 500ms or 1m30s, or {tag: path} for a tag's number of milliseconds, as a Siemens TIME counts.",
                "oneOf": [
                  {
                    "type": "string",
                    "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "from": {
                "description": "What the value is compared with: the alarm compares the distance between them, |value - from|, with the limit, as a deviation warning compares a process value with {tag: ../Values/Auto setpoint}. Default: the alarm compares the value itself. A number, or {tag: path} for a tag's value as the simulation acts.",
                "oneOf": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "set": {
                "description": "The Boolean tags the alarm sets, by their Ignition paths: true while it's active, false otherwise, such as ../States/Alarm H and ../Alarms/Alarm H/Alarm.",
                "type": "array",
                "items": {
                  "type": "string"
                },
                "minItems": 1,
                "uniqueItems": true
              },
              "when": {
                "description": "Acts only while each of these tags, by its Ignition path (absolute, or relative to the tag's folder), has its value: a command only in Manual mode, {../States/Manual: true}. A generator leaves the value meanwhile, to another whose when asks the same tag for a different value; a timer counts while it holds and goes back to 0 after. A command is reset without acting, as a PLC does one it ignores.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "type": [
                    "boolean",
                    "number",
                    "string"
                  ]
                }
              }
            },
            "required": [
              "set"
            ],
            "additionalProperties": false,
            "oneOf": [
              {
                "required": [
                  "above"
                ]
              },
              {
                "required": [
                  "below"
                ]
              }
            ]
          }
        },
        "required": [
          "limit"
        ],
        "additionalProperties": false
      },
      {
        "title": "sine",
        "description": "Swings the tag's value between min and max once every period, following the clock; rounded for a whole-number node. (generator)",
        "type": "object",
        "properties": {
          "sine": {
            "type": "object",
            "properties": {
              "every": {
                "description": "How often the value changes. Default 1s. A duration such as 1s, 500ms or 1m30s.",
                "type": "string",
                "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
              },
              "max": {
                "description": "The highest value.",
                "type": "number"
              },
              "min": {
                "description": "The lowest value.",
                "type": "number"
              },
              "period": {
                "description": "How long one swing, from the middle up to max, down to min and back, takes. A duration such as 1s, 500ms or 1m30s.",
                "type": "string",
                "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
              },
              "phase": {
                "description": "How much later than the clock the swing runs, to set sines apart. Default 0s. A duration such as 1s, 500ms or 1m30s.",
                "type": "string",
                "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
              },
              "when": {
                "description": "Acts only while each of these tags, by its Ignition path (absolute, or relative to the tag's folder), has its value: a command only in Manual mode, {../States/Manual: true}. A generator leaves the value meanwhile, to another whose when asks the same tag for a different value; a timer counts while it holds and goes back to 0 after. A command is reset without acting, as a PLC does one it ignores.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "type": [
                    "boolean",
                    "number",
                    "string"
                  ]
                }
              }
            },
            "required": [
              "min",
              "max",
              "period"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "sine"
        ],
        "additionalProperties": false
      },
      {
        "title": "sum",
        "description": "Sets the tag's value to the sum of the tags in of, each times its factor, times scale plus offset; a Boolean counts 1 or 0. (generator)",
        "type": "object",
        "properties": {
          "sum": {
            "type": "object",
            "properties": {
              "of": {
                "description": "The tags it adds up, by their Ignition paths: a list, or a mapping of each to the factor it counts with, -1 to subtract, as a depth error is {../Values/Setpoint: 1, ../Values/Depth: -1}.",
                "oneOf": [
                  {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                  },
                  {
                    "type": "object",
                    "minProperties": 1,
                    "additionalProperties": {
                      "type": "number"
                    }
                  }
                ]
              },
              "offset": {
                "description": "What is added to the total × scale. Default 0.",
                "type": "number"
              },
              "scale": {
                "description": "What the total is multiplied by. Default 1.",
                "type": "number"
              },
              "when": {
                "description": "Acts only while each of these tags, by its Ignition path (absolute, or relative to the tag's folder), has its value: a command only in Manual mode, {../States/Manual: true}. A generator leaves the value meanwhile, to another whose when asks the same tag for a different value; a timer counts while it holds and goes back to 0 after. A command is reset without acting, as a PLC does one it ignores.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "type": [
                    "boolean",
                    "number",
                    "string"
                  ]
                }
              }
            },
            "required": [
              "of"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "sum"
        ],
        "additionalProperties": false
      },
      {
        "title": "timer",
        "description": "While its when holds, counts the tag's value down to 0, in unit, from the duration from gives, then sets each tag in set to its value; back to 0 once its when stops holding. (generator)",
        "type": "object",
        "properties": {
          "timer": {
            "type": "object",
            "properties": {
              "every": {
                "description": "How often the value counts down. Default 1s. A duration such as 1s, 500ms or 1m30s.",
                "type": "string",
                "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
              },
              "from": {
                "description": "What it counts down from: a duration such as 30m, or {tag: path} for a tag's number of units, as {tag: ../Setpoints/Service mode duration} holds milliseconds. From 0 or less it doesn't count, and never runs out.",
                "oneOf": [
                  {
                    "type": "string",
                    "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "tag": {
                        "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "tag"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "set": {
                "description": "The tags set as it runs out, by their Ignition paths, each with its value: a constant, or {tag: path}, such as {../States/Service mode: false}.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "oneOf": [
                    {
                      "type": [
                        "boolean",
                        "number",
                        "string"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "tag": {
                          "description": "The tag's Ignition path, absolute or relative to the tag's folder.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "tag"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              },
              "unit": {
                "description": "What one of the value's units is, and of from's tag's: 1ms for a Siemens TIME, 1s, or 1m for minutes. Default 1ms. A duration such as 1s, 500ms or 1m30s.",
                "type": "string",
                "pattern": "^([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h)(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)(ns|us|µs|ms|s|m|h))*$"
              },
              "when": {
                "description": "Acts only while each of these tags, by its Ignition path (absolute, or relative to the tag's folder), has its value: a command only in Manual mode, {../States/Manual: true}. A generator leaves the value meanwhile, to another whose when asks the same tag for a different value; a timer counts while it holds and goes back to 0 after. A command is reset without acting, as a PLC does one it ignores.",
                "type": "object",
                "minProperties": 1,
                "additionalProperties": {
                  "type": [
                    "boolean",
                    "number",
                    "string"
                  ]
                }
              }
            },
            "required": [
              "from"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "timer"
        ],
        "additionalProperties": false
      }
    ]
  }
}
