doc/svghmi/intro.rst
author Edouard Tisserant <edouard.tisserant@gmail.com>
Wed, 03 Apr 2024 13:02:50 +0200
changeset 3925 1d383b4c0a23
permissions -rw-r--r--
Doc: re-organize existing, sketch outline, add SVGHMI intro.
3925
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     1
Introduction to SVGHMI
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     2
======================
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     3
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     4
+-----------------------------+-------------------------------------------------------------------------------+
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     5
|                             | SVGHMI is a SVG based HMI toolkit. With it, PLC programmers and HMI designers |
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     6
| .. image:: svhgmi_pitch.svg | can efficiently produce Scalable Web Based HMIs. <br />  <br /> HMI design    |
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     7
|                             | happens in `Inkscape  <https://inkscape.org>`_.                               |
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     8
|                             | Designer freely draws HMI pages and widgets following WYSIWYG principle.      |
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     9
+-----------------------------+-------------------------------------------------------------------------------+
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    10
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    11
WYSIWYG HMI design with Inkscape
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    12
--------------------------------
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    13
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    14
    "**What You See Is What You Get**, is a system in which editing software
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    15
    allows content to be edited in a form that resembles its appearance when
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    16
    printed or displayed as a finished product."
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    17
    
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    18
    -- Oxford English Dictionary
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    19
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    20
Widgets can be selected from customizable widget library and drag'n'dropped
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    21
directly in Inkscape.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    22
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    23
.. image:: svghmi_dnd.svg
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    24
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    25
SVGHMI's Page and Widget roles are assigned to SVG elements by changing objects
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    26
name and description in Inkscape.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    27
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    28
.. image:: svhgmi_inkscape.svg
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    29
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    30
HMI tree scale together with PLC instance tree
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    31
----------------------------------------------
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    32
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    33
In SVGHMI, **scalability** applies to both graphics and data. Once HMI and PLC
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    34
are associated in a first version of a machine, it is easy to extend both of
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    35
them simultaneously. In most cases DRY principle applies. PLC code or SVG
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    36
elements can be re-used and extended.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    37
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    38
PLC data exposed to HMI is represented in an "HMI Tree" deduced from PLC
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    39
program. More precisely, HMI Tree is a simplified subset of POU instances tree.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    40
PLC  programmer selects variables to be exposed by assigning them a derived
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    41
HMI_* type. For example HMI_REAL is used instead of REAL to expose a floating
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    42
point variable.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    43
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    44
.. image:: svghmi_trees.svg
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    45
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    46
In order to reduce HMI Tree complexity, structure of POU instance tree is not
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    47
preserved by default. Only POUs having a single HMI_NODE variable defined
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    48
appear in HMI Tree. This allows to expose variables that are spread in a
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    49
complex hierarchy of POUs in a single HMI Tree node.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    50
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    51
.. image:: svghmi_types.svg
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    52
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    53
Re-usable widgets and pages
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    54
---------------------------
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    55
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    56
HMI elements are SVG elements whose labels start with ``HMI:``.  They can be
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    57
widgets or pages, and can point to locations in HMI tree with a path starting
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    58
with a ``/``, and with ``/``-separated hierarchical levels.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    59
For example, ``/THIS/IS/A/VALID/HMI_TREE/PATH``.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    60
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    61
``HMI:Switch@/GREENLIGHT``
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    62
    "Switch" type widget bound to a variable named GREENLIGHT at root of HMI tree
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    63
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    64
Each ``HMI:Page`` has a unique name. ``HMI:Jump`` and ``HMI:Back`` widgets are
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    65
used to switch to other pages. PLC can also trigger page change autonomously.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    66
HMI must have at least one SVG element labelled ``HMI:Page:Home``. ``Home`` is
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    67
a special page name: it will make this page the landing page when HMI is loaded.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    68
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    69
.. image:: svhgmi_pages.svg
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    70
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    71
``HMI:Page:Home``
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    72
    Mandatory "Home" page declaration
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    73
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    74
``HMI:Jump:Home``
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    75
    Change current page to "Home" page when clicked
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    76
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    77
``HMI:Back``
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    78
    Change current page back to previous page when clicked
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    79
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    80
Pages and groups of widgets can be dynamically re-based to another compatible
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    81
HMI Tree location. They can then be be re-used as HMI components, paired with
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    82
corresponding POU instances on PLC side.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    83
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    84
Simple yet powerful widgets
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    85
---------------------------
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    86
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    87
Widgets are meant to be as simple as possible. Still, they can become complex
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    88
when implementing interactions that cannot be broken down into multiple
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    89
independent widgets.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    90
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    91
+------------------------------------+---------------------------------+
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    92
| Meter Widget Template (`HMI:Meter`)|      Voltmeter (`HMI:Meter`)    | 
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    93
+====================================+=================================+
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    94
| .. image:: svghmi_meter.svg        | .. image:: svghmi_voltmeter.svg |
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    95
+------------------------------------+---------------------------------+
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    96
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    97
HMI and pages have their own local variables allowing interaction in between
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    98
widgets bypassing HMI Tree. For example, position of `HMI:Scrollbar` can be
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    99
directly connected to a position in `HMI:JSONTable` with a page local
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   100
variable.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   101
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   102
How does it work ?
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   103
------------------
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   104
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   105
HMI's client and server code is generated during SVGHMI build, based on PLC 
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   106
code and HMI design.
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   107
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   108
.. image:: svghmi_overview.svg
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   109
1d383b4c0a23 Doc: re-organize existing, sketch outline, add SVGHMI intro.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   110
SVGHMI build is part of Beremiz build, available in IDE and command line.