openc3-cosmos-tool-docs 6.0.1 → 6.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/tools/staticdocs/404.html +1 -1
  3. data/tools/staticdocs/assets/js/{019369f3.8413befc.js → 019369f3.1a6a0205.js} +1 -1
  4. data/tools/staticdocs/assets/js/{058ffc22.a4ceeb8e.js → 058ffc22.5cfabd67.js} +1 -1
  5. data/tools/staticdocs/assets/js/{0686a885.ae0a89e8.js → 0686a885.0e2ea47d.js} +1 -1
  6. data/tools/staticdocs/assets/js/{078dbab0.90ef4019.js → 078dbab0.5515d5e3.js} +1 -1
  7. data/tools/staticdocs/assets/js/{0f5d161c.1c827de2.js → 0f5d161c.7697df48.js} +1 -1
  8. data/tools/staticdocs/assets/js/{0ff569c9.3b7f9c95.js → 0ff569c9.f81b787b.js} +1 -1
  9. data/tools/staticdocs/assets/js/{103cc3be.76716a45.js → 103cc3be.e7943c80.js} +1 -1
  10. data/tools/staticdocs/assets/js/{13196248.18801ae0.js → 13196248.ea83002e.js} +1 -1
  11. data/tools/staticdocs/assets/js/{13c1b4e4.4457fa9a.js → 13c1b4e4.eb5250f4.js} +1 -1
  12. data/tools/staticdocs/assets/js/1e02e6a3.f477eca7.js +1 -0
  13. data/tools/staticdocs/assets/js/{2047b354.9470f5c9.js → 2047b354.d91f6c3e.js} +1 -1
  14. data/tools/staticdocs/assets/js/{22b3ac48.ac895789.js → 22b3ac48.0df9587b.js} +1 -1
  15. data/tools/staticdocs/assets/js/26b8abb2.a9f9025d.js +1 -0
  16. data/tools/staticdocs/assets/js/{2bb7bf90.471e10a1.js → 2bb7bf90.4051cf46.js} +1 -1
  17. data/tools/staticdocs/assets/js/31436304.a6b2eb4a.js +1 -0
  18. data/tools/staticdocs/assets/js/3969.afdd070b.js +1 -0
  19. data/tools/staticdocs/assets/js/{3dd7ef3b.d8bb37a8.js → 3dd7ef3b.c3455b97.js} +1 -1
  20. data/tools/staticdocs/assets/js/{40365d27.5f8a5da7.js → 40365d27.5ed2e9b5.js} +1 -1
  21. data/tools/staticdocs/assets/js/{411898ad.c8f67fde.js → 411898ad.f7fc4d80.js} +1 -1
  22. data/tools/staticdocs/assets/js/{42170351.86617d4a.js → 42170351.fbc05869.js} +1 -1
  23. data/tools/staticdocs/assets/js/{43652efd.0c473c25.js → 43652efd.60fa883f.js} +1 -1
  24. data/tools/staticdocs/assets/js/{2124.0e1f26f5.js → 5205.07e5caf3.js} +1 -1
  25. data/tools/staticdocs/assets/js/5328.3e2a53eb.js +1 -0
  26. data/tools/staticdocs/assets/js/53ca7c5b.fe331a71.js +1 -0
  27. data/tools/staticdocs/assets/js/{54d0d530.9ace531c.js → 54d0d530.ef91ba12.js} +1 -1
  28. data/tools/staticdocs/assets/js/5761.e7fabbc9.js +4 -0
  29. data/tools/staticdocs/assets/js/{5b233ba7.565c0c28.js → 5b233ba7.2ea0179c.js} +1 -1
  30. data/tools/staticdocs/assets/js/{5bc719f6.80b7b43c.js → 5bc719f6.b84c55e3.js} +1 -1
  31. data/tools/staticdocs/assets/js/{5c6ce5ec.ed839e0d.js → 5c6ce5ec.67d1d92e.js} +1 -1
  32. data/tools/staticdocs/assets/js/5e3ed378.cc5e2748.js +1 -0
  33. data/tools/staticdocs/assets/js/{5fe211ef.96109971.js → 5fe211ef.5a6390e4.js} +1 -1
  34. data/tools/staticdocs/assets/js/651.a043d7b1.js +1 -0
  35. data/tools/staticdocs/assets/js/6831b732.bb38c0d0.js +1 -0
  36. data/tools/staticdocs/assets/js/{696b4199.34aa1d77.js → 696b4199.2a7ff897.js} +1 -1
  37. data/tools/staticdocs/assets/js/6b210247.ef28d4e5.js +1 -0
  38. data/tools/staticdocs/assets/js/{6b65133b.f71c0e94.js → 6b65133b.0376a397.js} +1 -1
  39. data/tools/staticdocs/assets/js/{6f92e431.c98e31e0.js → 6f92e431.d2ce2753.js} +1 -1
  40. data/tools/staticdocs/assets/js/{72c6d8a8.1053fbd7.js → 72c6d8a8.10f0f9ec.js} +1 -1
  41. data/tools/staticdocs/assets/js/{75e64983.45bf7edc.js → 75e64983.81988bef.js} +1 -1
  42. data/tools/staticdocs/assets/js/{80c97f38.5a408d9c.js → 80c97f38.607160d3.js} +1 -1
  43. data/tools/staticdocs/assets/js/{867640d5.866fe67b.js → 867640d5.2c0fa6d9.js} +1 -1
  44. data/tools/staticdocs/assets/js/89e76475.a76d0072.js +1 -0
  45. data/tools/staticdocs/assets/js/{8f7843ee.59da8025.js → 8f7843ee.abe30983.js} +1 -1
  46. data/tools/staticdocs/assets/js/9357.9a7e89b5.js +101 -0
  47. data/tools/staticdocs/assets/js/{9424f0b3.cc8aa06e.js → 9424f0b3.bc60f3d9.js} +1 -1
  48. data/tools/staticdocs/assets/js/{97535711.94a5b402.js → 97535711.88c7444a.js} +1 -1
  49. data/tools/staticdocs/assets/js/99581c43.5e55992d.js +1 -0
  50. data/tools/staticdocs/assets/js/9d6e81d0.141ccd61.js +1 -0
  51. data/tools/staticdocs/assets/js/9fb6059a.821f7504.js +1 -0
  52. data/tools/staticdocs/assets/js/{a677c089.d8d7a8f5.js → a677c089.7caa32f6.js} +1 -1
  53. data/tools/staticdocs/assets/js/a9987364.81e9c91d.js +1 -0
  54. data/tools/staticdocs/assets/js/{aa6b6c1b.993f091d.js → aa6b6c1b.72eac29d.js} +1 -1
  55. data/tools/staticdocs/assets/js/{b4596165.a5fe2cea.js → b4596165.c648533a.js} +1 -1
  56. data/tools/staticdocs/assets/js/{b6d70f94.5df56282.js → b6d70f94.7813125e.js} +1 -1
  57. data/tools/staticdocs/assets/js/{b9f60ba6.cdb4a698.js → b9f60ba6.4c0bb1dd.js} +1 -1
  58. data/tools/staticdocs/assets/js/{bd0034eb.5fb449fc.js → bd0034eb.8ad39448.js} +1 -1
  59. data/tools/staticdocs/assets/js/{c24eae19.f419c8fb.js → c24eae19.89738127.js} +1 -1
  60. data/tools/staticdocs/assets/js/{c2598f55.85419dc8.js → c2598f55.812cdcd1.js} +1 -1
  61. data/tools/staticdocs/assets/js/{cb8c3f08.9264e5dd.js → cb8c3f08.07d1c9e9.js} +1 -1
  62. data/tools/staticdocs/assets/js/{cd879be4.aa3c877c.js → cd879be4.59af1749.js} +1 -1
  63. data/tools/staticdocs/assets/js/{d1b923aa.de9e8fd6.js → d1b923aa.a73e7e79.js} +1 -1
  64. data/tools/staticdocs/assets/js/d1bfc316.a58b9bbd.js +1 -0
  65. data/tools/staticdocs/assets/js/{d24bf9b6.1cb515f4.js → d24bf9b6.9fef8263.js} +1 -1
  66. data/tools/staticdocs/assets/js/{d57a4b5d.09769a64.js → d57a4b5d.c74b62b1.js} +1 -1
  67. data/tools/staticdocs/assets/js/{d5d77c37.1704d750.js → d5d77c37.e812e6e7.js} +1 -1
  68. data/tools/staticdocs/assets/js/{d66bf9c0.9a597f56.js → d66bf9c0.842d2efa.js} +1 -1
  69. data/tools/staticdocs/assets/js/d8ca4191.f5da7c6d.js +1 -0
  70. data/tools/staticdocs/assets/js/{d9b92eba.5a40eb6d.js → d9b92eba.34e63ba6.js} +1 -1
  71. data/tools/staticdocs/assets/js/{db8fa1d0.f9f65c91.js → db8fa1d0.94b76b52.js} +1 -1
  72. data/tools/staticdocs/assets/js/{dbe31111.dae4b9bd.js → dbe31111.75e9fc53.js} +1 -1
  73. data/tools/staticdocs/assets/js/dc5f7beb.9e4e6681.js +1 -0
  74. data/tools/staticdocs/assets/js/{e501b0d1.cb2ef34f.js → e501b0d1.d3a1e4bc.js} +1 -1
  75. data/tools/staticdocs/assets/js/{ebec1ccb.086b8668.js → ebec1ccb.120a5b80.js} +1 -1
  76. data/tools/staticdocs/assets/js/{f15615f1.afd4ba93.js → f15615f1.49804e96.js} +1 -1
  77. data/tools/staticdocs/assets/js/fd886806.124ffe26.js +1 -0
  78. data/tools/staticdocs/assets/js/main.ed84fc7e.js +36 -0
  79. data/tools/staticdocs/assets/js/runtime~main.91337aca.js +1 -0
  80. data/tools/staticdocs/docs/configuration/accessors.html +2 -2
  81. data/tools/staticdocs/docs/configuration/command.html +2 -2
  82. data/tools/staticdocs/docs/configuration/format.html +2 -2
  83. data/tools/staticdocs/docs/configuration/interfaces.html +2 -2
  84. data/tools/staticdocs/docs/configuration/plugins.html +4 -4
  85. data/tools/staticdocs/docs/configuration/protocols.html +2 -2
  86. data/tools/staticdocs/docs/configuration/ssl-tls.html +2 -2
  87. data/tools/staticdocs/docs/configuration/table.html +2 -2
  88. data/tools/staticdocs/docs/configuration/target.html +2 -2
  89. data/tools/staticdocs/docs/configuration/telemetry-screens.html +2 -2
  90. data/tools/staticdocs/docs/configuration/telemetry.html +2 -2
  91. data/tools/staticdocs/docs/configuration.html +1 -1
  92. data/tools/staticdocs/docs/development/curl.html +2 -2
  93. data/tools/staticdocs/docs/development/developing.html +3 -3
  94. data/tools/staticdocs/docs/development/json-api.html +2 -2
  95. data/tools/staticdocs/docs/development/log-structure.html +2 -2
  96. data/tools/staticdocs/docs/development/roadmap.html +2 -2
  97. data/tools/staticdocs/docs/development/streaming-api.html +2 -2
  98. data/tools/staticdocs/docs/development/testing.html +2 -2
  99. data/tools/staticdocs/docs/development.html +1 -1
  100. data/tools/staticdocs/docs/getting-started/generators.html +2 -2
  101. data/tools/staticdocs/docs/getting-started/gettingstarted.html +2 -2
  102. data/tools/staticdocs/docs/getting-started/installation.html +2 -2
  103. data/tools/staticdocs/docs/getting-started/key_concepts.html +2 -2
  104. data/tools/staticdocs/docs/getting-started/podman.html +2 -2
  105. data/tools/staticdocs/docs/getting-started/requirements.html +2 -2
  106. data/tools/staticdocs/docs/getting-started/upgrading.html +2 -2
  107. data/tools/staticdocs/docs/getting-started.html +1 -1
  108. data/tools/staticdocs/docs/guides/bridges.html +2 -2
  109. data/tools/staticdocs/docs/guides/cfs.html +2 -2
  110. data/tools/staticdocs/docs/guides/custom-widgets.html +2 -2
  111. data/tools/staticdocs/docs/guides/exposing_microservices.html +33 -0
  112. data/tools/staticdocs/docs/guides/little-endian-bitfields.html +2 -2
  113. data/tools/staticdocs/docs/guides/local-mode.html +2 -2
  114. data/tools/staticdocs/docs/guides/logging.html +2 -2
  115. data/tools/staticdocs/docs/guides/monitoring.html +2 -2
  116. data/tools/staticdocs/docs/guides/performance.html +2 -2
  117. data/tools/staticdocs/docs/guides/raspberrypi.html +2 -2
  118. data/tools/staticdocs/docs/guides/script-writing.html +2 -2
  119. data/tools/staticdocs/docs/guides/scripting-api.html +2 -2
  120. data/tools/staticdocs/docs/guides.html +1 -1
  121. data/tools/staticdocs/docs/meta/contributing.html +2 -2
  122. data/tools/staticdocs/docs/meta/licenses.html +2 -2
  123. data/tools/staticdocs/docs/meta/philosophy.html +2 -2
  124. data/tools/staticdocs/docs/meta/xtce.html +2 -2
  125. data/tools/staticdocs/docs/meta.html +1 -1
  126. data/tools/staticdocs/docs/privacy.html +2 -2
  127. data/tools/staticdocs/docs/tools/admin.html +2 -2
  128. data/tools/staticdocs/docs/tools/autonomic.html +2 -2
  129. data/tools/staticdocs/docs/tools/bucket-explorer.html +2 -2
  130. data/tools/staticdocs/docs/tools/calendar.html +2 -2
  131. data/tools/staticdocs/docs/tools/cmd-sender.html +2 -2
  132. data/tools/staticdocs/docs/tools/cmd-tlm-server.html +2 -2
  133. data/tools/staticdocs/docs/tools/command_history.html +2 -2
  134. data/tools/staticdocs/docs/tools/data-extractor.html +2 -2
  135. data/tools/staticdocs/docs/tools/data-viewer.html +2 -2
  136. data/tools/staticdocs/docs/tools/handbooks.html +2 -2
  137. data/tools/staticdocs/docs/tools/limits-monitor.html +2 -2
  138. data/tools/staticdocs/docs/tools/packet-viewer.html +2 -2
  139. data/tools/staticdocs/docs/tools/script-runner.html +2 -2
  140. data/tools/staticdocs/docs/tools/table-manager.html +2 -2
  141. data/tools/staticdocs/docs/tools/tlm-grapher.html +2 -2
  142. data/tools/staticdocs/docs/tools/tlm-viewer.html +2 -2
  143. data/tools/staticdocs/docs/tools.html +1 -1
  144. data/tools/staticdocs/docs.html +2 -2
  145. data/tools/staticdocs/index.html +1 -1
  146. data/tools/staticdocs/lunr-index-1736455916496.json +1 -0
  147. data/tools/staticdocs/lunr-index.json +1 -1
  148. data/tools/staticdocs/markdown-page.html +2 -2
  149. data/tools/staticdocs/search-doc-1736455916496.json +1 -0
  150. data/tools/staticdocs/search-doc.json +1 -1
  151. data/tools/staticdocs/sitemap.xml +1 -1
  152. metadata +82 -80
  153. data/tools/staticdocs/assets/js/1602.1e622848.js +0 -1
  154. data/tools/staticdocs/assets/js/1e02e6a3.8e63f255.js +0 -1
  155. data/tools/staticdocs/assets/js/26b8abb2.45d268b1.js +0 -1
  156. data/tools/staticdocs/assets/js/3040.18a0bb2a.js +0 -4
  157. data/tools/staticdocs/assets/js/3687.6fa52db1.js +0 -101
  158. data/tools/staticdocs/assets/js/4303.a84f454a.js +0 -1
  159. data/tools/staticdocs/assets/js/53ca7c5b.f0e35da3.js +0 -1
  160. data/tools/staticdocs/assets/js/5e3ed378.048e258b.js +0 -1
  161. data/tools/staticdocs/assets/js/6831b732.4008a669.js +0 -1
  162. data/tools/staticdocs/assets/js/6b210247.d37e3087.js +0 -1
  163. data/tools/staticdocs/assets/js/7690.fc05b8e6.js +0 -1
  164. data/tools/staticdocs/assets/js/89e76475.b4e9da15.js +0 -1
  165. data/tools/staticdocs/assets/js/99581c43.ebea1d08.js +0 -1
  166. data/tools/staticdocs/assets/js/9d6e81d0.4bc52207.js +0 -1
  167. data/tools/staticdocs/assets/js/9fb6059a.57936fbe.js +0 -1
  168. data/tools/staticdocs/assets/js/a9987364.2aa836fd.js +0 -1
  169. data/tools/staticdocs/assets/js/d1bfc316.82dd17ab.js +0 -1
  170. data/tools/staticdocs/assets/js/d8ca4191.1861d710.js +0 -1
  171. data/tools/staticdocs/assets/js/dc5f7beb.15fc7cc8.js +0 -1
  172. data/tools/staticdocs/assets/js/fd886806.fa25adc4.js +0 -1
  173. data/tools/staticdocs/assets/js/main.c4acbd62.js +0 -36
  174. data/tools/staticdocs/assets/js/runtime~main.cb6ff8de.js +0 -1
  175. data/tools/staticdocs/lunr-index-1734734383200.json +0 -1
  176. data/tools/staticdocs/search-doc-1734734383200.json +0 -1
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["5996"],{7015:function(e){e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"defaultSidebar":[{"type":"link","label":"Introduction","href":"/tools/staticdocs/docs/","docId":"introduction","unlisted":false},{"type":"category","label":"Getting Started","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation","href":"/tools/staticdocs/docs/getting-started/installation","customProps":{"myEmoji":"\uD83D\uDCBE"},"docId":"getting-started/installation","unlisted":false},{"type":"link","label":"Getting Started","href":"/tools/staticdocs/docs/getting-started/gettingstarted","customProps":{"myEmoji":"\uD83E\uDDD1\u200D\uD83D\uDCBB"},"docId":"getting-started/gettingstarted","unlisted":false},{"type":"link","label":"Code Generators","href":"/tools/staticdocs/docs/getting-started/generators","customProps":{"myEmoji":"\uD83C\uDFED"},"docId":"getting-started/generators","unlisted":false},{"type":"link","label":"Upgrading","href":"/tools/staticdocs/docs/getting-started/upgrading","customProps":{"myEmoji":"\u2B06\uFE0F"},"docId":"getting-started/upgrading","unlisted":false},{"type":"link","label":"Key Concepts","href":"/tools/staticdocs/docs/getting-started/key_concepts","customProps":{"myEmoji":"\uD83D\uDCA1"},"docId":"getting-started/key_concepts","unlisted":false},{"type":"link","label":"Requirements and Design","href":"/tools/staticdocs/docs/getting-started/requirements","customProps":{"myEmoji":"\uD83D\uDCD1"},"docId":"getting-started/requirements","unlisted":false},{"type":"link","label":"Podman","href":"/tools/staticdocs/docs/getting-started/podman","customProps":{"myEmoji":"\uD83E\uDEDB"},"docId":"getting-started/podman","unlisted":false}],"href":"/tools/staticdocs/docs/getting-started"},{"type":"category","label":"Configuration","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"File Format","href":"/tools/staticdocs/docs/configuration/format","docId":"configuration/format","unlisted":false},{"type":"link","label":"Plugins","href":"/tools/staticdocs/docs/configuration/plugins","customProps":{"myEmoji":"\uD83D\uDD0C"},"docId":"configuration/plugins","unlisted":false},{"type":"link","label":"Targets","href":"/tools/staticdocs/docs/configuration/target","customProps":{"myEmoji":"\uD83D\uDEF0\uFE0F"},"docId":"configuration/target","unlisted":false},{"type":"link","label":"Commands","href":"/tools/staticdocs/docs/configuration/command","customProps":{"myEmoji":"\uD83D\uDCE1"},"docId":"configuration/command","unlisted":false},{"type":"link","label":"Telemetry","href":"/tools/staticdocs/docs/configuration/telemetry","customProps":{"myEmoji":"\uD83D\uDCE1"},"docId":"configuration/telemetry","unlisted":false},{"type":"link","label":"Interfaces","href":"/tools/staticdocs/docs/configuration/interfaces","customProps":{"myEmoji":"\uD83D\uDCA1"},"docId":"configuration/interfaces","unlisted":false},{"type":"link","label":"Protocols","href":"/tools/staticdocs/docs/configuration/protocols","customProps":{"myEmoji":"\uD83D\uDCA1"},"docId":"configuration/protocols","unlisted":false},{"type":"link","label":"Accessors","href":"/tools/staticdocs/docs/configuration/accessors","customProps":{"myEmoji":"\u270F\uFE0F"},"docId":"configuration/accessors","unlisted":false},{"type":"link","label":"Tables","href":"/tools/staticdocs/docs/configuration/table","docId":"configuration/table","unlisted":false},{"type":"link","label":"Screens","href":"/tools/staticdocs/docs/configuration/telemetry-screens","customProps":{"myEmoji":"\uD83D\uDDA5\uFE0F"},"docId":"configuration/telemetry-screens","unlisted":false},{"type":"link","label":"SSL-TLS","href":"/tools/staticdocs/docs/configuration/ssl-tls","customProps":{"myEmoji":"\uD83D\uDD10"},"docId":"configuration/ssl-tls","unlisted":false}],"href":"/tools/staticdocs/docs/configuration"},{"type":"category","label":"Tools","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Admin","href":"/tools/staticdocs/docs/tools/admin","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/admin","unlisted":false},{"type":"link","label":"Autonomic (Enterprise)","href":"/tools/staticdocs/docs/tools/autonomic","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/autonomic","unlisted":false},{"type":"link","label":"Bucket Explorer","href":"/tools/staticdocs/docs/tools/bucket-explorer","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/bucket-explorer","unlisted":false},{"type":"link","label":"Calendar (Enterprise)","href":"/tools/staticdocs/docs/tools/calendar","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/calendar","unlisted":false},{"type":"link","label":"Command Sender","href":"/tools/staticdocs/docs/tools/cmd-sender","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/cmd-sender","unlisted":false},{"type":"link","label":"Command and Telemetry Server","href":"/tools/staticdocs/docs/tools/cmd-tlm-server","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/cmd-tlm-server","unlisted":false},{"type":"link","label":"Command History (Enterprise)","href":"/tools/staticdocs/docs/tools/command_history","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/command_history","unlisted":false},{"type":"link","label":"Data Extractor","href":"/tools/staticdocs/docs/tools/data-extractor","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/data-extractor","unlisted":false},{"type":"link","label":"Data Viewer","href":"/tools/staticdocs/docs/tools/data-viewer","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/data-viewer","unlisted":false},{"type":"link","label":"Handbooks","href":"/tools/staticdocs/docs/tools/handbooks","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/handbooks","unlisted":false},{"type":"link","label":"Limits Monitor","href":"/tools/staticdocs/docs/tools/limits-monitor","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/limits-monitor","unlisted":false},{"type":"link","label":"Packet Viewer","href":"/tools/staticdocs/docs/tools/packet-viewer","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/packet-viewer","unlisted":false},{"type":"link","label":"Script Runner","href":"/tools/staticdocs/docs/tools/script-runner","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/script-runner","unlisted":false},{"type":"link","label":"Table Manager","href":"/tools/staticdocs/docs/tools/table-manager","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/table-manager","unlisted":false},{"type":"link","label":"Telemetry Grapher","href":"/tools/staticdocs/docs/tools/tlm-grapher","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/tlm-grapher","unlisted":false},{"type":"link","label":"Telemetry Viewer","href":"/tools/staticdocs/docs/tools/tlm-viewer","customProps":{"myEmoji":"\uD83D\uDEE0\uFE0F"},"docId":"tools/tlm-viewer","unlisted":false}],"href":"/tools/staticdocs/docs/tools"},{"type":"category","label":"Guides","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Bridges","href":"/tools/staticdocs/docs/guides/bridges","customProps":{"myEmoji":"\uD83C\uDF09"},"docId":"guides/bridges","unlisted":false},{"type":"link","label":"COSMOS and NASA cFS","href":"/tools/staticdocs/docs/guides/cfs","customProps":{"myEmoji":"\uD83D\uDE80"},"docId":"guides/cfs","unlisted":false},{"type":"link","label":"Custom Widgets","href":"/tools/staticdocs/docs/guides/custom-widgets","customProps":{"myEmoji":"\uD83D\uDD28"},"docId":"guides/custom-widgets","unlisted":false},{"type":"link","label":"Exposing Microservices","href":"/tools/staticdocs/docs/guides/exposing_microservices","customProps":{"myEmoji":"\uD83D\uDEAA"},"docId":"guides/exposing_microservices","unlisted":false},{"type":"link","label":"Little Endian Bitfields","href":"/tools/staticdocs/docs/guides/little-endian-bitfields","customProps":{"myEmoji":"\uD83D\uDCBB"},"docId":"guides/little-endian-bitfields","unlisted":false},{"type":"link","label":"Local Mode","href":"/tools/staticdocs/docs/guides/local-mode","customProps":{"myEmoji":"\uD83E\uDDED"},"docId":"guides/local-mode","unlisted":false},{"type":"link","label":"Logging","href":"/tools/staticdocs/docs/guides/logging","customProps":{"myEmoji":"\uD83E\uDEB5"},"docId":"guides/logging","unlisted":false},{"type":"link","label":"Monitoring","href":"/tools/staticdocs/docs/guides/monitoring","customProps":{"myEmoji":"\uD83D\uDDA5\uFE0F"},"docId":"guides/monitoring","unlisted":false},{"type":"link","label":"Performance","href":"/tools/staticdocs/docs/guides/performance","customProps":{"myEmoji":"\uD83D\uDCCA"},"docId":"guides/performance","unlisted":false},{"type":"link","label":"Raspberry Pi","href":"/tools/staticdocs/docs/guides/raspberrypi","customProps":{"myEmoji":"\uD83C\uDF53"},"docId":"guides/raspberrypi","unlisted":false},{"type":"link","label":"Script Writing Guide","href":"/tools/staticdocs/docs/guides/script-writing","customProps":{"myEmoji":"\uD83C\uDFC3\u200D\u27A1\uFE0F"},"docId":"guides/script-writing","unlisted":false},{"type":"link","label":"Scripting API Guide","href":"/tools/staticdocs/docs/guides/scripting-api","customProps":{"myEmoji":"\uD83D\uDCDD"},"docId":"guides/scripting-api","unlisted":false}],"href":"/tools/staticdocs/docs/guides"},{"type":"category","label":"Development","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Testing with Curl","href":"/tools/staticdocs/docs/development/curl","customProps":{"myEmoji":"\uD83C\uDF0A"},"docId":"development/curl","unlisted":false},{"type":"link","label":"Developing COSMOS","href":"/tools/staticdocs/docs/development/developing","customProps":{"myEmoji":"\uD83D\uDCBB"},"docId":"development/developing","unlisted":false},{"type":"link","label":"JSON API","href":"/tools/staticdocs/docs/development/json-api","customProps":{"myEmoji":"\uD83D\uDDA5\uFE0F"},"docId":"development/json-api","unlisted":false},{"type":"link","label":"Log Structure","href":"/tools/staticdocs/docs/development/log-structure","customProps":{"myEmoji":"\uD83E\uDEB5"},"docId":"development/log-structure","unlisted":false},{"type":"link","label":"Roadmap","href":"/tools/staticdocs/docs/development/roadmap","customProps":{"myEmoji":"\uD83D\uDDFA\uFE0F"},"docId":"development/roadmap","unlisted":false},{"type":"link","label":"Streaming API","href":"/tools/staticdocs/docs/development/streaming-api","customProps":{"myEmoji":"\uD83D\uDCDD"},"docId":"development/streaming-api","unlisted":false},{"type":"link","label":"Testing COSMOS","href":"/tools/staticdocs/docs/development/testing","customProps":{"myEmoji":"\uD83D\uDCCB"},"docId":"development/testing","unlisted":false}],"href":"/tools/staticdocs/docs/development"},{"type":"category","label":"Meta","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Contributing","href":"/tools/staticdocs/docs/meta/contributing","customProps":{"myEmoji":"\uD83D\uDE42"},"docId":"meta/contributing","unlisted":false},{"type":"link","label":"Licenses","href":"/tools/staticdocs/docs/meta/licenses","customProps":{"myEmoji":"\uD83D\uDD75\uFE0F"},"docId":"meta/licenses","unlisted":false},{"type":"link","label":"Philosophy","href":"/tools/staticdocs/docs/meta/philosophy","customProps":{"myEmoji":"\uD83E\uDD14"},"docId":"meta/philosophy","unlisted":false},{"type":"link","label":"XTCE Support","href":"/tools/staticdocs/docs/meta/xtce","customProps":{"myEmoji":"\uD83D\uDE35"},"docId":"meta/xtce","unlisted":false}],"href":"/tools/staticdocs/docs/meta"},{"type":"link","label":"OpenC3, Inc. Privacy Policy","href":"/tools/staticdocs/docs/privacy","docId":"privacy","unlisted":false}]},"docs":{"configuration/accessors":{"id":"configuration/accessors","title":"Accessors","description":"Responsible for reading and writing data to a buffer","sidebar":"defaultSidebar"},"configuration/command":{"id":"configuration/command","title":"Commands","description":"Command definition file format and keywords","sidebar":"defaultSidebar"},"configuration/format":{"id":"configuration/format","title":"File Format","description":"Structure of a COSMOS file, including using ERB","sidebar":"defaultSidebar"},"configuration/interfaces":{"id":"configuration/interfaces","title":"Interfaces","description":"Built-in COSMOS interfaces including how to create one","sidebar":"defaultSidebar"},"configuration/plugins":{"id":"configuration/plugins","title":"Plugins","description":"Plugin definition file format and keywords","sidebar":"defaultSidebar"},"configuration/protocols":{"id":"configuration/protocols","title":"Protocols","description":"Built-in COSMOS protocols including how to create one","sidebar":"defaultSidebar"},"configuration/ssl-tls":{"id":"configuration/ssl-tls","title":"SSL-TLS","description":"How to configure SSL and TLS","sidebar":"defaultSidebar"},"configuration/table":{"id":"configuration/table","title":"Tables","description":"Table definition file format and keywords","sidebar":"defaultSidebar"},"configuration/target":{"id":"configuration/target","title":"Targets","description":"Target definition file format and keywords","sidebar":"defaultSidebar"},"configuration/telemetry":{"id":"configuration/telemetry","title":"Telemetry","description":"Telemetry definition file format and keywords","sidebar":"defaultSidebar"},"configuration/telemetry-screens":{"id":"configuration/telemetry-screens","title":"Screens","description":"Telemetry Viewer screen definition and widget documentation","sidebar":"defaultSidebar"},"development/curl":{"id":"development/curl","title":"Testing with Curl","description":"How to use Curl to hit the COSMOS APIs","sidebar":"defaultSidebar"},"development/developing":{"id":"development/developing","title":"Developing COSMOS","description":"Building COSMOS and developing the frontend and backend","sidebar":"defaultSidebar"},"development/json-api":{"id":"development/json-api","title":"JSON API","description":"Interfacing to the COSMOS APIs using JSON-RPC","sidebar":"defaultSidebar"},"development/log-structure":{"id":"development/log-structure","title":"Log Structure","description":"Structure of the COSMOS log file","sidebar":"defaultSidebar"},"development/roadmap":{"id":"development/roadmap","title":"Roadmap","description":"COSMOS roadmap now and into the future","sidebar":"defaultSidebar"},"development/streaming-api":{"id":"development/streaming-api","title":"Streaming API","description":"Using the websocket streaming API to retrieve data","sidebar":"defaultSidebar"},"development/testing":{"id":"development/testing","title":"Testing COSMOS","description":"Running the Playwright integration tests and unit tests","sidebar":"defaultSidebar"},"getting-started/generators":{"id":"getting-started/generators","title":"Code Generators","description":"Using openc3.sh to generate code","sidebar":"defaultSidebar"},"getting-started/gettingstarted":{"id":"getting-started/gettingstarted","title":"Getting Started","description":"Getting starting with COSMOS","sidebar":"defaultSidebar"},"getting-started/installation":{"id":"getting-started/installation","title":"Installation","description":"Installing OpenC3 COSMOS","sidebar":"defaultSidebar"},"getting-started/key_concepts":{"id":"getting-started/key_concepts","title":"Key Concepts","description":"Projects, Containerization, Frontend, Backend","sidebar":"defaultSidebar"},"getting-started/podman":{"id":"getting-started/podman","title":"Podman","description":"Installing and running COSMOS with Podman","sidebar":"defaultSidebar"},"getting-started/requirements":{"id":"getting-started/requirements","title":"Requirements and Design","description":"COSMOS Requirements and Design","sidebar":"defaultSidebar"},"getting-started/upgrading":{"id":"getting-started/upgrading","title":"Upgrading","description":"How to upgrade and migrate COSMOS","sidebar":"defaultSidebar"},"guides/bridges":{"id":"guides/bridges","title":"Bridges","description":"Bridge data into COSMOS from serial ports, PCI, etc","sidebar":"defaultSidebar"},"guides/cfs":{"id":"guides/cfs","title":"COSMOS and NASA cFS","description":"Tutorial for integrating with NASA cFS","sidebar":"defaultSidebar"},"guides/custom-widgets":{"id":"guides/custom-widgets","title":"Custom Widgets","description":"How to build custom widgets for use in Telemetry Viewer","sidebar":"defaultSidebar"},"guides/exposing_microservices":{"id":"guides/exposing_microservices","title":"Exposing Microservices","description":"Provide external accessibility to microservices","sidebar":"defaultSidebar"},"guides/little-endian-bitfields":{"id":"guides/little-endian-bitfields","title":"Little Endian Bitfields","description":"Defining little endian bitfields","sidebar":"defaultSidebar"},"guides/local-mode":{"id":"guides/local-mode","title":"Local Mode","description":"Edit scripts and screens directly on the host file system","sidebar":"defaultSidebar"},"guides/logging":{"id":"guides/logging","title":"Logging","description":"The log files in COSMOS","sidebar":"defaultSidebar"},"guides/monitoring":{"id":"guides/monitoring","title":"Monitoring","description":"Various ways to monitor COSMOS internals","sidebar":"defaultSidebar"},"guides/performance":{"id":"guides/performance","title":"Performance","description":"Hardware requirements like memory and CPU","sidebar":"defaultSidebar"},"guides/raspberrypi":{"id":"guides/raspberrypi","title":"Raspberry Pi","description":"Running COSMOS on a Raspberry Pi","sidebar":"defaultSidebar"},"guides/script-writing":{"id":"guides/script-writing","title":"Script Writing Guide","description":"Key concepts and best practices for script writing","sidebar":"defaultSidebar"},"guides/scripting-api":{"id":"guides/scripting-api","title":"Scripting API Guide","description":"Scripting API methods, deprecations and migrations","sidebar":"defaultSidebar"},"introduction":{"id":"introduction","title":"Introduction","description":"This site aims to be a comprehensive guide to OpenC3 COSMOS. We\'ll cover topics such","sidebar":"defaultSidebar"},"meta/contributing":{"id":"meta/contributing","title":"Contributing","description":"Contributing to COSMOS using the github workflow","sidebar":"defaultSidebar"},"meta/licenses":{"id":"meta/licenses","title":"Licenses","description":"COSMOS licenses including the AGPLv3 vs Commercial","sidebar":"defaultSidebar"},"meta/philosophy":{"id":"meta/philosophy","title":"Philosophy","description":"COSMOS goals and philosophy","sidebar":"defaultSidebar"},"meta/xtce":{"id":"meta/xtce","title":"XTCE Support","description":"XTCE Command and Telemetry Definition Standard","sidebar":"defaultSidebar"},"privacy":{"id":"privacy","title":"OpenC3, Inc. Privacy Policy","description":"OpenC3 Inc. is strongly committed to protecting your privacy and complying with your choices. Both personal and non-personal information collected is safeguarded according to the highest privacy and data protection standards adopted worldwide. We have always had a robust and effective data protection program in place which complies with existing law and abides by the data protection principles. However, we recognise our obligations in updating and expanding this program to meet the demands of the GDPR.","sidebar":"defaultSidebar"},"tools/admin":{"id":"tools/admin","title":"Admin","description":"Administer COSMOS, install plugins, change settings","sidebar":"defaultSidebar"},"tools/autonomic":{"id":"tools/autonomic","title":"Autonomic (Enterprise)","description":"Automated execution of commands and scripts","sidebar":"defaultSidebar"},"tools/bucket-explorer":{"id":"tools/bucket-explorer","title":"Bucket Explorer","description":"File browser to the COSMOS backend bucket storage system","sidebar":"defaultSidebar"},"tools/calendar":{"id":"tools/calendar","title":"Calendar (Enterprise)","description":"Calendar visualization of metadata, notes, and timelines","sidebar":"defaultSidebar"},"tools/cmd-sender":{"id":"tools/cmd-sender","title":"Command Sender","description":"Send individual commands","sidebar":"defaultSidebar"},"tools/cmd-tlm-server":{"id":"tools/cmd-tlm-server","title":"Command and Telemetry Server","description":"Status about interfaces, targets and log messages","sidebar":"defaultSidebar"},"tools/command_history":{"id":"tools/command_history","title":"Command History (Enterprise)","description":"See all the commands sent, by whom, and if successful","sidebar":"defaultSidebar"},"tools/data-extractor":{"id":"tools/data-extractor","title":"Data Extractor","description":"Extract command or telemetry data into files","sidebar":"defaultSidebar"},"tools/data-viewer":{"id":"tools/data-viewer","title":"Data Viewer","description":"View packet or item data","sidebar":"defaultSidebar"},"tools/handbooks":{"id":"tools/handbooks","title":"Handbooks","description":"Format the command and telemetry definition into a webpage","sidebar":"defaultSidebar"},"tools/limits-monitor":{"id":"tools/limits-monitor","title":"Limits Monitor","description":"View out of limit items and log messages","sidebar":"defaultSidebar"},"tools/packet-viewer":{"id":"tools/packet-viewer","title":"Packet Viewer","description":"Displays all packets with their items","sidebar":"defaultSidebar"},"tools/script-runner":{"id":"tools/script-runner","title":"Script Runner","description":"Run Python or Ruby scripts to send commands and check telemetry","sidebar":"defaultSidebar"},"tools/table-manager":{"id":"tools/table-manager","title":"Table Manager","description":"Binary file editor with upload / download","sidebar":"defaultSidebar"},"tools/tlm-grapher":{"id":"tools/tlm-grapher","title":"Telemetry Grapher","description":"Graph real time or historical data","sidebar":"defaultSidebar"},"tools/tlm-viewer":{"id":"tools/tlm-viewer","title":"Telemetry Viewer","description":"Build custom screens using built-in widgets","sidebar":"defaultSidebar"}}}}')}}]);
@@ -1 +1 @@
1
- "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["442"],{7594:function(e,t,i){i.r(t),i.d(t,{default:()=>u,frontMatter:()=>r,metadata:()=>n,assets:()=>a,toc:()=>o,contentTitle:()=>c});var n=JSON.parse('{"id":"tools/packet-viewer","title":"Packet Viewer","description":"Displays all packets with their items","source":"@site/docs/tools/packet-viewer.md","sourceDirName":"tools","slug":"/tools/packet-viewer","permalink":"/tools/staticdocs/docs/tools/packet-viewer","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/tools/packet-viewer.md","tags":[],"version":"current","frontMatter":{"title":"Packet Viewer","description":"Displays all packets with their items","sidebar_custom_props":{"myEmoji":"\uD83D\uDEE0\uFE0F"}},"sidebar":"defaultSidebar","previous":{"title":"Limits Monitor","permalink":"/tools/staticdocs/docs/tools/limits-monitor"},"next":{"title":"Script Runner","permalink":"/tools/staticdocs/docs/tools/script-runner"}}'),s=i("2322"),l=i("2840");let r={title:"Packet Viewer",description:"Displays all packets with their items",sidebar_custom_props:{myEmoji:"\uD83D\uDEE0\uFE0F"}},c=void 0,a={},o=[{value:"Introduction",id:"introduction",level:2},{value:"Packet Viewer Menus",id:"packet-viewer-menus",level:2},{value:"File Menu Items",id:"file-menu-items",level:3},{value:"View Menu Items",id:"view-menu-items",level:3},{value:"Selecting Packets",id:"selecting-packets",level:2},{value:"Details",id:"details",level:3}];function d(e){let t={a:"a",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,l.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(t.p,{children:"Packet Viewer is a live telemetry viewer which requires no configuration to display the current values for all defined target, packet, items. Items with limits are displayed colored (blue, green, yellow, or red) according to their current state. Items can be right clicked to get detailed information."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Packet Viewer",src:i(6077).Z+"",width:"1274",height:"837"})}),"\n",(0,s.jsx)(t.h2,{id:"packet-viewer-menus",children:"Packet Viewer Menus"}),"\n",(0,s.jsx)(t.h3,{id:"file-menu-items",children:"File Menu Items"}),"\n",(0,s.jsx)("img",{src:i(7212).Z,alt:"File Menu",style:{float:"left","margin-right":"50px",height:"120px"}}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Change the refresh and stale interval"}),"\n",(0,s.jsx)(t.li,{children:"Opens a saved configuration"}),"\n",(0,s.jsx)(t.li,{children:"Save the current configuration (view settings)"}),"\n",(0,s.jsx)(t.li,{children:"Reset the configuration (default settings)"}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"view-menu-items",children:"View Menu Items"}),"\n",(0,s.jsx)("img",{src:i(9754).Z,alt:"View Menu",style:{float:"left","margin-right":"50px",height:"180px"}}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Shows ",(0,s.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/target#ignore_item",children:"ignored items"})]}),"\n",(0,s.jsxs)(t.li,{children:["Display ",(0,s.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry#derived-items",children:"derived"})," items last"]}),"\n",(0,s.jsxs)(t.li,{children:["Display formatted items with ",(0,s.jsx)(t.a,{href:"../configuration/telemetry#units",children:"units"})]}),"\n",(0,s.jsxs)(t.li,{children:["Display ",(0,s.jsx)(t.a,{href:"../configuration/telemetry#format_string",children:"formatted"})," items"]}),"\n",(0,s.jsxs)(t.li,{children:["Display ",(0,s.jsx)(t.a,{href:"../configuration/telemetry#read_conversion",children:"converted"})," items"]}),"\n",(0,s.jsx)(t.li,{children:"Display raw items"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"selecting-packets",children:"Selecting Packets"}),"\n",(0,s.jsx)(t.p,{children:"Initially opening Packet Viewer will open the first alphabetical Target and Packet. Click the drop down menus to update the Items table to a new packet. To filter the list of items you can type in the search box."}),"\n",(0,s.jsx)(t.h3,{id:"details",children:"Details"}),"\n",(0,s.jsx)(t.p,{children:"Right-clicking an item and selecting Details will open the details dialog."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Details",src:i(6812).Z+"",width:"591",height:"697"})}),"\n",(0,s.jsx)(t.p,{children:"This dialog lists everything defined on the telemetry item."})]})}function u(e={}){let{wrapper:t}={...(0,l.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},7212:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/file_menu-d9ac5efbe78e58f024666452b9f28af72c6d09a3460fc7c0737c2bb74e4ea409.png"},9754:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/view_menu-a02cfbd5e6fafa5d3b4f1ae76bfbd63f49388939b4732bf91709f48e44498d19.png"},6077:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/packet_viewer-505c517c9a838a41d6fe668ff7ca2efb1b89ced4b75df638cd11a45484bc6533.png"},6812:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/temp1_details-4c4bbe7c2d60e636f0304ee8ac7237af8db2bdba8666c9ae2dc0a105eca248f2.png"},2840:function(e,t,i){i.d(t,{Z:function(){return c},a:function(){return r}});var n=i(2784);let s={},l=n.createContext(s);function r(e){let t=n.useContext(l);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(l.Provider,{value:t},e.children)}}}]);
1
+ "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["442"],{2317:function(e,t,i){i.r(t),i.d(t,{default:()=>u,frontMatter:()=>r,metadata:()=>n,assets:()=>a,toc:()=>o,contentTitle:()=>c});var n=JSON.parse('{"id":"tools/packet-viewer","title":"Packet Viewer","description":"Displays all packets with their items","source":"@site/docs/tools/packet-viewer.md","sourceDirName":"tools","slug":"/tools/packet-viewer","permalink":"/tools/staticdocs/docs/tools/packet-viewer","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/tools/packet-viewer.md","tags":[],"version":"current","frontMatter":{"title":"Packet Viewer","description":"Displays all packets with their items","sidebar_custom_props":{"myEmoji":"\uD83D\uDEE0\uFE0F"}},"sidebar":"defaultSidebar","previous":{"title":"Limits Monitor","permalink":"/tools/staticdocs/docs/tools/limits-monitor"},"next":{"title":"Script Runner","permalink":"/tools/staticdocs/docs/tools/script-runner"}}'),s=i("2322"),l=i("2840");let r={title:"Packet Viewer",description:"Displays all packets with their items",sidebar_custom_props:{myEmoji:"\uD83D\uDEE0\uFE0F"}},c=void 0,a={},o=[{value:"Introduction",id:"introduction",level:2},{value:"Packet Viewer Menus",id:"packet-viewer-menus",level:2},{value:"File Menu Items",id:"file-menu-items",level:3},{value:"View Menu Items",id:"view-menu-items",level:3},{value:"Selecting Packets",id:"selecting-packets",level:2},{value:"Details",id:"details",level:3}];function d(e){let t={a:"a",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",ul:"ul",...(0,l.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(t.p,{children:"Packet Viewer is a live telemetry viewer which requires no configuration to display the current values for all defined target, packet, items. Items with limits are displayed colored (blue, green, yellow, or red) according to their current state. Items can be right clicked to get detailed information."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Packet Viewer",src:i(6077).Z+"",width:"1274",height:"837"})}),"\n",(0,s.jsx)(t.h2,{id:"packet-viewer-menus",children:"Packet Viewer Menus"}),"\n",(0,s.jsx)(t.h3,{id:"file-menu-items",children:"File Menu Items"}),"\n",(0,s.jsx)("img",{src:i(7212).Z,alt:"File Menu",style:{float:"left","margin-right":"50px",height:"120px"}}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Change the refresh and stale interval"}),"\n",(0,s.jsx)(t.li,{children:"Opens a saved configuration"}),"\n",(0,s.jsx)(t.li,{children:"Save the current configuration (view settings)"}),"\n",(0,s.jsx)(t.li,{children:"Reset the configuration (default settings)"}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"view-menu-items",children:"View Menu Items"}),"\n",(0,s.jsx)("img",{src:i(9754).Z,alt:"View Menu",style:{float:"left","margin-right":"50px",height:"180px"}}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Shows ",(0,s.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/target#ignore_item",children:"ignored items"})]}),"\n",(0,s.jsxs)(t.li,{children:["Display ",(0,s.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry#derived-items",children:"derived"})," items last"]}),"\n",(0,s.jsxs)(t.li,{children:["Display formatted items with ",(0,s.jsx)(t.a,{href:"../configuration/telemetry#units",children:"units"})]}),"\n",(0,s.jsxs)(t.li,{children:["Display ",(0,s.jsx)(t.a,{href:"../configuration/telemetry#format_string",children:"formatted"})," items"]}),"\n",(0,s.jsxs)(t.li,{children:["Display ",(0,s.jsx)(t.a,{href:"../configuration/telemetry#read_conversion",children:"converted"})," items"]}),"\n",(0,s.jsx)(t.li,{children:"Display raw items"}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"selecting-packets",children:"Selecting Packets"}),"\n",(0,s.jsx)(t.p,{children:"Initially opening Packet Viewer will open the first alphabetical Target and Packet. Click the drop down menus to update the Items table to a new packet. To filter the list of items you can type in the search box."}),"\n",(0,s.jsx)(t.h3,{id:"details",children:"Details"}),"\n",(0,s.jsx)(t.p,{children:"Right-clicking an item and selecting Details will open the details dialog."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Details",src:i(6812).Z+"",width:"591",height:"697"})}),"\n",(0,s.jsx)(t.p,{children:"This dialog lists everything defined on the telemetry item."})]})}function u(e={}){let{wrapper:t}={...(0,l.a)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},7212:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/file_menu-d9ac5efbe78e58f024666452b9f28af72c6d09a3460fc7c0737c2bb74e4ea409.png"},9754:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/view_menu-a02cfbd5e6fafa5d3b4f1ae76bfbd63f49388939b4732bf91709f48e44498d19.png"},6077:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/packet_viewer-505c517c9a838a41d6fe668ff7ca2efb1b89ced4b75df638cd11a45484bc6533.png"},6812:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/temp1_details-4c4bbe7c2d60e636f0304ee8ac7237af8db2bdba8666c9ae2dc0a105eca248f2.png"},2840:function(e,t,i){i.d(t,{Z:function(){return c},a:function(){return r}});var n=i(2784);let s={},l=n.createContext(s);function r(e){let t=n.useContext(l);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(l.Provider,{value:t},e.children)}}}]);
@@ -1 +1 @@
1
- "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["9146"],{7073:function(e,n,r){r.r(n),r.d(n,{default:()=>p,frontMatter:()=>t,metadata:()=>s,assets:()=>c,toc:()=>a,contentTitle:()=>l});var s=JSON.parse('{"id":"guides/raspberrypi","title":"Raspberry Pi","description":"Running COSMOS on a Raspberry Pi","source":"@site/docs/guides/raspberrypi.md","sourceDirName":"guides","slug":"/guides/raspberrypi","permalink":"/tools/staticdocs/docs/guides/raspberrypi","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/guides/raspberrypi.md","tags":[],"version":"current","frontMatter":{"title":"Raspberry Pi","description":"Running COSMOS on a Raspberry Pi","sidebar_custom_props":{"myEmoji":"\uD83C\uDF53"}},"sidebar":"defaultSidebar","previous":{"title":"Performance","permalink":"/tools/staticdocs/docs/guides/performance"},"next":{"title":"Script Writing Guide","permalink":"/tools/staticdocs/docs/guides/script-writing"}}'),i=r("2322"),o=r("2840");let t={title:"Raspberry Pi",description:"Running COSMOS on a Raspberry Pi",sidebar_custom_props:{myEmoji:"\uD83C\uDF53"}},l=void 0,c={},a=[{value:"COSMOS Running on Raspberry Pi 4",id:"cosmos-running-on-raspberry-pi-4",level:3}];function d(e){let n={a:"a",code:"code",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h3,{id:"cosmos-running-on-raspberry-pi-4",children:"COSMOS Running on Raspberry Pi 4"}),"\n",(0,i.jsx)(n.p,{children:"The Raspberry Pi 4 is a low-cost powerful ARM-based minicomputer that runs linux. And because it runs modern linux, it can also run COSMOS! These directions will get you up and running."}),"\n",(0,i.jsx)(n.p,{children:"What you'll need:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Raspberry Pi 4 board (tested with 8GB RAM)"}),"\n",(0,i.jsx)(n.li,{children:"A Pi Case but Optional"}),"\n",(0,i.jsx)(n.li,{children:"Raspbeerry Pi Power Supply"}),"\n",(0,i.jsx)(n.li,{children:"32GB or Larger SD Card - Also faster the better"}),"\n",(0,i.jsx)(n.li,{children:"A Laptop with a way to write SD Cards"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Let's get started!"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Setup 64-bit Raspian OS Lite on the SD Card"}),"\n",(0,i.jsxs)(n.p,{children:["Make sure you have the Raspberry Pi Imager app from: ",(0,i.jsx)(n.a,{href:"https://www.raspberrypi.com/software/",children:"https://www.raspberrypi.com/software/"})]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Insert the SD Card into your computer (Note this process will erase all data on the SD card!)"}),"\n",(0,i.jsx)(n.li,{children:"Open the Raspberry Pi Imager App"}),"\n",(0,i.jsx)(n.li,{children:'Click the "Choose Device" Button'}),"\n",(0,i.jsx)(n.li,{children:"Pick Your Raspberry Pi Model"}),"\n",(0,i.jsx)(n.li,{children:'Click the "Choose OS" Button'}),"\n",(0,i.jsx)(n.li,{children:'Select "Raspberry Pi OS (other)"'}),"\n",(0,i.jsx)(n.li,{children:'Select "Raspberry Pi OS Lite (64-bit)"'}),"\n",(0,i.jsx)(n.li,{children:'Click the "Choose Storage" Button'}),"\n",(0,i.jsx)(n.li,{children:"Select Your SD Card"}),"\n",(0,i.jsx)(n.li,{children:"Click Edit Settings"}),"\n",(0,i.jsx)(n.li,{children:"If prompted if you would like to prefill the Wifi information, select OK"}),"\n",(0,i.jsx)(n.li,{children:"Set the hostname to: cosmos.local"}),"\n",(0,i.jsx)(n.li,{children:"Set the username and password. The default username is your username, you should also set a password to make the system secure"}),"\n",(0,i.jsx)(n.li,{children:"Fill in your Wifi info, and set the country appropriately (ie. US)"}),"\n",(0,i.jsx)(n.li,{children:"Set the correct time zone"}),"\n",(0,i.jsx)(n.li,{children:"Goto the Services Tab and Enable SSH"}),"\n",(0,i.jsx)(n.li,{children:"You can either use Password auth, or public-key only if your computer is already setup for passwordless SSH"}),"\n",(0,i.jsx)(n.li,{children:'Goto the Options tab and make sure "Enable Telemetry" is not checked'}),"\n",(0,i.jsx)(n.li,{children:'Click "Save" when everything is filled out'}),"\n",(0,i.jsx)(n.li,{children:'Click "Yes" to apply OS Customization Settings, Yes to Are You Sure, and Wait for it to complete'}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Make sure the Raspberry Pi is NOT powered on"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Remove the SD Card from your computer and insert into the Raspberry Pi"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Apply power to the Raspberry Pi and wait approximately 1 minute for it to boot"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"SSH to your raspberry Pi"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Open a terminal window and use ssh to connect to your Pi"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["On Mac / Linux: ssh ",(0,i.jsx)(n.a,{href:"mailto:yourusername@cosmos.local",children:"yourusername@cosmos.local"})]}),"\n",(0,i.jsx)(n.li,{children:"On Windows, use Putty to connect. You will probably have to install Bonjour for Windows for .local addresses to work as well."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"From SSH, Enter the following commands"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:" sudo sysctl -w vm.max_map_count=262144\n sudo sysctl -w vm.overcommit_memory=1\n sudo apt update\n sudo apt upgrade\n sudo apt install git -y\n curl -fsSL https://get.docker.com -o get-docker.sh\n sudo sh get-docker.sh\n sudo usermod -aG docker $USER\n newgrp docker\n git clone https://github.com/OpenC3/cosmos-project.git cosmos\n cd cosmos\n # Edit compose.yaml and remove 127.0.0.1: from the ports section of the openc3-traefik service\n ./openc3.sh run\n"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["After about 2 minutes, open a web browser on your computer, and goto: ",(0,i.jsx)(n.a,{href:"http://cosmos.local:2900",children:"http://cosmos.local:2900"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Congratulations! You now have COSMOS running on a Raspberry Pi!"}),"\n"]}),"\n"]})]})}function p(e={}){let{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},2840:function(e,n,r){r.d(n,{Z:function(){return l},a:function(){return t}});var s=r(2784);let i={},o=s.createContext(i);function t(e){let n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]);
1
+ "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["9146"],{3411:function(e,n,r){r.r(n),r.d(n,{default:()=>p,frontMatter:()=>t,metadata:()=>s,assets:()=>c,toc:()=>a,contentTitle:()=>l});var s=JSON.parse('{"id":"guides/raspberrypi","title":"Raspberry Pi","description":"Running COSMOS on a Raspberry Pi","source":"@site/docs/guides/raspberrypi.md","sourceDirName":"guides","slug":"/guides/raspberrypi","permalink":"/tools/staticdocs/docs/guides/raspberrypi","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/guides/raspberrypi.md","tags":[],"version":"current","frontMatter":{"title":"Raspberry Pi","description":"Running COSMOS on a Raspberry Pi","sidebar_custom_props":{"myEmoji":"\uD83C\uDF53"}},"sidebar":"defaultSidebar","previous":{"title":"Performance","permalink":"/tools/staticdocs/docs/guides/performance"},"next":{"title":"Script Writing Guide","permalink":"/tools/staticdocs/docs/guides/script-writing"}}'),i=r("2322"),o=r("2840");let t={title:"Raspberry Pi",description:"Running COSMOS on a Raspberry Pi",sidebar_custom_props:{myEmoji:"\uD83C\uDF53"}},l=void 0,c={},a=[{value:"COSMOS Running on Raspberry Pi 4",id:"cosmos-running-on-raspberry-pi-4",level:3}];function d(e){let n={a:"a",code:"code",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h3,{id:"cosmos-running-on-raspberry-pi-4",children:"COSMOS Running on Raspberry Pi 4"}),"\n",(0,i.jsx)(n.p,{children:"The Raspberry Pi 4 is a low-cost powerful ARM-based minicomputer that runs linux. And because it runs modern linux, it can also run COSMOS! These directions will get you up and running."}),"\n",(0,i.jsx)(n.p,{children:"What you'll need:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Raspberry Pi 4 board (tested with 8GB RAM)"}),"\n",(0,i.jsx)(n.li,{children:"A Pi Case but Optional"}),"\n",(0,i.jsx)(n.li,{children:"Raspbeerry Pi Power Supply"}),"\n",(0,i.jsx)(n.li,{children:"32GB or Larger SD Card - Also faster the better"}),"\n",(0,i.jsx)(n.li,{children:"A Laptop with a way to write SD Cards"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Let's get started!"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Setup 64-bit Raspian OS Lite on the SD Card"}),"\n",(0,i.jsxs)(n.p,{children:["Make sure you have the Raspberry Pi Imager app from: ",(0,i.jsx)(n.a,{href:"https://www.raspberrypi.com/software/",children:"https://www.raspberrypi.com/software/"})]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Insert the SD Card into your computer (Note this process will erase all data on the SD card!)"}),"\n",(0,i.jsx)(n.li,{children:"Open the Raspberry Pi Imager App"}),"\n",(0,i.jsx)(n.li,{children:'Click the "Choose Device" Button'}),"\n",(0,i.jsx)(n.li,{children:"Pick Your Raspberry Pi Model"}),"\n",(0,i.jsx)(n.li,{children:'Click the "Choose OS" Button'}),"\n",(0,i.jsx)(n.li,{children:'Select "Raspberry Pi OS (other)"'}),"\n",(0,i.jsx)(n.li,{children:'Select "Raspberry Pi OS Lite (64-bit)"'}),"\n",(0,i.jsx)(n.li,{children:'Click the "Choose Storage" Button'}),"\n",(0,i.jsx)(n.li,{children:"Select Your SD Card"}),"\n",(0,i.jsx)(n.li,{children:"Click Edit Settings"}),"\n",(0,i.jsx)(n.li,{children:"If prompted if you would like to prefill the Wifi information, select OK"}),"\n",(0,i.jsx)(n.li,{children:"Set the hostname to: cosmos.local"}),"\n",(0,i.jsx)(n.li,{children:"Set the username and password. The default username is your username, you should also set a password to make the system secure"}),"\n",(0,i.jsx)(n.li,{children:"Fill in your Wifi info, and set the country appropriately (ie. US)"}),"\n",(0,i.jsx)(n.li,{children:"Set the correct time zone"}),"\n",(0,i.jsx)(n.li,{children:"Goto the Services Tab and Enable SSH"}),"\n",(0,i.jsx)(n.li,{children:"You can either use Password auth, or public-key only if your computer is already setup for passwordless SSH"}),"\n",(0,i.jsx)(n.li,{children:'Goto the Options tab and make sure "Enable Telemetry" is not checked'}),"\n",(0,i.jsx)(n.li,{children:'Click "Save" when everything is filled out'}),"\n",(0,i.jsx)(n.li,{children:'Click "Yes" to apply OS Customization Settings, Yes to Are You Sure, and Wait for it to complete'}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Make sure the Raspberry Pi is NOT powered on"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Remove the SD Card from your computer and insert into the Raspberry Pi"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Apply power to the Raspberry Pi and wait approximately 1 minute for it to boot"}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"SSH to your raspberry Pi"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Open a terminal window and use ssh to connect to your Pi"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["On Mac / Linux: ssh ",(0,i.jsx)(n.a,{href:"mailto:yourusername@cosmos.local",children:"yourusername@cosmos.local"})]}),"\n",(0,i.jsx)(n.li,{children:"On Windows, use Putty to connect. You will probably have to install Bonjour for Windows for .local addresses to work as well."}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"From SSH, Enter the following commands"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:" sudo sysctl -w vm.max_map_count=262144\n sudo sysctl -w vm.overcommit_memory=1\n sudo apt update\n sudo apt upgrade\n sudo apt install git -y\n curl -fsSL https://get.docker.com -o get-docker.sh\n sudo sh get-docker.sh\n sudo usermod -aG docker $USER\n newgrp docker\n git clone https://github.com/OpenC3/cosmos-project.git cosmos\n cd cosmos\n # Edit compose.yaml and remove 127.0.0.1: from the ports section of the openc3-traefik service\n ./openc3.sh run\n"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["After about 2 minutes, open a web browser on your computer, and goto: ",(0,i.jsx)(n.a,{href:"http://cosmos.local:2900",children:"http://cosmos.local:2900"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Congratulations! You now have COSMOS running on a Raspberry Pi!"}),"\n"]}),"\n"]})]})}function p(e={}){let{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},2840:function(e,n,r){r.d(n,{Z:function(){return l},a:function(){return t}});var s=r(2784);let i={},o=s.createContext(i);function t(e){let n=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["3380"],{9633:function(e,c,n){n.r(c),n.d(c,{default:function(){return d}});var r=n(2322);n(2784);var s=n(7239),o=n(4700),u=n(8483),t=n(9702),a=n(6290);function d(e){return(0,r.jsx)(o.FG,{className:(0,s.Z)(u.k.wrapper.docsPages),children:(0,r.jsx)(a.Z,{children:(0,t.H)(e.route.routes)})})}}}]);
@@ -1 +1 @@
1
- "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["7637"],{9121:function(e,t,n){n.r(t),n.d(t,{default:()=>h,frontMatter:()=>o,metadata:()=>s,assets:()=>l,toc:()=>c,contentTitle:()=>a});var s=JSON.parse('{"id":"getting-started/generators","title":"Code Generators","description":"Using openc3.sh to generate code","source":"@site/docs/getting-started/generators.md","sourceDirName":"getting-started","slug":"/getting-started/generators","permalink":"/tools/staticdocs/docs/getting-started/generators","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/getting-started/generators.md","tags":[],"version":"current","sidebarPosition":3,"frontMatter":{"sidebar_position":3,"title":"Code Generators","description":"Using openc3.sh to generate code","sidebar_custom_props":{"myEmoji":"\uD83C\uDFED"}},"sidebar":"defaultSidebar","previous":{"title":"Getting Started","permalink":"/tools/staticdocs/docs/getting-started/gettingstarted"},"next":{"title":"Upgrading","permalink":"/tools/staticdocs/docs/getting-started/upgrading"}}'),i=n("2322"),r=n("2840");let o={sidebar_position:3,title:"Code Generators",description:"Using openc3.sh to generate code",sidebar_custom_props:{myEmoji:"\uD83C\uDFED"}},a=void 0,l={},c=[{value:"Plugin Generator",id:"plugin-generator",level:2},{value:"Target Generator",id:"target-generator",level:2},{value:"Microservice Generator",id:"microservice-generator",level:2},{value:"Conversion Generator",id:"conversion-generator",level:2},{value:"Limits Response Generator",id:"limits-response-generator",level:2},{value:"Widget Generator",id:"widget-generator",level:2},{value:"Tool Generator",id:"tool-generator",level:2}];function d(e){let t={a:"a",admonition:"admonition",code:"code",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["The COSMOS Code Generators are built into the scripts ",(0,i.jsx)(t.code,{children:"openc3.sh"})," and ",(0,i.jsx)(t.code,{children:"openc3.bat"})," that are included in the COSMOS ",(0,i.jsx)(t.a,{href:"https://github.com/OpenC3/cosmos-project",children:"project"})," (more about ",(0,i.jsx)(t.a,{href:"key_concepts#projects",children:"projects"}),")."]}),"\n",(0,i.jsxs)(t.p,{children:["If you followed the ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/getting-started/installation",children:"Installation Guide"})," you should already be inside a cloned ",(0,i.jsx)(t.a,{href:"https://github.com/OpenC3/cosmos-project",children:"openc3-project"})," which is in your PATH (necessary for openc3.bat / openc3.sh to be resolved). To see all the available code generators type the following:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"% openc3.sh cli generate\nUnknown generator ''. Valid generators: plugin, target, microservice, widget, conversion,\nlimits_response, tool, tool_vue, tool_angular, tool_react, tool_svelte\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"Training Available",type:"note",children:(0,i.jsxs)(t.p,{children:["If any of this gets confusing, contact us at ",(0,i.jsx)("a",{href:"mailto:support@openc3.com",children:(0,i.jsx)(t.a,{href:"mailto:support@openc3.com",children:"support@openc3.com"})}),". We have training classes available!"]})}),"\n",(0,i.jsx)(t.h2,{id:"plugin-generator",children:"Plugin Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The plugin generator creates the scaffolding for a new COSMOS Plugin. It requires a plugin name and will create a new directory called ",(0,i.jsx)(t.code,{children:"openc3-cosmos-<name>"}),". For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"% openc3.sh cli generate plugin\nUsage: cli generate plugin <NAME>\n\n% openc3.sh cli generate plugin GSE\nPlugin openc3-cosmos-gse successfully generated!\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:".gitignore"}),(0,i.jsx)(t.td,{children:"Tells git to ignore any node_modules directory (for tool development)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"LICENSE.txt"}),(0,i.jsx)(t.td,{children:"License for the plugin. COSMOS Plugins should be licensed in a manner compatible with the AGPLv3, unless they are designed only for use with COSMOS Enterprise Edition."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"openc3-cosmos-gse.gemspec"}),(0,i.jsxs)(t.td,{children:["Gemspec file which should be edited to add user specific information like description, authors, emails, homepage, etc. The name of this file is used in compiling the plugin contents into the final corresponding gem file: e.g. openc3-cosmos-gse-1.0.0.gem. COSMOS plugins should always begin with the openc3-cosmos prefix to make them easily identifiable in the Rubygems repository. The file is formatted as documented at: ",(0,i.jsx)(t.a,{href:"https://guides.rubygems.org/specification-reference/",children:"https://guides.rubygems.org/specification-reference/"})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"plugin.txt"}),(0,i.jsxs)(t.td,{children:["COSMOS specific file for Plugin creation. Learn more ",(0,i.jsx)(t.a,{href:"../configuration/plugins",children:"here"}),"."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Rakefile"}),(0,i.jsx)(t.td,{children:'Ruby Rakefile configured to support building the plugin by running "openc3.sh cli rake build VERSION=X.X.X" where X.X.X is the plugin version number'})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"README.md"}),(0,i.jsx)(t.td,{children:"Markdown file used to document the plugin"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"requirements.txt"}),(0,i.jsx)(t.td,{children:"Python dependencies file (only for Python plugins)"})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"While this structure is required, it is not very useful by itself. The plugin generator just creates the framework for other generators to use."}),"\n",(0,i.jsx)(t.h2,{id:"target-generator",children:"Target Generator"}),"\n",(0,i.jsx)(t.p,{children:"The target generator creates the scaffolding for a new COSMOS Target. It must operate inside an existing COSMOS plugin and requires a target name. For example:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate target\nUsage: cli generate target <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate target GSE\nTarget GSE successfully generated!\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE"}),(0,i.jsx)(t.td,{children:"Contains the configuration for the GSE target. The target name is always defined in all caps. This is typically the default name of the target, but well-designed targets will allow themselves to be renamed at installation."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/cmd_tlm"}),(0,i.jsx)(t.td,{children:"Contains the command and telemetry definition files for the GSE target. These files capture the format of the commands that can be sent to the target, and the telemetry packets that are expected to be received by COSMOS from the target. Note that the files in this folder are processed in alphabetical order by default. That can matter if you reference a packet in another file (it must already have been defined)."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/cmd_tlm/cmd.txt"}),(0,i.jsxs)(t.td,{children:["Example ",(0,i.jsx)(t.a,{href:"../configuration/command",children:"command"})," configuration. Will need to be edited for the target specific commands."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/cmd_tlm/tlm.txt"}),(0,i.jsxs)(t.td,{children:["Example ",(0,i.jsx)(t.a,{href:"../configuration/telemetry",children:"telemetry"})," configuration. Will need to be edited for the target specific telemetry."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib"}),(0,i.jsxs)(t.td,{children:["Contains any custom code required by the target. Good examples of custom code are library files, custom ",(0,i.jsx)(t.a,{href:"../configuration/interfaces",children:"interface"})," classes and ",(0,i.jsx)(t.a,{href:"../configuration/protocols",children:"protocols"}),"."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib/gse.rb/py"}),(0,i.jsx)(t.td,{children:"Example library file which can be expanded as the target is developed. COSMOS recommends building up library methods to avoid code duplication and ease reuse."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/procedures"}),(0,i.jsxs)(t.td,{children:["This folder contains target specific procedures and helper methods which exercise functionality of the target. These procedures should be kept simple and only use the command and telemetry definitions associated with this target. See the ",(0,i.jsx)(t.a,{href:"../guides/script-writing#script-organization",children:"Scripting Guide"})," for more information."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/procedures/procedure.rb/py"}),(0,i.jsx)(t.td,{children:"Procedure with an example of sending a command and checking telemetry"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/public"}),(0,i.jsxs)(t.td,{children:["Put image files here for use in Telemetry Viewer Canvas Image widgets such as ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens#canvasimage",children:"CANVASIMAGE"})," and ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens#canvasimagevalue",children:"CANVASIMAGEVALUE"})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/screens"}),(0,i.jsxs)(t.td,{children:["Contains telemetry ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens",children:"screens"})," for the target"]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/screens/status.txt"}),(0,i.jsxs)(t.td,{children:["Example ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens",children:"screen"})," to display telemetry values"]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/target.txt"}),(0,i.jsxs)(t.td,{children:[(0,i.jsx)(t.a,{href:"../configuration/target",children:"Target"})," configuration such as ignoring command and telemetry items and how to process the cmd/tlm files"]})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"It also updates the plugin.txt file to add the new target:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:"VARIABLE gse_target_name GSE\n\nTARGET GSE <%= gse_target_name %>\nINTERFACE <%= gse_target_name %>_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil BURST\n MAP_TARGET <%= gse_target_name %>\n"})}),"\n",(0,i.jsx)(t.h2,{id:"microservice-generator",children:"Microservice Generator"}),"\n",(0,i.jsx)(t.p,{children:"The microservice generator creates the scaffolding for a new COSMOS Microservice. It must operate inside an existing COSMOS plugin and requires a target name. For example:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate microservice\nUsage: cli generate microservice <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate microservice background\nMicroservice BACKGROUND successfully generated!\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"microservices/BACKGROUND"}),(0,i.jsx)(t.td,{children:"Contains the code and any necessary configuration for the BACKGROUND microservice. The name is always defined in all caps. This is typically the default name of the microservice, but well-designed microservices will allow themselves to be renamed at installation."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"microservices/BACKGROUND/background.rb"}),(0,i.jsx)(t.td,{children:"Fully functional microservice which will run every minute and log a message. Edit to implement any custom logic that you want to run in the background. Potential uses are safety microservices which can check and autonomously respond to complex events and take action (NOTE: Simple actions might just require a Limits Response)."})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"It also updates the plugin.txt file to add the new microservice:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:"MICROSERVICE BACKGROUND background-microservice\n CMD ruby background.rb\n"})}),"\n",(0,i.jsx)(t.h2,{id:"conversion-generator",children:"Conversion Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The conversion generator creates the scaffolding for a new COSMOS ",(0,i.jsx)(t.a,{href:"../configuration/telemetry#read_conversion",children:"Conversion"}),". It must operate inside an existing COSMOS plugin and requires both a target name and conversion name. For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate conversion\nUsage: cli generate conversion <TARGET> <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate limits_response GSE double\nConversion targets/GSE/lib/double_conversion.rb successfully generated!\nTo use the conversion add the following to a telemetry item:\n READ_CONVERSION double_conversion.rb\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib/double_conversion.rb"}),(0,i.jsx)(t.td,{children:"Fully functional Conversion which has an example implementation of the call() method to convert any existing COSMOS values."})]})})]}),"\n",(0,i.jsx)(t.p,{children:"As the generator states, to use this conversion code you must add it to a telemetry item. For example:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:'TELEMETRY GSE STATUS BIG_ENDIAN "Telemetry description"\n # Keyword Name BitSize Type ID Description\n APPEND_ID_ITEM ID 16 INT 1 "Identifier"\n APPEND_ITEM VALUE 32 FLOAT "Value"\n READ_CONVERSION double_conversion.rb\n APPEND_ITEM BOOL 8 UINT "Boolean"\n STATE FALSE 0\n STATE TRUE 1\n APPEND_ITEM LABEL 0 STRING "The label to apply"\n'})}),"\n",(0,i.jsx)(t.h2,{id:"limits-response-generator",children:"Limits Response Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The limits_response generator creates the scaffolding for a new COSMOS ",(0,i.jsx)(t.a,{href:"../configuration/telemetry#limits_response",children:"Limits Response"}),". It must operate inside an existing COSMOS plugin and requires both a target name and limits response name. For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate limits_response\nUsage: cli generate limits_response <TARGET> <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate limits_response GSE safe\nLimits response targets/GSE/lib/safe_limits_response.rb successfully generated!\nTo use the limits response add the following to a telemetry item:\n LIMITS_RESPONSE safe_limits_response.rb\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib/safe_limits_response.rb"}),(0,i.jsx)(t.td,{children:"Fully functional Limits Response which has an example implementation of the call() method and taking action based on the current limits state of the particular item"})]})})]}),"\n",(0,i.jsx)(t.p,{children:"As the generator states, to use this limits code you must add it to a telemetry item which has limits defined. In the generated GSE target, none of the items have limits defined so you first need to add limits and then add the response."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:'TELEMETRY GSE STATUS BIG_ENDIAN "Telemetry description"\n # Keyword Name BitSize Type ID Description\n APPEND_ID_ITEM ID 16 INT 1 "Identifier"\n APPEND_ITEM VALUE 32 FLOAT "Value"\n LIMITS DEFAULT 1 ENABLED -80.0 -70.0 60.0 80.0 -20.0 20.0\n LIMITS_RESPONSE safe_limits_response.rb\n APPEND_ITEM BOOL 8 UINT "Boolean"\n STATE FALSE 0\n STATE TRUE 1\n APPEND_ITEM LABEL 0 STRING "The label to apply"\n'})}),"\n",(0,i.jsx)(t.h2,{id:"widget-generator",children:"Widget Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The conversion generator creates the scaffolding for a new COSMOS Widget for use in ",(0,i.jsx)(t.a,{href:"../configuration/telemetry-screens",children:"Telemetry Viewer Screens"}),". For more information see the ",(0,i.jsx)(t.a,{href:"../guides/custom-widgets",children:"Custom Widget"})," guide. It must operate inside an existing COSMOS plugin and requires a widget name. For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate widget\nUsage: cli generate widget <SuperdataWidget>\n\nopenc3-cosmos-gse % openc3.sh cli generate widget HelloworldWidget\nWidget HelloworldWidget successfully generated!\nPlease be sure HelloworldWidget does not overlap an existing widget: https://docs.openc3.com/docs/configuration/telemetry-screens\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/HelloworldWidget.vue"}),(0,i.jsx)(t.td,{children:"Fully functional widget which displays a simple value. This can be expanded using existing COSMOS Vue.js code to create any data visualization imaginable."})]})})]}),"\n",(0,i.jsx)(t.p,{children:"It also updates the plugin.txt file to add the new widget:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:"WIDGET Helloworld\n"})}),"\n",(0,i.jsx)(t.h2,{id:"tool-generator",children:"Tool Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The tool generator creates the scaffolding for a new COSMOS Tool. It's It must operate inside an existing COSMOS plugin and requires a tool name. Developing a custom tool requires intensive knowledge of a Javascript framework such as Vue.js, Angular, React, or Svelte. Since all the COSMOS tools are built in Vue.js, that is the recommended framework for new tool development. For additional help on frontend development, see ",(0,i.jsx)(t.a,{href:"../development/developing#running-a-frontend-application",children:"Running a Frontend Application"}),"."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate tool\nUsage: cli generate tool 'Tool Name'\n\nopenc3-cosmos-gse % openc3.sh cli generate widget DataVis\nTool datavis successfully generated!\nPlease be sure datavis does not conflict with any other tools\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/App.vue"}),(0,i.jsx)(t.td,{children:"Basic Vue template to render the application."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/main.js"}),(0,i.jsx)(t.td,{children:"Entry point for the new tool which loads Vue, Vuetify, and other libraries."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/router.js"}),(0,i.jsx)(t.td,{children:"Vue component router."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/tools/datavis"}),(0,i.jsx)(t.td,{children:"Contains all the files necessary to serve a web-based tool named datavis. The name is always defined in all lowercase. Due to technical limitations, the toolname must be unique and cannot be renamed at installation."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/tools/datavis/datavis.vue"}),(0,i.jsx)(t.td,{children:"Fully functional tool which displays a simple button. This can be expanded using existing COSMOS Vue.js code to create any tool imaginable."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"package.json"}),(0,i.jsx)(t.td,{children:"Build and dependency definition file. Used by npm or yarn to build the tool."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"vue.config.js"}),(0,i.jsx)(t.td,{children:"Vue configuration file used to serve the application in development and build the application."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"<dotfiles>"}),(0,i.jsx)(t.td,{children:"Various dotfiles which help configure formatters and tools for Javascript frontend development"})]})]})]}),"\n",(0,i.jsxs)(t.p,{children:["It also updates the plugin.txt file to add the new tool. The icon can be changed to any of the material design icons found ",(0,i.jsx)(t.a,{href:"https://pictogrammers.com/library/mdi/",children:"here"}),"."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:'TOOL datavis "DataVis"\n INLINE_URL js/app.js\n ICON mdi-file-cad-box\n'})})]})}function h(e={}){let{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},2840:function(e,t,n){n.d(t,{Z:function(){return a},a:function(){return o}});var s=n(2784);let i={},r=s.createContext(i);function o(e){let t=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]);
1
+ "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["7637"],{2695:function(e,t,n){n.r(t),n.d(t,{default:()=>h,frontMatter:()=>o,metadata:()=>s,assets:()=>l,toc:()=>c,contentTitle:()=>a});var s=JSON.parse('{"id":"getting-started/generators","title":"Code Generators","description":"Using openc3.sh to generate code","source":"@site/docs/getting-started/generators.md","sourceDirName":"getting-started","slug":"/getting-started/generators","permalink":"/tools/staticdocs/docs/getting-started/generators","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/getting-started/generators.md","tags":[],"version":"current","sidebarPosition":3,"frontMatter":{"sidebar_position":3,"title":"Code Generators","description":"Using openc3.sh to generate code","sidebar_custom_props":{"myEmoji":"\uD83C\uDFED"}},"sidebar":"defaultSidebar","previous":{"title":"Getting Started","permalink":"/tools/staticdocs/docs/getting-started/gettingstarted"},"next":{"title":"Upgrading","permalink":"/tools/staticdocs/docs/getting-started/upgrading"}}'),i=n("2322"),r=n("2840");let o={sidebar_position:3,title:"Code Generators",description:"Using openc3.sh to generate code",sidebar_custom_props:{myEmoji:"\uD83C\uDFED"}},a=void 0,l={},c=[{value:"Plugin Generator",id:"plugin-generator",level:2},{value:"Target Generator",id:"target-generator",level:2},{value:"Microservice Generator",id:"microservice-generator",level:2},{value:"Conversion Generator",id:"conversion-generator",level:2},{value:"Limits Response Generator",id:"limits-response-generator",level:2},{value:"Widget Generator",id:"widget-generator",level:2},{value:"Tool Generator",id:"tool-generator",level:2}];function d(e){let t={a:"a",admonition:"admonition",code:"code",h2:"h2",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["The COSMOS Code Generators are built into the scripts ",(0,i.jsx)(t.code,{children:"openc3.sh"})," and ",(0,i.jsx)(t.code,{children:"openc3.bat"})," that are included in the COSMOS ",(0,i.jsx)(t.a,{href:"https://github.com/OpenC3/cosmos-project",children:"project"})," (more about ",(0,i.jsx)(t.a,{href:"key_concepts#projects",children:"projects"}),")."]}),"\n",(0,i.jsxs)(t.p,{children:["If you followed the ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/getting-started/installation",children:"Installation Guide"})," you should already be inside a cloned ",(0,i.jsx)(t.a,{href:"https://github.com/OpenC3/cosmos-project",children:"openc3-project"})," which is in your PATH (necessary for openc3.bat / openc3.sh to be resolved). To see all the available code generators type the following:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"% openc3.sh cli generate\nUnknown generator ''. Valid generators: plugin, target, microservice, widget, conversion,\nlimits_response, tool, tool_vue, tool_angular, tool_react, tool_svelte\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"Training Available",type:"note",children:(0,i.jsxs)(t.p,{children:["If any of this gets confusing, contact us at ",(0,i.jsx)("a",{href:"mailto:support@openc3.com",children:(0,i.jsx)(t.a,{href:"mailto:support@openc3.com",children:"support@openc3.com"})}),". We have training classes available!"]})}),"\n",(0,i.jsx)(t.h2,{id:"plugin-generator",children:"Plugin Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The plugin generator creates the scaffolding for a new COSMOS Plugin. It requires a plugin name and will create a new directory called ",(0,i.jsx)(t.code,{children:"openc3-cosmos-<name>"}),". For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"% openc3.sh cli generate plugin\nUsage: cli generate plugin <NAME>\n\n% openc3.sh cli generate plugin GSE\nPlugin openc3-cosmos-gse successfully generated!\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:".gitignore"}),(0,i.jsx)(t.td,{children:"Tells git to ignore any node_modules directory (for tool development)"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"LICENSE.txt"}),(0,i.jsx)(t.td,{children:"License for the plugin. COSMOS Plugins should be licensed in a manner compatible with the AGPLv3, unless they are designed only for use with COSMOS Enterprise Edition."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"openc3-cosmos-gse.gemspec"}),(0,i.jsxs)(t.td,{children:["Gemspec file which should be edited to add user specific information like description, authors, emails, homepage, etc. The name of this file is used in compiling the plugin contents into the final corresponding gem file: e.g. openc3-cosmos-gse-1.0.0.gem. COSMOS plugins should always begin with the openc3-cosmos prefix to make them easily identifiable in the Rubygems repository. The file is formatted as documented at: ",(0,i.jsx)(t.a,{href:"https://guides.rubygems.org/specification-reference/",children:"https://guides.rubygems.org/specification-reference/"})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"plugin.txt"}),(0,i.jsxs)(t.td,{children:["COSMOS specific file for Plugin creation. Learn more ",(0,i.jsx)(t.a,{href:"../configuration/plugins",children:"here"}),"."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"Rakefile"}),(0,i.jsx)(t.td,{children:'Ruby Rakefile configured to support building the plugin by running "openc3.sh cli rake build VERSION=X.X.X" where X.X.X is the plugin version number'})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"README.md"}),(0,i.jsx)(t.td,{children:"Markdown file used to document the plugin"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"requirements.txt"}),(0,i.jsx)(t.td,{children:"Python dependencies file (only for Python plugins)"})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"While this structure is required, it is not very useful by itself. The plugin generator just creates the framework for other generators to use."}),"\n",(0,i.jsx)(t.h2,{id:"target-generator",children:"Target Generator"}),"\n",(0,i.jsx)(t.p,{children:"The target generator creates the scaffolding for a new COSMOS Target. It must operate inside an existing COSMOS plugin and requires a target name. For example:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate target\nUsage: cli generate target <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate target GSE\nTarget GSE successfully generated!\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE"}),(0,i.jsx)(t.td,{children:"Contains the configuration for the GSE target. The target name is always defined in all caps. This is typically the default name of the target, but well-designed targets will allow themselves to be renamed at installation."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/cmd_tlm"}),(0,i.jsx)(t.td,{children:"Contains the command and telemetry definition files for the GSE target. These files capture the format of the commands that can be sent to the target, and the telemetry packets that are expected to be received by COSMOS from the target. Note that the files in this folder are processed in alphabetical order by default. That can matter if you reference a packet in another file (it must already have been defined)."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/cmd_tlm/cmd.txt"}),(0,i.jsxs)(t.td,{children:["Example ",(0,i.jsx)(t.a,{href:"../configuration/command",children:"command"})," configuration. Will need to be edited for the target specific commands."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/cmd_tlm/tlm.txt"}),(0,i.jsxs)(t.td,{children:["Example ",(0,i.jsx)(t.a,{href:"../configuration/telemetry",children:"telemetry"})," configuration. Will need to be edited for the target specific telemetry."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib"}),(0,i.jsxs)(t.td,{children:["Contains any custom code required by the target. Good examples of custom code are library files, custom ",(0,i.jsx)(t.a,{href:"../configuration/interfaces",children:"interface"})," classes and ",(0,i.jsx)(t.a,{href:"../configuration/protocols",children:"protocols"}),"."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib/gse.rb/py"}),(0,i.jsx)(t.td,{children:"Example library file which can be expanded as the target is developed. COSMOS recommends building up library methods to avoid code duplication and ease reuse."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/procedures"}),(0,i.jsxs)(t.td,{children:["This folder contains target specific procedures and helper methods which exercise functionality of the target. These procedures should be kept simple and only use the command and telemetry definitions associated with this target. See the ",(0,i.jsx)(t.a,{href:"../guides/script-writing#script-organization",children:"Scripting Guide"})," for more information."]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/procedures/procedure.rb/py"}),(0,i.jsx)(t.td,{children:"Procedure with an example of sending a command and checking telemetry"})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/public"}),(0,i.jsxs)(t.td,{children:["Put image files here for use in Telemetry Viewer Canvas Image widgets such as ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens#canvasimage",children:"CANVASIMAGE"})," and ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens#canvasimagevalue",children:"CANVASIMAGEVALUE"})]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/screens"}),(0,i.jsxs)(t.td,{children:["Contains telemetry ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens",children:"screens"})," for the target"]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/screens/status.txt"}),(0,i.jsxs)(t.td,{children:["Example ",(0,i.jsx)(t.a,{href:"/tools/staticdocs/docs/configuration/telemetry-screens",children:"screen"})," to display telemetry values"]})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/target.txt"}),(0,i.jsxs)(t.td,{children:[(0,i.jsx)(t.a,{href:"../configuration/target",children:"Target"})," configuration such as ignoring command and telemetry items and how to process the cmd/tlm files"]})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"It also updates the plugin.txt file to add the new target:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:"VARIABLE gse_target_name GSE\n\nTARGET GSE <%= gse_target_name %>\nINTERFACE <%= gse_target_name %>_INT tcpip_client_interface.rb host.docker.internal 8080 8081 10.0 nil BURST\n MAP_TARGET <%= gse_target_name %>\n"})}),"\n",(0,i.jsx)(t.h2,{id:"microservice-generator",children:"Microservice Generator"}),"\n",(0,i.jsx)(t.p,{children:"The microservice generator creates the scaffolding for a new COSMOS Microservice. It must operate inside an existing COSMOS plugin and requires a target name. For example:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate microservice\nUsage: cli generate microservice <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate microservice background\nMicroservice BACKGROUND successfully generated!\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"microservices/BACKGROUND"}),(0,i.jsx)(t.td,{children:"Contains the code and any necessary configuration for the BACKGROUND microservice. The name is always defined in all caps. This is typically the default name of the microservice, but well-designed microservices will allow themselves to be renamed at installation."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"microservices/BACKGROUND/background.rb"}),(0,i.jsx)(t.td,{children:"Fully functional microservice which will run every minute and log a message. Edit to implement any custom logic that you want to run in the background. Potential uses are safety microservices which can check and autonomously respond to complex events and take action (NOTE: Simple actions might just require a Limits Response)."})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"It also updates the plugin.txt file to add the new microservice:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:"MICROSERVICE BACKGROUND background-microservice\n CMD ruby background.rb\n"})}),"\n",(0,i.jsx)(t.h2,{id:"conversion-generator",children:"Conversion Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The conversion generator creates the scaffolding for a new COSMOS ",(0,i.jsx)(t.a,{href:"../configuration/telemetry#read_conversion",children:"Conversion"}),". It must operate inside an existing COSMOS plugin and requires both a target name and conversion name. For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate conversion\nUsage: cli generate conversion <TARGET> <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate limits_response GSE double\nConversion targets/GSE/lib/double_conversion.rb successfully generated!\nTo use the conversion add the following to a telemetry item:\n READ_CONVERSION double_conversion.rb\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib/double_conversion.rb"}),(0,i.jsx)(t.td,{children:"Fully functional Conversion which has an example implementation of the call() method to convert any existing COSMOS values."})]})})]}),"\n",(0,i.jsx)(t.p,{children:"As the generator states, to use this conversion code you must add it to a telemetry item. For example:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:'TELEMETRY GSE STATUS BIG_ENDIAN "Telemetry description"\n # Keyword Name BitSize Type ID Description\n APPEND_ID_ITEM ID 16 INT 1 "Identifier"\n APPEND_ITEM VALUE 32 FLOAT "Value"\n READ_CONVERSION double_conversion.rb\n APPEND_ITEM BOOL 8 UINT "Boolean"\n STATE FALSE 0\n STATE TRUE 1\n APPEND_ITEM LABEL 0 STRING "The label to apply"\n'})}),"\n",(0,i.jsx)(t.h2,{id:"limits-response-generator",children:"Limits Response Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The limits_response generator creates the scaffolding for a new COSMOS ",(0,i.jsx)(t.a,{href:"../configuration/telemetry#limits_response",children:"Limits Response"}),". It must operate inside an existing COSMOS plugin and requires both a target name and limits response name. For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate limits_response\nUsage: cli generate limits_response <TARGET> <NAME> (--ruby or --python)\n\nopenc3-cosmos-gse % openc3.sh cli generate limits_response GSE safe\nLimits response targets/GSE/lib/safe_limits_response.rb successfully generated!\nTo use the limits response add the following to a telemetry item:\n LIMITS_RESPONSE safe_limits_response.rb\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"targets/GSE/lib/safe_limits_response.rb"}),(0,i.jsx)(t.td,{children:"Fully functional Limits Response which has an example implementation of the call() method and taking action based on the current limits state of the particular item"})]})})]}),"\n",(0,i.jsx)(t.p,{children:"As the generator states, to use this limits code you must add it to a telemetry item which has limits defined. In the generated GSE target, none of the items have limits defined so you first need to add limits and then add the response."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:'TELEMETRY GSE STATUS BIG_ENDIAN "Telemetry description"\n # Keyword Name BitSize Type ID Description\n APPEND_ID_ITEM ID 16 INT 1 "Identifier"\n APPEND_ITEM VALUE 32 FLOAT "Value"\n LIMITS DEFAULT 1 ENABLED -80.0 -70.0 60.0 80.0 -20.0 20.0\n LIMITS_RESPONSE safe_limits_response.rb\n APPEND_ITEM BOOL 8 UINT "Boolean"\n STATE FALSE 0\n STATE TRUE 1\n APPEND_ITEM LABEL 0 STRING "The label to apply"\n'})}),"\n",(0,i.jsx)(t.h2,{id:"widget-generator",children:"Widget Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The conversion generator creates the scaffolding for a new COSMOS Widget for use in ",(0,i.jsx)(t.a,{href:"../configuration/telemetry-screens",children:"Telemetry Viewer Screens"}),". For more information see the ",(0,i.jsx)(t.a,{href:"../guides/custom-widgets",children:"Custom Widget"})," guide. It must operate inside an existing COSMOS plugin and requires a widget name. For example:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate widget\nUsage: cli generate widget <SuperdataWidget>\n\nopenc3-cosmos-gse % openc3.sh cli generate widget HelloworldWidget\nWidget HelloworldWidget successfully generated!\nPlease be sure HelloworldWidget does not overlap an existing widget: https://docs.openc3.com/docs/configuration/telemetry-screens\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsx)(t.tbody,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/HelloworldWidget.vue"}),(0,i.jsx)(t.td,{children:"Fully functional widget which displays a simple value. This can be expanded using existing COSMOS Vue.js code to create any data visualization imaginable."})]})})]}),"\n",(0,i.jsx)(t.p,{children:"It also updates the plugin.txt file to add the new widget:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:"WIDGET Helloworld\n"})}),"\n",(0,i.jsx)(t.h2,{id:"tool-generator",children:"Tool Generator"}),"\n",(0,i.jsxs)(t.p,{children:["The tool generator creates the scaffolding for a new COSMOS Tool. It's It must operate inside an existing COSMOS plugin and requires a tool name. Developing a custom tool requires intensive knowledge of a Javascript framework such as Vue.js, Angular, React, or Svelte. Since all the COSMOS tools are built in Vue.js, that is the recommended framework for new tool development. For additional help on frontend development, see ",(0,i.jsx)(t.a,{href:"../development/developing#running-a-frontend-application",children:"Running a Frontend Application"}),"."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"openc3-cosmos-gse % openc3.sh cli generate tool\nUsage: cli generate tool 'Tool Name'\n\nopenc3-cosmos-gse % openc3.sh cli generate widget DataVis\nTool datavis successfully generated!\nPlease be sure datavis does not conflict with any other tools\n"})}),"\n",(0,i.jsx)(t.p,{children:"This creates the following files and directories:"}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Name"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/App.vue"}),(0,i.jsx)(t.td,{children:"Basic Vue template to render the application."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/main.js"}),(0,i.jsx)(t.td,{children:"Entry point for the new tool which loads Vue, Vuetify, and other libraries."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/router.js"}),(0,i.jsx)(t.td,{children:"Vue component router."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/tools/datavis"}),(0,i.jsx)(t.td,{children:"Contains all the files necessary to serve a web-based tool named datavis. The name is always defined in all lowercase. Due to technical limitations, the toolname must be unique and cannot be renamed at installation."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"src/tools/datavis/datavis.vue"}),(0,i.jsx)(t.td,{children:"Fully functional tool which displays a simple button. This can be expanded using existing COSMOS Vue.js code to create any tool imaginable."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"package.json"}),(0,i.jsx)(t.td,{children:"Build and dependency definition file. Used by npm or yarn to build the tool."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"vue.config.js"}),(0,i.jsx)(t.td,{children:"Vue configuration file used to serve the application in development and build the application."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:"<dotfiles>"}),(0,i.jsx)(t.td,{children:"Various dotfiles which help configure formatters and tools for Javascript frontend development"})]})]})]}),"\n",(0,i.jsxs)(t.p,{children:["It also updates the plugin.txt file to add the new tool. The icon can be changed to any of the material design icons found ",(0,i.jsx)(t.a,{href:"https://pictogrammers.com/library/mdi/",children:"here"}),"."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ruby",children:'TOOL datavis "DataVis"\n INLINE_URL main.js\n ICON mdi-file-cad-box\n'})})]})}function h(e={}){let{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},2840:function(e,t,n){n.d(t,{Z:function(){return a},a:function(){return o}});var s=n(2784);let i={},r=s.createContext(i);function o(e){let t=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["5162"],{8351:function(e,n,i){i.r(n),i.d(n,{default:()=>h,frontMatter:()=>s,metadata:()=>r,assets:()=>a,toc:()=>l,contentTitle:()=>c});var r=JSON.parse('{"id":"guides/exposing_microservices","title":"Exposing Microservices","description":"Provide external accessibility to microservices","source":"@site/docs/guides/exposing_microservices.md","sourceDirName":"guides","slug":"/guides/exposing_microservices","permalink":"/tools/staticdocs/docs/guides/exposing_microservices","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/guides/exposing_microservices.md","tags":[],"version":"current","frontMatter":{"title":"Exposing Microservices","description":"Provide external accessibility to microservices","sidebar_custom_props":{"myEmoji":"\uD83D\uDEAA"}},"sidebar":"defaultSidebar","previous":{"title":"Custom Widgets","permalink":"/tools/staticdocs/docs/guides/custom-widgets"},"next":{"title":"Little Endian Bitfields","permalink":"/tools/staticdocs/docs/guides/little-endian-bitfields"}}'),t=i("2322"),o=i("2840");let s={title:"Exposing Microservices",description:"Provide external accessibility to microservices",sidebar_custom_props:{myEmoji:"\uD83D\uDEAA"}},c=void 0,a={},l=[{value:"Expose microservices using the PORT and ROUTE_PREFIX keywords",id:"expose-microservices-using-the-port-and-route_prefix-keywords",level:2},{value:"Connecting to microservices from a different INTERFACE in plugin.txt",id:"connecting-to-microservices-from-a-different-interface-in-plugintxt",level:2}];function d(e){let n={a:"a",admonition:"admonition",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"COSMOS provides a simple method to add new APIs and make custom microservices and interfaces accessible to the network."}),"\n",(0,t.jsx)(n.admonition,{title:"Make sure anything you expose is secure",type:"warning",children:(0,t.jsx)(n.p,{children:"Make sure that any new apis you expose check for user credentials and authorize actions appropriately."})}),"\n",(0,t.jsx)(n.h2,{id:"expose-microservices-using-the-port-and-route_prefix-keywords",children:"Expose microservices using the PORT and ROUTE_PREFIX keywords"}),"\n",(0,t.jsxs)(n.p,{children:["In your plugin.txt file, both ",(0,t.jsx)(n.a,{href:"../configuration/plugins#interface-1",children:"INTERFACE"})," and ",(0,t.jsx)(n.a,{href:"../configuration/plugins#microservice-1",children:"MICROSERVICE"})," support the keywords ",(0,t.jsx)(n.a,{href:"../configuration/plugins#port-1",children:"PORT"})," and ",(0,t.jsx)(n.a,{href:"../configuration/plugins#route_prefix-1",children:"ROUTE_PREFIX"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"../configuration/plugins#port-1",children:"PORT"})," is used to declare the port(s) that your microservice is listening for connections on. This is used in combination with ",(0,t.jsx)(n.a,{href:"../configuration/plugins#route_prefix-1",children:"ROUTE_PREFIX"})," to create a dynamic traefik route to your microservice."]}),"\n",(0,t.jsx)(n.p,{children:"The following code is used internally to let traefik know where to connect to your microservice internally:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ruby",children:"if ENV['OPENC3_OPERATOR_HOSTNAME']\n url = \"http://#{ENV['OPENC3_OPERATOR_HOSTNAME']}:#{port}\"\nelse\n if ENV['KUBERNETES_SERVICE_HOST']\n url = \"http://#{microservice_name.downcase.gsub('__', '-').gsub('_', '-')}-service:#{port}\"\n else\n url = \"http://openc3-operator:#{port}\"\n end\nend\n"})}),"\n",(0,t.jsx)(n.p,{children:"Note that this is the internal route to your microservice. Determining this route checks two different environment variables."}),"\n",(0,t.jsx)(n.p,{children:'OPENC3_OPERATOR_HOSTNAME is used to override the default service name for our regular docker compose operator of "openc3-operator". Usually this is not set.'}),"\n",(0,t.jsx)(n.p,{children:"In OpenC3 Enterprise, KUBERNETES_SERVICE_HOST is used to detect if we are running in a Kubernetes environment (it will be set by Kubernetes), in which case the service is expected to have a Kubernetes service named scope-user-microservicename-service. For example, if you are using the DEFAULT scope and have a microservice named MYMICROSERVICE the service would be found at the hostname: default-user-mymicroservice-service. Double underscores or single underscores are replaced by a dash and the name is all lower case."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"../configuration/plugins#route_prefix-1",children:"ROUTE_PREFIX"})," is used to define the external route. The external route will take the form of http(s)://YOURCOSMOSDOMAIN",":PORT","/ROUTE_PREFIX. So for example, if you set the ",(0,t.jsx)(n.a,{href:"../configuration/plugins#route_prefix-1",children:"ROUTE_PREFIX"})," to /mymicroservice then on a default local installation, it could be reached at ",(0,t.jsx)(n.code,{children:"http://localhost:2900/mymicroservice"}),". The ",(0,t.jsx)(n.code,{children:"http://localhost:2900"})," part should be substituted by whatever domain you are accessing COSMOS at."]}),"\n",(0,t.jsxs)(n.p,{children:["Here is a snippet of code showing ",(0,t.jsx)(n.a,{href:"../configuration/plugins#port-1",children:"PORT"})," and ",(0,t.jsx)(n.a,{href:"../configuration/plugins#route_prefix-1",children:"ROUTE_PREFIX"})," in use within a plugin.txt file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"VARIABLE cfdp_microservice_name CFDP\nVARIABLE cfdp_route_prefix /cfdp\nVARIABLE cfdp_port 2905\n\nMICROSERVICE CFDP <%= cfdp_microservice_name %>\n WORK_DIR .\n ROUTE_PREFIX <%= cfdp_route_prefix %>\n PORT <%= cfdp_port %>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Leaving the variables at their default values the following will occur:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The microservice will be exposed internally to Docker (Open Source or Enterprise) at: ",(0,t.jsx)(n.code,{children:"http://openc3-operator:2905"})]}),"\n",(0,t.jsxs)(n.li,{children:["The microservice will be exposed internally to Kubernetes (Enterprise) at: ",(0,t.jsx)(n.code,{children:"http://default-user-cfdp-service:2905"})]}),"\n",(0,t.jsxs)(n.li,{children:["The microservice will be exposed externally to the network at: ",(0,t.jsx)(n.code,{children:"http://localhost:2900/cfdp"})]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The same can be done for ",(0,t.jsx)(n.a,{href:"../configuration/plugins#interface-1",children:"INTERFACE"})," but note that the Kubernetes service name will use the microservice name of the interface which takes the form of ",(0,t.jsx)(n.code,{children:"SCOPE__INTERFACE__INTERFACENAME"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Here is an example using ",(0,t.jsx)(n.a,{href:"../configuration/plugins#port",children:"PORT"})," and ",(0,t.jsx)(n.a,{href:"../configuration/plugins#route_prefix",children:"ROUTE_PREFIX"})," with ",(0,t.jsx)(n.a,{href:"../configuration/plugins#interface-1",children:"INTERFACE"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"VARIABLE my_interface_name MY_INT\nVARIABLE my_route_prefix /myint\nVARIABLE my_port 2910\n\nINTERFACE <%= my_interface_name %> http_server_interface.rb <%= my_port %>\n ROUTE_PREFIX <%= my_route_prefix %>\n PORT <%= my_port %>\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The interface will be exposed internally to Docker (Open Source or Enterprise) at: ",(0,t.jsx)(n.code,{children:"http://openc3-operator:2910"})]}),"\n",(0,t.jsxs)(n.li,{children:["The interface will be exposed internally to Kubernetes (Enterprise) at: ",(0,t.jsx)(n.code,{children:"http://default-interface-my-int-service:2905"})]}),"\n",(0,t.jsxs)(n.li,{children:["The interface will be exposed externally to the network at: ",(0,t.jsx)(n.code,{children:"http://localhost:2900/myint"})]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{title:"Sharded Operator on Kubernetes (Enterprise)",type:"warning",children:(0,t.jsx)(n.p,{children:"The sharded operator is expected to be used on Kubernetes whenever the Kubernetes Operator is not used. Typically this will be because the user does not have permission to use the Kubernetes API directly to spawn containers which is required for use of the Kubernetes Operator. In this case, Kubernetes services will NOT be automatically created, and will have to be manually created by a user with permissions in Kubernetes, or through some other authorized method (like a custom framework dashboard or config file)."})}),"\n",(0,t.jsx)(n.h2,{id:"connecting-to-microservices-from-a-different-interface-in-plugintxt",children:"Connecting to microservices from a different INTERFACE in plugin.txt"}),"\n",(0,t.jsx)(n.p,{children:"Sometimes you might want to have an INTERFACE connect to a microservice you are running. For this case, only the PORT keyword is required on the INTERFACE or MICROSERVICE because we are only connecting internally and ROUTE_PREFIX isn't used."}),"\n",(0,t.jsx)(n.p,{children:"The following code taken from our demo plugin provides an example of how to calculate the correct hostname across both Open Source and Enterprise versions of COSMOS in a plugin.txt file:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:" <% example_host = ENV['KUBERNETES_SERVICE_HOST'] ? \"#{scope}-user-#{example_microservice_name.downcase.gsub('__', '-').gsub('_', '-')}-service\" : \"openc3-operator\" %>\n INTERFACE <%= example_int_name %> example_interface.rb <%= example_host %> <%= example_port %>\n MAP_TARGET <%= example_target_name %>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Note that the above code does not handle the OPENC3_OPERATOR_HOSTNAME environment variable which might change the default name of openc3-operator. Update as needed."})]})}function h(e={}){let{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},2840:function(e,n,i){i.d(n,{Z:function(){return c},a:function(){return s}});var r=i(2784);let t={},o=r.createContext(t);function s(e){let n=r.useContext(o);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["3969"],{6697:function(c,e,o){o.r(e)}}]);
@@ -1 +1 @@
1
- "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["7810"],{8120:function(e,n,t){t.r(n),t.d(n,{default:()=>u,frontMatter:()=>r,metadata:()=>o,assets:()=>l,toc:()=>a,contentTitle:()=>c});var o=JSON.parse('{"id":"meta/contributing","title":"Contributing","description":"Contributing to COSMOS using the github workflow","source":"@site/docs/meta/contributing.md","sourceDirName":"meta","slug":"/meta/contributing","permalink":"/tools/staticdocs/docs/meta/contributing","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/meta/contributing.md","tags":[],"version":"current","frontMatter":{"title":"Contributing","description":"Contributing to COSMOS using the github workflow","sidebar_custom_props":{"myEmoji":"\uD83D\uDE42"}},"sidebar":"defaultSidebar","previous":{"title":"Meta","permalink":"/tools/staticdocs/docs/meta"},"next":{"title":"Licenses","permalink":"/tools/staticdocs/docs/meta/licenses"}}'),i=t("2322"),s=t("2840");let r={title:"Contributing",description:"Contributing to COSMOS using the github workflow",sidebar_custom_props:{myEmoji:"\uD83D\uDE42"}},c=void 0,l={},a=[{value:"Test Dependencies",id:"test-dependencies",level:2},{value:"Workflow",id:"workflow",level:2}];function d(e){let n={a:"a",admonition:"admonition",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"So you've got an awesome idea to throw into COSMOS. Great! This is the basic process:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Fork the project on Github"}),"\n",(0,i.jsx)(n.li,{children:"Create a feature branch"}),"\n",(0,i.jsx)(n.li,{children:"Make your changes"}),"\n",(0,i.jsx)(n.li,{children:"Submit a pull request"}),"\n"]}),"\n",(0,i.jsxs)(n.admonition,{title:"Don't Forget the Contributor License Agreement!",type:"note",children:[(0,i.jsxs)(n.p,{children:["By contributing to this project, you accept our Contributor License Agreement which is found here: ",(0,i.jsx)(n.a,{href:"https://github.com/OpenC3/cosmos/blob/main/CONTRIBUTING.txt",children:"Contributor License Agreement"})]}),(0,i.jsx)(n.p,{children:"This protects both you and us and you retain full rights to any code you write."})]}),"\n",(0,i.jsx)(n.h2,{id:"test-dependencies",children:"Test Dependencies"}),"\n",(0,i.jsxs)(n.p,{children:["To run the test suite and build the gem you'll need to install COSMOS's\ndependencies. COSMOS uses Bundler, so a quick run of the ",(0,i.jsx)(n.code,{children:"bundle"})," command and\nyou're all set!"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\\$ bundle\n"})}),"\n",(0,i.jsx)(n.p,{children:"Before you start, run the tests and make sure that they pass (to confirm your\nenvironment is configured properly):"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\\$ bundle exec rake build spec\n"})}),"\n",(0,i.jsx)(n.h2,{id:"workflow",children:"Workflow"}),"\n",(0,i.jsx)(n.p,{children:"Here's the most direct way to get your work merged into the project:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Fork the project."}),"\n",(0,i.jsx)(n.li,{children:"Clone down your fork:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git clone git://github.com/<username>/openc3.git\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Create a topic branch to contain your change:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git checkout -b my_awesome_feature\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Hack away, add tests. Not necessarily in that order."}),"\n",(0,i.jsxs)(n.li,{children:["Make sure everything still passes by running ",(0,i.jsx)(n.code,{children:"bundle exec rake"}),"."]}),"\n",(0,i.jsx)(n.li,{children:"If necessary, rebase your commits into logical chunks, without errors."}),"\n",(0,i.jsx)(n.li,{children:"Push the branch up:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git push origin my_awesome_feature\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create a pull request against openc3/cosmos",":main"," and describe what your\nchange does and the why you think it should be merged."]}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{title:"Find a problem in the code or documentation?",type:"note",children:(0,i.jsxs)(n.p,{children:["Please ",(0,i.jsx)(n.a,{href:"https://github.com/OpenC3/cosmos/issues/new/choose",children:"create an issue"})," on\nGitHub describing what we can do to make it better."]})})]})}function u(e={}){let{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},2840:function(e,n,t){t.d(n,{Z:function(){return c},a:function(){return r}});var o=t(2784);let i={},s=o.createContext(i);function r(e){let n=o.useContext(s);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]);
1
+ "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["7810"],{8220:function(e,n,t){t.r(n),t.d(n,{default:()=>u,frontMatter:()=>r,metadata:()=>o,assets:()=>l,toc:()=>a,contentTitle:()=>c});var o=JSON.parse('{"id":"meta/contributing","title":"Contributing","description":"Contributing to COSMOS using the github workflow","source":"@site/docs/meta/contributing.md","sourceDirName":"meta","slug":"/meta/contributing","permalink":"/tools/staticdocs/docs/meta/contributing","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/meta/contributing.md","tags":[],"version":"current","frontMatter":{"title":"Contributing","description":"Contributing to COSMOS using the github workflow","sidebar_custom_props":{"myEmoji":"\uD83D\uDE42"}},"sidebar":"defaultSidebar","previous":{"title":"Meta","permalink":"/tools/staticdocs/docs/meta"},"next":{"title":"Licenses","permalink":"/tools/staticdocs/docs/meta/licenses"}}'),i=t("2322"),s=t("2840");let r={title:"Contributing",description:"Contributing to COSMOS using the github workflow",sidebar_custom_props:{myEmoji:"\uD83D\uDE42"}},c=void 0,l={},a=[{value:"Test Dependencies",id:"test-dependencies",level:2},{value:"Workflow",id:"workflow",level:2}];function d(e){let n={a:"a",admonition:"admonition",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"So you've got an awesome idea to throw into COSMOS. Great! This is the basic process:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Fork the project on Github"}),"\n",(0,i.jsx)(n.li,{children:"Create a feature branch"}),"\n",(0,i.jsx)(n.li,{children:"Make your changes"}),"\n",(0,i.jsx)(n.li,{children:"Submit a pull request"}),"\n"]}),"\n",(0,i.jsxs)(n.admonition,{title:"Don't Forget the Contributor License Agreement!",type:"note",children:[(0,i.jsxs)(n.p,{children:["By contributing to this project, you accept our Contributor License Agreement which is found here: ",(0,i.jsx)(n.a,{href:"https://github.com/OpenC3/cosmos/blob/main/CONTRIBUTING.txt",children:"Contributor License Agreement"})]}),(0,i.jsx)(n.p,{children:"This protects both you and us and you retain full rights to any code you write."})]}),"\n",(0,i.jsx)(n.h2,{id:"test-dependencies",children:"Test Dependencies"}),"\n",(0,i.jsxs)(n.p,{children:["To run the test suite and build the gem you'll need to install COSMOS's\ndependencies. COSMOS uses Bundler, so a quick run of the ",(0,i.jsx)(n.code,{children:"bundle"})," command and\nyou're all set!"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\\$ bundle\n"})}),"\n",(0,i.jsx)(n.p,{children:"Before you start, run the tests and make sure that they pass (to confirm your\nenvironment is configured properly):"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\\$ bundle exec rake build spec\n"})}),"\n",(0,i.jsx)(n.h2,{id:"workflow",children:"Workflow"}),"\n",(0,i.jsx)(n.p,{children:"Here's the most direct way to get your work merged into the project:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Fork the project."}),"\n",(0,i.jsx)(n.li,{children:"Clone down your fork:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git clone git://github.com/<username>/openc3.git\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Create a topic branch to contain your change:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git checkout -b my_awesome_feature\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Hack away, add tests. Not necessarily in that order."}),"\n",(0,i.jsxs)(n.li,{children:["Make sure everything still passes by running ",(0,i.jsx)(n.code,{children:"bundle exec rake"}),"."]}),"\n",(0,i.jsx)(n.li,{children:"If necessary, rebase your commits into logical chunks, without errors."}),"\n",(0,i.jsx)(n.li,{children:"Push the branch up:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git push origin my_awesome_feature\n"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create a pull request against openc3/cosmos",":main"," and describe what your\nchange does and the why you think it should be merged."]}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{title:"Find a problem in the code or documentation?",type:"note",children:(0,i.jsxs)(n.p,{children:["Please ",(0,i.jsx)(n.a,{href:"https://github.com/OpenC3/cosmos/issues/new/choose",children:"create an issue"})," on\nGitHub describing what we can do to make it better."]})})]})}function u(e={}){let{wrapper:n}={...(0,s.a)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},2840:function(e,n,t){t.d(n,{Z:function(){return c},a:function(){return r}});var o=t(2784);let i={},s=o.createContext(i);function r(e){let n=o.useContext(s);return o.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]);
@@ -1 +1 @@
1
- "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["4593"],{3814:function(e,t,i){i.r(t),i.d(t,{default:()=>c,frontMatter:()=>s,metadata:()=>n,assets:()=>l,toc:()=>h,contentTitle:()=>o});var n=JSON.parse('{"id":"tools/tlm-grapher","title":"Telemetry Grapher","description":"Graph real time or historical data","source":"@site/docs/tools/tlm-grapher.md","sourceDirName":"tools","slug":"/tools/tlm-grapher","permalink":"/tools/staticdocs/docs/tools/tlm-grapher","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/tools/tlm-grapher.md","tags":[],"version":"current","frontMatter":{"title":"Telemetry Grapher","description":"Graph real time or historical data","sidebar_custom_props":{"myEmoji":"\uD83D\uDEE0\uFE0F"}},"sidebar":"defaultSidebar","previous":{"title":"Table Manager","permalink":"/tools/staticdocs/docs/tools/table-manager"},"next":{"title":"Telemetry Viewer","permalink":"/tools/staticdocs/docs/tools/tlm-viewer"}}'),a=i("2322"),r=i("2840");let s={title:"Telemetry Grapher",description:"Graph real time or historical data",sidebar_custom_props:{myEmoji:"\uD83D\uDEE0\uFE0F"}},o=void 0,l={},h=[{value:"Introductions",id:"introductions",level:2},{value:"Telemetry Grapher Menus",id:"telemetry-grapher-menus",level:2},{value:"File Menu Items",id:"file-menu-items",level:3},{value:"Open Configuration",id:"open-configuration",level:4},{value:"Save Configuration",id:"save-configuration",level:4},{value:"Graph Menu Items",id:"graph-menu-items",level:3},{value:"Selecting Items",id:"selecting-items",level:2},{value:"Graph Window Management",id:"graph-window-management",level:2}];function d(e){let t={h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",p:"p",ul:"ul",...(0,r.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h2,{id:"introductions",children:"Introductions"}),"\n",(0,a.jsx)(t.p,{children:"Telemetry Grapher is a graphing application that allows for one or more telemetry points per graph. It supports multiple graphs per screen which can be resized and reordered. Multiple configurations can be saved and restored for different situations."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Telemetry Grapher",src:i(2603).Z+"",width:"1270",height:"927"})}),"\n",(0,a.jsx)(t.h2,{id:"telemetry-grapher-menus",children:"Telemetry Grapher Menus"}),"\n",(0,a.jsx)(t.h3,{id:"file-menu-items",children:"File Menu Items"}),"\n",(0,a.jsx)("img",{src:i(857).Z,alt:"File Menu",style:{float:"left","margin-right":"50px",height:"90px"}}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Open a saved configuration (graphs and items)"}),"\n",(0,a.jsx)(t.li,{children:"Save the current configuration"}),"\n",(0,a.jsx)(t.li,{children:"Reset the configuration (default settings)"}),"\n"]}),"\n",(0,a.jsx)(t.h4,{id:"open-configuration",children:"Open Configuration"}),"\n",(0,a.jsx)(t.p,{children:"The Open Configuration dialog displays a list of all saved configurations. You select a configuration and then click Ok to load it. You can delete existing configurations by clicking the Trash icon next to a configuration name."}),"\n",(0,a.jsx)(t.h4,{id:"save-configuration",children:"Save Configuration"}),"\n",(0,a.jsx)(t.p,{children:"The Save Configuration dialog also displays a list of all saved configurations. You click the Configuration Name text field, enter the name of your new configuration, and click Ok to save. You can delete existing configurations by clicking the Trash icon next to a configuration name."}),"\n",(0,a.jsx)(t.h3,{id:"graph-menu-items",children:"Graph Menu Items"}),"\n",(0,a.jsx)("img",{src:i(9309).Z,alt:"File Menu",style:{float:"left","margin-right":"50px",height:"150px"}}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Add a new graph"}),"\n",(0,a.jsx)(t.li,{children:"Start / Resume graphing"}),"\n",(0,a.jsx)(t.li,{children:"Pause graph"}),"\n",(0,a.jsx)(t.li,{children:"Stop graph"}),"\n",(0,a.jsx)(t.li,{children:"Edit grapher settings"}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Editing the grapher settings brings up a dialog to change settings affecting every graph in the Telemetry Grapher tool. Changing the Seconds Graphed changes the visible windows displaying graph points. The smaller of Seconds Graphed and Points Graphed will be used when calculating the number of points to display. Changing the Points Saved will affect performance of the browser window if set too high. The default of 1,000,000 points can store over 11.5 days of 1Hz data points."}),"\n",(0,a.jsx)(t.p,{children:"Editing an individual graph by clicking the pencil icon in title bar of the graph brings up the edit graph dialog."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Edit Graph",src:i(8422).Z+"",width:"592",height:"766"})}),"\n",(0,a.jsx)(t.p,{children:"Editing the Start Date and Start Time will re-query the data to begin at the specified time. This operation can take several seconds depending on how far back data is requested. Similarly, specifying the End Date and End Time will limit the data request to the specified time. Leaving the End Date / End Time fields blank will cause Telemetry Grapher to continue to graph items in real-time as they arrive."}),"\n",(0,a.jsx)(t.p,{children:"Changing the Min Y and Max Y values simply sets the graph scale. Deleting the Min Y and Max Y values allows the graph to scale automatically as values arrive. Compare the following graph with the minimum set to 0 and the maximum set to 100 with the first graph image (auto-scale)."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Min Max",src:i(7708).Z+"",width:"1247",height:"718"})}),"\n",(0,a.jsx)(t.h2,{id:"selecting-items",children:"Selecting Items"}),"\n",(0,a.jsx)(t.p,{children:"Selecting a target from the Select Target drop down automatically updates the available packets in the Select Packet drop down which updates the available items in the Select Item drop down. Clicking Add Item adds the item to the graph which immediately begins graphing."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Temp 1",src:i(8813).Z+"",width:"1247",height:"829"})}),"\n",(0,a.jsx)(t.p,{children:"As time passes, the main graph fills up and starts scrolling while the overview graph at the bottom shows the entire history."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Temp 1 History",src:i(4854).Z+"",width:"1247",height:"829"})}),"\n",(0,a.jsx)(t.p,{children:"Selecting a new item and adding it to the graph automatically fills the graph with history until the beginning of the first item. This allows you to add items to the graph incrementally and maintain full history."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Temp1 Temp2",src:i(8133).Z+"",width:"1247",height:"829"})}),"\n",(0,a.jsx)(t.h2,{id:"graph-window-management",children:"Graph Window Management"}),"\n",(0,a.jsx)(t.p,{children:"All graphs can be moved around the browser window by clicking their title bar and moving them. Other graphs will move around intelligently to fill the space. This allows you order the graphs no matter which order they were created in."}),"\n",(0,a.jsx)(t.p,{children:"Each graph has a set of window buttons in the upper right corner. The first shrinks or grows the graph both horizontally and vertically to allow for 4 graphs in the same browser tab. Note that half height graphs no longer show the overview graph."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Four Graphs",src:i(3032).Z+"",width:"1247",height:"710"})}),"\n",(0,a.jsx)(t.p,{children:"The second button shrinks or grows the graph horizontally so it will either be half or full width of the browser window. This allows for two full width graphs on top of each other."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Two Full Width",src:i(5813).Z+"",width:"1247",height:"833"})}),"\n",(0,a.jsx)(t.p,{children:"The second button shrinks or grows the graph vertically so it will either be half or full height of the browser window. This allows for two full height graphs side by side."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Two Full Height",src:i(9038).Z+"",width:"1247",height:"833"})}),"\n",(0,a.jsx)(t.p,{children:"The line button minimizes the graph to effectively hide it. This allows you to focus on a single graph without losing existing graphs."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Minimized",src:i(8171).Z+"",width:"1247",height:"833"})}),"\n",(0,a.jsx)(t.p,{children:"The final X button closes the graph."})]})}function c(e={}){let{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},857:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/file_menu-1c05cfc08f9d07b3f7122d2fe1ad98ed428dc563d2c5d2edddbed71f46779eb8.png"},9309:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/graph_menu-289cbbb168622f661c1c98a7bd2c1b43f888e9c3560ba4e1d435ab62d0aad6de.png"},8422:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/edit_graph-9618076f837e0d358ea0bfbf503d43b377805d818370405536f5a1c049209e99.png"},3032:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/four_graphs-1aa5a7cb9ce51cec815fc9d8740b40e113bd171c4977711d47ef1e6daf02719e.png"},7708:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/graph_min_max-75be4a19a7e13a1b9b7a18a9b898b170c8ded7768b01ce6c6effd566ac8e071a.png"},8813:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/graph_temp1-028d8660c779136ff017b0b8a9fadb294e9ff478a65d7bd73032c3c2ed4f03d0.png"},8133:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/graph_temp1_temp2-ad650da0ddf1fb5c6e9764b737bfab3027f5abcb935ad86d9716dfdf13032dca.png"},4854:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/graph_temp1_time-53c18518755d1d1c816db7f0a67e26c5408aba32b644fda519b5ecf7a7ee9b27.png"},8171:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/minimized-47ddb9b9b68b47aae3d0a12cb39ab767adf446acbe213c0b5565c1bfaf8a463f.png"},2603:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/telemetry_grapher-3a37c074a25b7912a76d96fd46a1431d27202d71374f78c829f273e5cb342233.png"},9038:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/two_full_height-ccba2940b80345f3569ea47b7ddd3390c08195de91559f5586f85e36e411afd6.png"},5813:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/two_full_width-0116adbf994500a24d4717e002d32098f8d6197bcece510b84b90400f23feade.png"},2840:function(e,t,i){i.d(t,{Z:function(){return o},a:function(){return s}});var n=i(2784);let a={},r=n.createContext(a);function s(e){let t=n.useContext(r);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]);
1
+ "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["4593"],{1176:function(e,t,i){i.r(t),i.d(t,{default:()=>c,frontMatter:()=>s,metadata:()=>n,assets:()=>l,toc:()=>h,contentTitle:()=>o});var n=JSON.parse('{"id":"tools/tlm-grapher","title":"Telemetry Grapher","description":"Graph real time or historical data","source":"@site/docs/tools/tlm-grapher.md","sourceDirName":"tools","slug":"/tools/tlm-grapher","permalink":"/tools/staticdocs/docs/tools/tlm-grapher","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/tools/tlm-grapher.md","tags":[],"version":"current","frontMatter":{"title":"Telemetry Grapher","description":"Graph real time or historical data","sidebar_custom_props":{"myEmoji":"\uD83D\uDEE0\uFE0F"}},"sidebar":"defaultSidebar","previous":{"title":"Table Manager","permalink":"/tools/staticdocs/docs/tools/table-manager"},"next":{"title":"Telemetry Viewer","permalink":"/tools/staticdocs/docs/tools/tlm-viewer"}}'),a=i("2322"),r=i("2840");let s={title:"Telemetry Grapher",description:"Graph real time or historical data",sidebar_custom_props:{myEmoji:"\uD83D\uDEE0\uFE0F"}},o=void 0,l={},h=[{value:"Introductions",id:"introductions",level:2},{value:"Telemetry Grapher Menus",id:"telemetry-grapher-menus",level:2},{value:"File Menu Items",id:"file-menu-items",level:3},{value:"Open Configuration",id:"open-configuration",level:4},{value:"Save Configuration",id:"save-configuration",level:4},{value:"Graph Menu Items",id:"graph-menu-items",level:3},{value:"Selecting Items",id:"selecting-items",level:2},{value:"Graph Window Management",id:"graph-window-management",level:2}];function d(e){let t={h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",p:"p",ul:"ul",...(0,r.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h2,{id:"introductions",children:"Introductions"}),"\n",(0,a.jsx)(t.p,{children:"Telemetry Grapher is a graphing application that allows for one or more telemetry points per graph. It supports multiple graphs per screen which can be resized and reordered. Multiple configurations can be saved and restored for different situations."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Telemetry Grapher",src:i(2603).Z+"",width:"1270",height:"927"})}),"\n",(0,a.jsx)(t.h2,{id:"telemetry-grapher-menus",children:"Telemetry Grapher Menus"}),"\n",(0,a.jsx)(t.h3,{id:"file-menu-items",children:"File Menu Items"}),"\n",(0,a.jsx)("img",{src:i(857).Z,alt:"File Menu",style:{float:"left","margin-right":"50px",height:"90px"}}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Open a saved configuration (graphs and items)"}),"\n",(0,a.jsx)(t.li,{children:"Save the current configuration"}),"\n",(0,a.jsx)(t.li,{children:"Reset the configuration (default settings)"}),"\n"]}),"\n",(0,a.jsx)(t.h4,{id:"open-configuration",children:"Open Configuration"}),"\n",(0,a.jsx)(t.p,{children:"The Open Configuration dialog displays a list of all saved configurations. You select a configuration and then click Ok to load it. You can delete existing configurations by clicking the Trash icon next to a configuration name."}),"\n",(0,a.jsx)(t.h4,{id:"save-configuration",children:"Save Configuration"}),"\n",(0,a.jsx)(t.p,{children:"The Save Configuration dialog also displays a list of all saved configurations. You click the Configuration Name text field, enter the name of your new configuration, and click Ok to save. You can delete existing configurations by clicking the Trash icon next to a configuration name."}),"\n",(0,a.jsx)(t.h3,{id:"graph-menu-items",children:"Graph Menu Items"}),"\n",(0,a.jsx)("img",{src:i(9309).Z,alt:"File Menu",style:{float:"left","margin-right":"50px",height:"150px"}}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"Add a new graph"}),"\n",(0,a.jsx)(t.li,{children:"Start / Resume graphing"}),"\n",(0,a.jsx)(t.li,{children:"Pause graph"}),"\n",(0,a.jsx)(t.li,{children:"Stop graph"}),"\n",(0,a.jsx)(t.li,{children:"Edit grapher settings"}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Editing the grapher settings brings up a dialog to change settings affecting every graph in the Telemetry Grapher tool. Changing the Seconds Graphed changes the visible windows displaying graph points. The smaller of Seconds Graphed and Points Graphed will be used when calculating the number of points to display. Changing the Points Saved will affect performance of the browser window if set too high. The default of 1,000,000 points can store over 11.5 days of 1Hz data points."}),"\n",(0,a.jsx)(t.p,{children:"Editing an individual graph by clicking the pencil icon in title bar of the graph brings up the edit graph dialog."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Edit Graph",src:i(8422).Z+"",width:"592",height:"766"})}),"\n",(0,a.jsx)(t.p,{children:"Editing the Start Date and Start Time will re-query the data to begin at the specified time. This operation can take several seconds depending on how far back data is requested. Similarly, specifying the End Date and End Time will limit the data request to the specified time. Leaving the End Date / End Time fields blank will cause Telemetry Grapher to continue to graph items in real-time as they arrive."}),"\n",(0,a.jsx)(t.p,{children:"Changing the Min Y and Max Y values simply sets the graph scale. Deleting the Min Y and Max Y values allows the graph to scale automatically as values arrive. Compare the following graph with the minimum set to 0 and the maximum set to 100 with the first graph image (auto-scale)."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Min Max",src:i(7708).Z+"",width:"1247",height:"718"})}),"\n",(0,a.jsx)(t.h2,{id:"selecting-items",children:"Selecting Items"}),"\n",(0,a.jsx)(t.p,{children:"Selecting a target from the Select Target drop down automatically updates the available packets in the Select Packet drop down which updates the available items in the Select Item drop down. Clicking Add Item adds the item to the graph which immediately begins graphing."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Temp 1",src:i(8813).Z+"",width:"1247",height:"829"})}),"\n",(0,a.jsx)(t.p,{children:"As time passes, the main graph fills up and starts scrolling while the overview graph at the bottom shows the entire history."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Temp 1 History",src:i(4854).Z+"",width:"1247",height:"829"})}),"\n",(0,a.jsx)(t.p,{children:"Selecting a new item and adding it to the graph automatically fills the graph with history until the beginning of the first item. This allows you to add items to the graph incrementally and maintain full history."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Temp1 Temp2",src:i(8133).Z+"",width:"1247",height:"829"})}),"\n",(0,a.jsx)(t.h2,{id:"graph-window-management",children:"Graph Window Management"}),"\n",(0,a.jsx)(t.p,{children:"All graphs can be moved around the browser window by clicking their title bar and moving them. Other graphs will move around intelligently to fill the space. This allows you order the graphs no matter which order they were created in."}),"\n",(0,a.jsx)(t.p,{children:"Each graph has a set of window buttons in the upper right corner. The first shrinks or grows the graph both horizontally and vertically to allow for 4 graphs in the same browser tab. Note that half height graphs no longer show the overview graph."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Four Graphs",src:i(3032).Z+"",width:"1247",height:"710"})}),"\n",(0,a.jsx)(t.p,{children:"The second button shrinks or grows the graph horizontally so it will either be half or full width of the browser window. This allows for two full width graphs on top of each other."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Two Full Width",src:i(5813).Z+"",width:"1247",height:"833"})}),"\n",(0,a.jsx)(t.p,{children:"The second button shrinks or grows the graph vertically so it will either be half or full height of the browser window. This allows for two full height graphs side by side."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Two Full Height",src:i(9038).Z+"",width:"1247",height:"833"})}),"\n",(0,a.jsx)(t.p,{children:"The line button minimizes the graph to effectively hide it. This allows you to focus on a single graph without losing existing graphs."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Minimized",src:i(8171).Z+"",width:"1247",height:"833"})}),"\n",(0,a.jsx)(t.p,{children:"The final X button closes the graph."})]})}function c(e={}){let{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},857:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/file_menu-1c05cfc08f9d07b3f7122d2fe1ad98ed428dc563d2c5d2edddbed71f46779eb8.png"},9309:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/graph_menu-289cbbb168622f661c1c98a7bd2c1b43f888e9c3560ba4e1d435ab62d0aad6de.png"},8422:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/edit_graph-9618076f837e0d358ea0bfbf503d43b377805d818370405536f5a1c049209e99.png"},3032:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/four_graphs-1aa5a7cb9ce51cec815fc9d8740b40e113bd171c4977711d47ef1e6daf02719e.png"},7708:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/graph_min_max-75be4a19a7e13a1b9b7a18a9b898b170c8ded7768b01ce6c6effd566ac8e071a.png"},8813:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/graph_temp1-028d8660c779136ff017b0b8a9fadb294e9ff478a65d7bd73032c3c2ed4f03d0.png"},8133:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/graph_temp1_temp2-ad650da0ddf1fb5c6e9764b737bfab3027f5abcb935ad86d9716dfdf13032dca.png"},4854:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/graph_temp1_time-53c18518755d1d1c816db7f0a67e26c5408aba32b644fda519b5ecf7a7ee9b27.png"},8171:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/minimized-47ddb9b9b68b47aae3d0a12cb39ab767adf446acbe213c0b5565c1bfaf8a463f.png"},2603:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/telemetry_grapher-3a37c074a25b7912a76d96fd46a1431d27202d71374f78c829f273e5cb342233.png"},9038:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/two_full_height-ccba2940b80345f3569ea47b7ddd3390c08195de91559f5586f85e36e411afd6.png"},5813:function(e,t,i){i.d(t,{Z:function(){return n}});let n=i.p+"assets/images/two_full_width-0116adbf994500a24d4717e002d32098f8d6197bcece510b84b90400f23feade.png"},2840:function(e,t,i){i.d(t,{Z:function(){return o},a:function(){return s}});var n=i(2784);let a={},r=n.createContext(a);function s(e){let t=n.useContext(r);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]);
@@ -1 +1 @@
1
- "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["602"],{8540:function(e,n,i){i.r(n),i.d(n,{default:()=>d,frontMatter:()=>r,metadata:()=>t,assets:()=>l,toc:()=>a,contentTitle:()=>c});var t=JSON.parse('{"id":"development/curl","title":"Testing with Curl","description":"How to use Curl to hit the COSMOS APIs","source":"@site/docs/development/curl.md","sourceDirName":"development","slug":"/development/curl","permalink":"/tools/staticdocs/docs/development/curl","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/development/curl.md","tags":[],"version":"current","frontMatter":{"title":"Testing with Curl","description":"How to use Curl to hit the COSMOS APIs","sidebar_custom_props":{"myEmoji":"\uD83C\uDF0A"}},"sidebar":"defaultSidebar","previous":{"title":"Development","permalink":"/tools/staticdocs/docs/development"},"next":{"title":"Developing COSMOS","permalink":"/tools/staticdocs/docs/development/developing"}}'),s=i("2322"),o=i("2840");let r={title:"Testing with Curl",description:"How to use Curl to hit the COSMOS APIs",sidebar_custom_props:{myEmoji:"\uD83C\uDF0A"}},c=void 0,l={},a=[{value:"Curl Example with OpenC3 COSMOS Open Source",id:"curl-example-with-openc3-cosmos-open-source",level:2},{value:"Curl Example with OpenC3 COSMOS Enterprise",id:"curl-example-with-openc3-cosmos-enterprise",level:2},{value:"Suite Runner Example",id:"suite-runner-example",level:2}];function p(e){let n={admonition:"admonition",code:"code",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.admonition,{title:"This documentation is for COSMOS Developers",type:"note",children:(0,s.jsx)(n.p,{children:"This information is just generally used behind the scenes in COSMOS tools"})}),"\n",(0,s.jsx)(n.p,{children:"The COSMOS APIs are all served over HTTP, which means you can use curl to experiment with them. Curl is a great tool for seeing exactly how the API responds to any given request."}),"\n",(0,s.jsx)(n.h2,{id:"curl-example-with-openc3-cosmos-open-source",children:"Curl Example with OpenC3 COSMOS Open Source"}),"\n",(0,s.jsx)(n.p,{children:"OpenC3 COSMOS Open Source just has a single user account, so all you need to do is pass the single password as the token with your requests like this."}),"\n",(0,s.jsx)(n.p,{children:"Request:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'curl -i -H "Content-Type: application/json-rpc" -H "Authorization: password" -d \'{"jsonrpc": "2.0", "method": "tlm", "params": ["INST HEALTH_STATUS TEMP1"], "keyword_params": {"scope": "DEFAULT"}, "id": 8}\' -X POST http://127.0.0.1:2900/openc3-api/api\n'})}),"\n",(0,s.jsx)(n.p,{children:"Response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'HTTP/1.1 200 OK\nCache-Control: max-age=0, private, must-revalidate\nContent-Length: 51\nContent-Type: application/json-rpc\nEtag: W/"e806aacfdbed0b325e7a5928e3bb5cf4"\nVary: Origin\nX-Request-Id: bbad6c6b-6d22-4374-a86f-b5b0b95e6939\nX-Runtime: 0.059044\nDate: Sat, 04 Nov 2023 21:34:47 GMT\n\n{"jsonrpc":"2.0","id":8,"result":53.26555000000001}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"curl-example-with-openc3-cosmos-enterprise",children:"Curl Example with OpenC3 COSMOS Enterprise"}),"\n",(0,s.jsx)(n.p,{children:"OpenC3 COSMOS Enterprise uses the Keycloak Single Sign-on system, so you must first request a token from Keycloak using a username and password pair, before you make requests. By default this token will expire in 5 minutes, and will need to be refreshed if it expires before your next request."}),"\n",(0,s.jsx)(n.p,{children:"Keycloak Request:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# Get tokens from Keycloak - You will need to update the username and password with your account\ncurl -i -H \"Content-Type: application/x-www-form-urlencoded\" -d 'username=operator&password=operator&client_id=api&grant_type=password&scope=openid' -X POST http://127.0.0.1:2900/auth/realms/openc3/protocol/openid-connect/token\n"})}),"\n",(0,s.jsx)(n.p,{children:"Keycloak Response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'HTTP/1.1 200 OK\nCache-Control: no-store\nContent-Length: 3207\nContent-Type: application/json\nPragma: no-cache\nReferrer-Policy: no-referrer\nSet-Cookie: KEYCLOAK_LOCALE=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/openc3/; HttpOnly\nSet-Cookie: KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/openc3/; HttpOnly\nStrict-Transport-Security: max-age=31536000; includeSubDomains\nX-Content-Type-Options: nosniff\nX-Frame-Options: SAMEORIGIN\nX-Xss-Protection: 1; mode=block\nDate: Wed, 10 May 2023 00:40:40 GMT\n\n{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0cDlERmpNZGFXMy16WXptdlBqVTZnNTVqMVNhWGhkZHJqU0szQVNvaDhVIn0.eyJleHAiOjE2ODM2Nzk1NDAsImlhdCI6MTY4MzY3OTI0MCwianRpIjoiZmVlOTQwYWYtZDY3Ny00MWUyLWIzNWYtZDI5ODhiM2RhZGQ2IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoyOTAwL2F1dGgvcmVhbG1zL29wZW5jMyIsInN1YiI6ImFjZTFlNmExLTkzMTktNDc2ZS1iZjQzLTZmM2NhYjllZTJkZSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFwaSIsInNlc3Npb25fc3RhdGUiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJhY3IiOiIxIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtb3BlbmMzIiwiQUxMU0NPUEVTX19vcGVyYXRvciIsIm9mZmxpbmVfYWNjZXNzIiwiQUxMU0NPUEVTX192aWV3ZXIiXX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJUaGUgT3BlcmF0b3IiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJvcGVyYXRvciIsImdpdmVuX25hbWUiOiJUaGUiLCJmYW1pbHlfbmFtZSI6Ik9wZXJhdG9yIn0.eSqSeZrmCTahwltz5jsu5r3w6W15T5h0BvIdqKWQBDcnxAcxKuT-Nwziw_ewySSgHeC172CIWJUpHVp8ACDQG-dfW4KkvA6AcGfSF_f8TBH_rZrVQwlvwwzdA_egGKzhZWcnAC8TDjXRxuaWmnOgWT0aaHZAoW8EvwmKp-1IVz2l0B-hqzfC7dkjMrCI1udLfDvDBza9OtuR-FnKGt8h4nYnRzr8pO2jwebPFyZlR00gVsyK-b411XqprpT-qpRObYZwH5womA-8xIiwRZj9dsfQ1TaHGFkp1LNzxcj_r6pfwVO263bohbeU7ImezQdbvGLJ9NHaglzVNroTui4BXA","expires_in":300,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI5NjNlMjJiMS0wZmYwLTRmZjktYTg0Zi1hOGI4MzcxOWFiMDEifQ.eyJleHAiOjE2ODM2ODEwNDAsImlhdCI6MTY4MzY3OTI0MCwianRpIjoiMmQyYjIyNmItNjJkOS00YjRjLWI3YTYtMGEwYjk4MGQyMjMwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoyOTAwL2F1dGgvcmVhbG1zL29wZW5jMyIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6MjkwMC9hdXRoL3JlYWxtcy9vcGVuYzMiLCJzdWIiOiJhY2UxZTZhMS05MzE5LTQ3NmUtYmY0My02ZjNjYWI5ZWUyZGUiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiYXBpIiwic2Vzc2lvbl9zdGF0ZSI6ImYzNzg1OTY3LTJhNDYtNGMxMi1hZDBjLWNmZjdmYzQ3N2RmOSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkifQ.1HlKdxQkaL5tYuHTXsOceLZFmNNLl9BjoA4oUl70x9M","token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0cDlERmpNZGFXMy16WXptdlBqVTZnNTVqMVNhWGhkZHJqU0szQVNvaDhVIn0.eyJleHAiOjE2ODM2Nzk1NDAsImlhdCI6MTY4MzY3OTI0MCwiYXV0aF90aW1lIjowLCJqdGkiOiJhNDJkOTY1ZS1lMzU0LTRiM2QtOTIyYS1hOWE0ZDgwZWYxMTkiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjI5MDAvYXV0aC9yZWFsbXMvb3BlbmMzIiwiYXVkIjoiYXBpIiwic3ViIjoiYWNlMWU2YTEtOTMxOS00NzZlLWJmNDMtNmYzY2FiOWVlMmRlIiwidHlwIjoiSUQiLCJhenAiOiJhcGkiLCJzZXNzaW9uX3N0YXRlIjoiZjM3ODU5NjctMmE0Ni00YzEyLWFkMGMtY2ZmN2ZjNDc3ZGY5IiwiYXRfaGFzaCI6IjNBWE9ISkFKYzFPVldLd2Y0a0Q4TkEiLCJhY3IiOiIxIiwic2lkIjoiZjM3ODU5NjctMmE0Ni00YzEyLWFkMGMtY2ZmN2ZjNDc3ZGY5IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiVGhlIE9wZXJhdG9yIiwicHJlZmVycmVkX3VzZXJuYW1lIjoib3BlcmF0b3IiLCJnaXZlbl9uYW1lIjoiVGhlIiwiZmFtaWx5X25hbWUiOiJPcGVyYXRvciJ9.gdLl6KOKIIAdl6jYEuAXQrGCNvuwLQb3RDnwrHJdqyFXshiwofBiLMFreRsIE-33xXWNBU6pnSLQHPVlQU5Vmzlk0IOfk-b4yNq0dNa1TV1kmnxRl8w1ulTQYVZjdsN-oyLNwe0v3aJcYtbvIA3DP8rgO6bVv0ogkjWtlda6MbkyZN-har8x3raUVSlUPRP2Basy1xSMNNA1jvB-nEM-aubrUZE6r0PjI6PE1hbLPmuPbcX3uuIwXu2-UoXepkB8H7omUuMm-S98aHpRarwszC0mmHD5b_wiXusMVw4xYw8eavFue4zfw-T2IKuTVtxbMTygXIah6iqi4gkpL8Mx1w","not-before-policy":0,"session_state":"f3785967-2a46-4c12-ad0c-cff7fc477df9","scope":"openid profile email"}\n'})}),"\n",(0,s.jsx)(n.p,{children:"COSMOS Request:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'# COSMOS Request now looks like this:\n\ncurl -i -H "Content-Type: application/json-rpc" -H "Authorization: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0cDlERmpNZGFXMy16WXptdlBqVTZnNTVqMVNhWGhkZHJqU0szQVNvaDhVIn0.eyJleHAiOjE2ODM2Nzk1NDAsImlhdCI6MTY4MzY3OTI0MCwianRpIjoiZmVlOTQwYWYtZDY3Ny00MWUyLWIzNWYtZDI5ODhiM2RhZGQ2IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoyOTAwL2F1dGgvcmVhbG1zL29wZW5jMyIsInN1YiI6ImFjZTFlNmExLTkzMTktNDc2ZS1iZjQzLTZmM2NhYjllZTJkZSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFwaSIsInNlc3Npb25fc3RhdGUiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJhY3IiOiIxIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtb3BlbmMzIiwiQUxMU0NPUEVTX19vcGVyYXRvciIsIm9mZmxpbmVfYWNjZXNzIiwiQUxMU0NPUEVTX192aWV3ZXIiXX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJUaGUgT3BlcmF0b3IiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJvcGVyYXRvciIsImdpdmVuX25hbWUiOiJUaGUiLCJmYW1pbHlfbmFtZSI6Ik9wZXJhdG9yIn0.eSqSeZrmCTahwltz5jsu5r3w6W15T5h0BvIdqKWQBDcnxAcxKuT-Nwziw_ewySSgHeC172CIWJUpHVp8ACDQG-dfW4KkvA6AcGfSF_f8TBH_rZrVQwlvwwzdA_egGKzhZWcnAC8TDjXRxuaWmnOgWT0aaHZAoW8EvwmKp-1IVz2l0B-hqzfC7dkjMrCI1udLfDvDBza9OtuR-FnKGt8h4nYnRzr8pO2jwebPFyZlR00gVsyK-b411XqprpT-qpRObYZwH5womA-8xIiwRZj9dsfQ1TaHGFkp1LNzxcj_r6pfwVO263bohbeU7ImezQdbvGLJ9NHaglzVNroTui4BXA" -d \'{"jsonrpc": "2.0", "method": "tlm", "params": ["INST HEALTH_STATUS TEMP1"], "keyword_params": {"scope": "DEFAULT"}, "id": 8}\' -X POST http://127.0.0.1:2900/openc3-api/api\n'})}),"\n",(0,s.jsx)(n.p,{children:"COSMOS Response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'HTTP/1.1 200 OK\nCache-Control: max-age=0, private, must-revalidate\nContent-Type: application/json-rpc\nEtag: W/"1e44c0878528687014e1e60a1cbebdae"\nVary: Origin\nX-Request-Id: 47a8dd26-1348-4693-8df1-5375f60abc6c\nX-Runtime: 0.046477\nDate: Wed, 10 May 2023 00:41:33 GMT\nTransfer-Encoding: chunked\n\n{"jsonrpc":"2.0","id":8,"result":29.204100000000007}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"suite-runner-example",children:"Suite Runner Example"}),"\n",(0,s.jsxs)(n.p,{children:["It can be very useful to run the a suite or script remotely from a continuous testing server. COSMOS' REST API allows for this. To figure out what is required to run a certain task on the web GUI you can open up your browser's developer tools to monitor the network traffic. You will see all the requests and responses required to run a command and you can reformat them yourself to suit your own purposes. Below is an example of running a test script from a Chromium-based browser:\n",(0,s.jsx)(n.img,{src:"https://github.com/OpenC3/cosmos/assets/55999897/df642d42-43e0-47f9-9b52-d42746d9746b",alt:"Network Traffic in browser developer tools"})]}),"\n",(0,s.jsxs)(n.p,{children:['You can see that there are 5 transactions total. To investigate just right-click on the network transaction and click "copy as ',(0,s.jsx)(n.code,{children:"curl"}),'" (depends on the browser). Here is an example of the second one:']}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl 'http://localhost:2900/script-api/scripts/TARGET/procedures/cmd_tlm_test.rb/lock?scope=DEFAULT' \\\n -X 'POST' \\\n -H 'Accept: application/json' \\\n -H 'Accept-Language: en-US,en;q=0.9' \\\n -H 'Authorization: pass' \\\n -H 'Connection: keep-alive' \\\n -H 'Content-Length: 0' \\\n -H 'Origin: http://ascportal:2900' \\\n -H 'Referer: http://localhost:2900/tools/scriptrunner/?file=TARGET%2Fprocedures%2Fcmd_tlm_test.rb' \\\n -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0' \\\n --insecure\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Many of the browser-specific headers are not required. The important thing to notice here is the URL and the request (in this case ",(0,s.jsx)(n.code,{children:"POST"}),"). If we inspect all of these we'll find out what each one does:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Set the script contents","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"this updates any local changes)"}),"\n",(0,s.jsxs)(n.li,{children:["Note that this is a different request to ",(0,s.jsx)(n.code,{children:"GET"})," the script contents. This is done on the page load."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"Lock the script (so other users can't edit it during execution)"}),"\n",(0,s.jsx)(n.li,{children:"Run script (this takes a JSON with options)"}),"\n",(0,s.jsx)(n.li,{children:"Open Websocket for logs"}),"\n",(0,s.jsx)(n.li,{children:"Request Result (this URL is a little different because the results are saved in redis)"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Below is a bash script which does all the above given some options. It requires ",(0,s.jsx)(n.code,{children:"curl"})," for the web requests and ",(0,s.jsx)(n.code,{children:"jq"})," for JSON parsing and formatting. It locks and runs the script, continually checks its status, then requests the result."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'#!/bin/bash\nset -e\nTARGET=${1:-\'TARGET\'}\nSCRIPT=${2:-\'procedures/cmd_tlm_test.rb\'}\nSUITE=${3:-\'TestSuite\'}\nCOSMOS_HOST=\'http://localhost:2900\'\nSCRIPT_API="$COSMOS_HOST/script-api"\nSCRIPT_PATH="scripts/$TARGET/$SCRIPT"\nCURL_ARGS=(\n -H \'Accept: application/json\'\n -H \'Authorization: password\'\n -H \'Accept-Language: en-US,en;q=0.9\'\n -H \'Connection: keep-alive\'\n -H \'Content-Type: application/json\'\n --insecure\n --silent )\n\n# Lock script #\ncurl "$SCRIPT_API/$SCRIPT_PATH/lock?scope=DEFAULT" -X "POST" "${CURL_ARGS[@]}"\n\n# Run script #\nRUN_OPTS=$(cat <<-json\n{\n "environment": [],\n "suiteRunner": {\n "method": "start",\n "suite": "$SUITE",\n "options": [\n "continueAfterError"\n ]\n }\n}\njson\n)\nRUN_OPTS=$(<<<"$RUN_OPTS" jq -rc .)\nID=$(curl "$SCRIPT_API/$SCRIPT_PATH/run?scope=DEFAULT" --data-raw "$RUN_OPTS" "${CURL_ARGS[@]}")\n\necho "Starting Script \'$SCRIPT_PATH\' at $(date) (may take up to 15 minutes)" > /dev/stderr\necho "You can monitor it in Script Runner here: $COSMOS_HOST/tools/scriptrunner/$ID" > /dev/stderr\n# Loop while Script ID is still running #\nwhile true; do\n SCRIPT_STATUS="$(curl "$SCRIPT_API/running-script?scope=DEFAULT" "${CURL_ARGS[@]}" | jq ".[]|select(.id==$ID)")"\n if [[ -z $SCRIPT_STATUS ]]; then\n break;\n fi\n sleep 2\ndone\n\n# Request results #\nBUCKET_FILE_URI="$(curl "$SCRIPT_API/completed-scripts?scope=DEFAULT" "${CURL_ARGS[@]}" |\\\n jq \'[.[]|select(.name | test("\'"${SCRIPT_PATH#scripts/}"\' "))][0] | .log | @uri\' -r)"\n\nURL="$(curl "$COSMOS_HOST/openc3-api/storage/download/$BUCKET_FILE_URI?bucket=OPENC3_LOGS_BUCKET&scope=DEFAULT" "${CURL_ARGS[@]}" |jq .url -r)"\n\ncurl "$COSMOS_HOST$URL" "${CURL_ARGS[@]}"\n'})})]})}function d(e={}){let{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},2840:function(e,n,i){i.d(n,{Z:function(){return c},a:function(){return r}});var t=i(2784);let s={},o=t.createContext(s);function r(e){let n=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);
1
+ "use strict";(self.webpackChunkdocs_openc3_com=self.webpackChunkdocs_openc3_com||[]).push([["602"],{8747:function(e,n,i){i.r(n),i.d(n,{default:()=>d,frontMatter:()=>r,metadata:()=>t,assets:()=>l,toc:()=>a,contentTitle:()=>c});var t=JSON.parse('{"id":"development/curl","title":"Testing with Curl","description":"How to use Curl to hit the COSMOS APIs","source":"@site/docs/development/curl.md","sourceDirName":"development","slug":"/development/curl","permalink":"/tools/staticdocs/docs/development/curl","draft":false,"unlisted":false,"editUrl":"https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/development/curl.md","tags":[],"version":"current","frontMatter":{"title":"Testing with Curl","description":"How to use Curl to hit the COSMOS APIs","sidebar_custom_props":{"myEmoji":"\uD83C\uDF0A"}},"sidebar":"defaultSidebar","previous":{"title":"Development","permalink":"/tools/staticdocs/docs/development"},"next":{"title":"Developing COSMOS","permalink":"/tools/staticdocs/docs/development/developing"}}'),s=i("2322"),o=i("2840");let r={title:"Testing with Curl",description:"How to use Curl to hit the COSMOS APIs",sidebar_custom_props:{myEmoji:"\uD83C\uDF0A"}},c=void 0,l={},a=[{value:"Curl Example with OpenC3 COSMOS Open Source",id:"curl-example-with-openc3-cosmos-open-source",level:2},{value:"Curl Example with OpenC3 COSMOS Enterprise",id:"curl-example-with-openc3-cosmos-enterprise",level:2},{value:"Suite Runner Example",id:"suite-runner-example",level:2}];function p(e){let n={admonition:"admonition",code:"code",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,o.a)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.admonition,{title:"This documentation is for COSMOS Developers",type:"note",children:(0,s.jsx)(n.p,{children:"This information is just generally used behind the scenes in COSMOS tools"})}),"\n",(0,s.jsx)(n.p,{children:"The COSMOS APIs are all served over HTTP, which means you can use curl to experiment with them. Curl is a great tool for seeing exactly how the API responds to any given request."}),"\n",(0,s.jsx)(n.h2,{id:"curl-example-with-openc3-cosmos-open-source",children:"Curl Example with OpenC3 COSMOS Open Source"}),"\n",(0,s.jsx)(n.p,{children:"OpenC3 COSMOS Open Source just has a single user account, so all you need to do is pass the single password as the token with your requests like this."}),"\n",(0,s.jsx)(n.p,{children:"Request:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'curl -i -H "Content-Type: application/json-rpc" -H "Authorization: password" -d \'{"jsonrpc": "2.0", "method": "tlm", "params": ["INST HEALTH_STATUS TEMP1"], "keyword_params": {"scope": "DEFAULT"}, "id": 8}\' -X POST http://127.0.0.1:2900/openc3-api/api\n'})}),"\n",(0,s.jsx)(n.p,{children:"Response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'HTTP/1.1 200 OK\nCache-Control: max-age=0, private, must-revalidate\nContent-Length: 51\nContent-Type: application/json-rpc\nEtag: W/"e806aacfdbed0b325e7a5928e3bb5cf4"\nVary: Origin\nX-Request-Id: bbad6c6b-6d22-4374-a86f-b5b0b95e6939\nX-Runtime: 0.059044\nDate: Sat, 04 Nov 2023 21:34:47 GMT\n\n{"jsonrpc":"2.0","id":8,"result":53.26555000000001}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"curl-example-with-openc3-cosmos-enterprise",children:"Curl Example with OpenC3 COSMOS Enterprise"}),"\n",(0,s.jsx)(n.p,{children:"OpenC3 COSMOS Enterprise uses the Keycloak Single Sign-on system, so you must first request a token from Keycloak using a username and password pair, before you make requests. By default this token will expire in 5 minutes, and will need to be refreshed if it expires before your next request."}),"\n",(0,s.jsx)(n.p,{children:"Keycloak Request:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"# Get tokens from Keycloak - You will need to update the username and password with your account\ncurl -i -H \"Content-Type: application/x-www-form-urlencoded\" -d 'username=operator&password=operator&client_id=api&grant_type=password&scope=openid' -X POST http://127.0.0.1:2900/auth/realms/openc3/protocol/openid-connect/token\n"})}),"\n",(0,s.jsx)(n.p,{children:"Keycloak Response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'HTTP/1.1 200 OK\nCache-Control: no-store\nContent-Length: 3207\nContent-Type: application/json\nPragma: no-cache\nReferrer-Policy: no-referrer\nSet-Cookie: KEYCLOAK_LOCALE=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/openc3/; HttpOnly\nSet-Cookie: KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0; Path=/auth/realms/openc3/; HttpOnly\nStrict-Transport-Security: max-age=31536000; includeSubDomains\nX-Content-Type-Options: nosniff\nX-Frame-Options: SAMEORIGIN\nX-Xss-Protection: 1; mode=block\nDate: Wed, 10 May 2023 00:40:40 GMT\n\n{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0cDlERmpNZGFXMy16WXptdlBqVTZnNTVqMVNhWGhkZHJqU0szQVNvaDhVIn0.eyJleHAiOjE2ODM2Nzk1NDAsImlhdCI6MTY4MzY3OTI0MCwianRpIjoiZmVlOTQwYWYtZDY3Ny00MWUyLWIzNWYtZDI5ODhiM2RhZGQ2IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoyOTAwL2F1dGgvcmVhbG1zL29wZW5jMyIsInN1YiI6ImFjZTFlNmExLTkzMTktNDc2ZS1iZjQzLTZmM2NhYjllZTJkZSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFwaSIsInNlc3Npb25fc3RhdGUiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJhY3IiOiIxIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtb3BlbmMzIiwiQUxMU0NPUEVTX19vcGVyYXRvciIsIm9mZmxpbmVfYWNjZXNzIiwiQUxMU0NPUEVTX192aWV3ZXIiXX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJUaGUgT3BlcmF0b3IiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJvcGVyYXRvciIsImdpdmVuX25hbWUiOiJUaGUiLCJmYW1pbHlfbmFtZSI6Ik9wZXJhdG9yIn0.eSqSeZrmCTahwltz5jsu5r3w6W15T5h0BvIdqKWQBDcnxAcxKuT-Nwziw_ewySSgHeC172CIWJUpHVp8ACDQG-dfW4KkvA6AcGfSF_f8TBH_rZrVQwlvwwzdA_egGKzhZWcnAC8TDjXRxuaWmnOgWT0aaHZAoW8EvwmKp-1IVz2l0B-hqzfC7dkjMrCI1udLfDvDBza9OtuR-FnKGt8h4nYnRzr8pO2jwebPFyZlR00gVsyK-b411XqprpT-qpRObYZwH5womA-8xIiwRZj9dsfQ1TaHGFkp1LNzxcj_r6pfwVO263bohbeU7ImezQdbvGLJ9NHaglzVNroTui4BXA","expires_in":300,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI5NjNlMjJiMS0wZmYwLTRmZjktYTg0Zi1hOGI4MzcxOWFiMDEifQ.eyJleHAiOjE2ODM2ODEwNDAsImlhdCI6MTY4MzY3OTI0MCwianRpIjoiMmQyYjIyNmItNjJkOS00YjRjLWI3YTYtMGEwYjk4MGQyMjMwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoyOTAwL2F1dGgvcmVhbG1zL29wZW5jMyIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6MjkwMC9hdXRoL3JlYWxtcy9vcGVuYzMiLCJzdWIiOiJhY2UxZTZhMS05MzE5LTQ3NmUtYmY0My02ZjNjYWI5ZWUyZGUiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiYXBpIiwic2Vzc2lvbl9zdGF0ZSI6ImYzNzg1OTY3LTJhNDYtNGMxMi1hZDBjLWNmZjdmYzQ3N2RmOSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkifQ.1HlKdxQkaL5tYuHTXsOceLZFmNNLl9BjoA4oUl70x9M","token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0cDlERmpNZGFXMy16WXptdlBqVTZnNTVqMVNhWGhkZHJqU0szQVNvaDhVIn0.eyJleHAiOjE2ODM2Nzk1NDAsImlhdCI6MTY4MzY3OTI0MCwiYXV0aF90aW1lIjowLCJqdGkiOiJhNDJkOTY1ZS1lMzU0LTRiM2QtOTIyYS1hOWE0ZDgwZWYxMTkiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjI5MDAvYXV0aC9yZWFsbXMvb3BlbmMzIiwiYXVkIjoiYXBpIiwic3ViIjoiYWNlMWU2YTEtOTMxOS00NzZlLWJmNDMtNmYzY2FiOWVlMmRlIiwidHlwIjoiSUQiLCJhenAiOiJhcGkiLCJzZXNzaW9uX3N0YXRlIjoiZjM3ODU5NjctMmE0Ni00YzEyLWFkMGMtY2ZmN2ZjNDc3ZGY5IiwiYXRfaGFzaCI6IjNBWE9ISkFKYzFPVldLd2Y0a0Q4TkEiLCJhY3IiOiIxIiwic2lkIjoiZjM3ODU5NjctMmE0Ni00YzEyLWFkMGMtY2ZmN2ZjNDc3ZGY5IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiVGhlIE9wZXJhdG9yIiwicHJlZmVycmVkX3VzZXJuYW1lIjoib3BlcmF0b3IiLCJnaXZlbl9uYW1lIjoiVGhlIiwiZmFtaWx5X25hbWUiOiJPcGVyYXRvciJ9.gdLl6KOKIIAdl6jYEuAXQrGCNvuwLQb3RDnwrHJdqyFXshiwofBiLMFreRsIE-33xXWNBU6pnSLQHPVlQU5Vmzlk0IOfk-b4yNq0dNa1TV1kmnxRl8w1ulTQYVZjdsN-oyLNwe0v3aJcYtbvIA3DP8rgO6bVv0ogkjWtlda6MbkyZN-har8x3raUVSlUPRP2Basy1xSMNNA1jvB-nEM-aubrUZE6r0PjI6PE1hbLPmuPbcX3uuIwXu2-UoXepkB8H7omUuMm-S98aHpRarwszC0mmHD5b_wiXusMVw4xYw8eavFue4zfw-T2IKuTVtxbMTygXIah6iqi4gkpL8Mx1w","not-before-policy":0,"session_state":"f3785967-2a46-4c12-ad0c-cff7fc477df9","scope":"openid profile email"}\n'})}),"\n",(0,s.jsx)(n.p,{children:"COSMOS Request:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'# COSMOS Request now looks like this:\n\ncurl -i -H "Content-Type: application/json-rpc" -H "Authorization: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0cDlERmpNZGFXMy16WXptdlBqVTZnNTVqMVNhWGhkZHJqU0szQVNvaDhVIn0.eyJleHAiOjE2ODM2Nzk1NDAsImlhdCI6MTY4MzY3OTI0MCwianRpIjoiZmVlOTQwYWYtZDY3Ny00MWUyLWIzNWYtZDI5ODhiM2RhZGQ2IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDoyOTAwL2F1dGgvcmVhbG1zL29wZW5jMyIsInN1YiI6ImFjZTFlNmExLTkzMTktNDc2ZS1iZjQzLTZmM2NhYjllZTJkZSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFwaSIsInNlc3Npb25fc3RhdGUiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJhY3IiOiIxIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtb3BlbmMzIiwiQUxMU0NPUEVTX19vcGVyYXRvciIsIm9mZmxpbmVfYWNjZXNzIiwiQUxMU0NPUEVTX192aWV3ZXIiXX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJzaWQiOiJmMzc4NTk2Ny0yYTQ2LTRjMTItYWQwYy1jZmY3ZmM0NzdkZjkiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJUaGUgT3BlcmF0b3IiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJvcGVyYXRvciIsImdpdmVuX25hbWUiOiJUaGUiLCJmYW1pbHlfbmFtZSI6Ik9wZXJhdG9yIn0.eSqSeZrmCTahwltz5jsu5r3w6W15T5h0BvIdqKWQBDcnxAcxKuT-Nwziw_ewySSgHeC172CIWJUpHVp8ACDQG-dfW4KkvA6AcGfSF_f8TBH_rZrVQwlvwwzdA_egGKzhZWcnAC8TDjXRxuaWmnOgWT0aaHZAoW8EvwmKp-1IVz2l0B-hqzfC7dkjMrCI1udLfDvDBza9OtuR-FnKGt8h4nYnRzr8pO2jwebPFyZlR00gVsyK-b411XqprpT-qpRObYZwH5womA-8xIiwRZj9dsfQ1TaHGFkp1LNzxcj_r6pfwVO263bohbeU7ImezQdbvGLJ9NHaglzVNroTui4BXA" -d \'{"jsonrpc": "2.0", "method": "tlm", "params": ["INST HEALTH_STATUS TEMP1"], "keyword_params": {"scope": "DEFAULT"}, "id": 8}\' -X POST http://127.0.0.1:2900/openc3-api/api\n'})}),"\n",(0,s.jsx)(n.p,{children:"COSMOS Response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'HTTP/1.1 200 OK\nCache-Control: max-age=0, private, must-revalidate\nContent-Type: application/json-rpc\nEtag: W/"1e44c0878528687014e1e60a1cbebdae"\nVary: Origin\nX-Request-Id: 47a8dd26-1348-4693-8df1-5375f60abc6c\nX-Runtime: 0.046477\nDate: Wed, 10 May 2023 00:41:33 GMT\nTransfer-Encoding: chunked\n\n{"jsonrpc":"2.0","id":8,"result":29.204100000000007}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"suite-runner-example",children:"Suite Runner Example"}),"\n",(0,s.jsxs)(n.p,{children:["It can be very useful to run the a suite or script remotely from a continuous testing server. COSMOS' REST API allows for this. To figure out what is required to run a certain task on the web GUI you can open up your browser's developer tools to monitor the network traffic. You will see all the requests and responses required to run a command and you can reformat them yourself to suit your own purposes. Below is an example of running a test script from a Chromium-based browser:\n",(0,s.jsx)(n.img,{src:"https://github.com/OpenC3/cosmos/assets/55999897/df642d42-43e0-47f9-9b52-d42746d9746b",alt:"Network Traffic in browser developer tools"})]}),"\n",(0,s.jsxs)(n.p,{children:['You can see that there are 5 transactions total. To investigate just right-click on the network transaction and click "copy as ',(0,s.jsx)(n.code,{children:"curl"}),'" (depends on the browser). Here is an example of the second one:']}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl 'http://localhost:2900/script-api/scripts/TARGET/procedures/cmd_tlm_test.rb/lock?scope=DEFAULT' \\\n -X 'POST' \\\n -H 'Accept: application/json' \\\n -H 'Accept-Language: en-US,en;q=0.9' \\\n -H 'Authorization: pass' \\\n -H 'Connection: keep-alive' \\\n -H 'Content-Length: 0' \\\n -H 'Origin: http://ascportal:2900' \\\n -H 'Referer: http://localhost:2900/tools/scriptrunner/?file=TARGET%2Fprocedures%2Fcmd_tlm_test.rb' \\\n -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0' \\\n --insecure\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Many of the browser-specific headers are not required. The important thing to notice here is the URL and the request (in this case ",(0,s.jsx)(n.code,{children:"POST"}),"). If we inspect all of these we'll find out what each one does:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Set the script contents","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"this updates any local changes)"}),"\n",(0,s.jsxs)(n.li,{children:["Note that this is a different request to ",(0,s.jsx)(n.code,{children:"GET"})," the script contents. This is done on the page load."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.li,{children:"Lock the script (so other users can't edit it during execution)"}),"\n",(0,s.jsx)(n.li,{children:"Run script (this takes a JSON with options)"}),"\n",(0,s.jsx)(n.li,{children:"Open Websocket for logs"}),"\n",(0,s.jsx)(n.li,{children:"Request Result (this URL is a little different because the results are saved in redis)"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Below is a bash script which does all the above given some options. It requires ",(0,s.jsx)(n.code,{children:"curl"})," for the web requests and ",(0,s.jsx)(n.code,{children:"jq"})," for JSON parsing and formatting. It locks and runs the script, continually checks its status, then requests the result."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'#!/bin/bash\nset -e\nTARGET=${1:-\'TARGET\'}\nSCRIPT=${2:-\'procedures/cmd_tlm_test.rb\'}\nSUITE=${3:-\'TestSuite\'}\nCOSMOS_HOST=\'http://localhost:2900\'\nSCRIPT_API="$COSMOS_HOST/script-api"\nSCRIPT_PATH="scripts/$TARGET/$SCRIPT"\nCURL_ARGS=(\n -H \'Accept: application/json\'\n -H \'Authorization: password\'\n -H \'Accept-Language: en-US,en;q=0.9\'\n -H \'Connection: keep-alive\'\n -H \'Content-Type: application/json\'\n --insecure\n --silent )\n\n# Lock script #\ncurl "$SCRIPT_API/$SCRIPT_PATH/lock?scope=DEFAULT" -X "POST" "${CURL_ARGS[@]}"\n\n# Run script #\nRUN_OPTS=$(cat <<-json\n{\n "environment": [],\n "suiteRunner": {\n "method": "start",\n "suite": "$SUITE",\n "options": [\n "continueAfterError"\n ]\n }\n}\njson\n)\nRUN_OPTS=$(<<<"$RUN_OPTS" jq -rc .)\nID=$(curl "$SCRIPT_API/$SCRIPT_PATH/run?scope=DEFAULT" --data-raw "$RUN_OPTS" "${CURL_ARGS[@]}")\n\necho "Starting Script \'$SCRIPT_PATH\' at $(date) (may take up to 15 minutes)" > /dev/stderr\necho "You can monitor it in Script Runner here: $COSMOS_HOST/tools/scriptrunner/$ID" > /dev/stderr\n# Loop while Script ID is still running #\nwhile true; do\n SCRIPT_STATUS="$(curl "$SCRIPT_API/running-script?scope=DEFAULT" "${CURL_ARGS[@]}" | jq ".[]|select(.id==$ID)")"\n if [[ -z $SCRIPT_STATUS ]]; then\n break;\n fi\n sleep 2\ndone\n\n# Request results #\nBUCKET_FILE_URI="$(curl "$SCRIPT_API/completed-scripts?scope=DEFAULT" "${CURL_ARGS[@]}" |\\\n jq \'[.[]|select(.name | test("\'"${SCRIPT_PATH#scripts/}"\' "))][0] | .log | @uri\' -r)"\n\nURL="$(curl "$COSMOS_HOST/openc3-api/storage/download/$BUCKET_FILE_URI?bucket=OPENC3_LOGS_BUCKET&scope=DEFAULT" "${CURL_ARGS[@]}" |jq .url -r)"\n\ncurl "$COSMOS_HOST$URL" "${CURL_ARGS[@]}"\n'})})]})}function d(e={}){let{wrapper:n}={...(0,o.a)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},2840:function(e,n,i){i.d(n,{Z:function(){return c},a:function(){return r}});var t=i(2784);let s={},o=t.createContext(s);function r(e){let n=t.useContext(o);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);