Typica is a free program for professional coffee roasters. https://typica.us
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

externalroaster.xml 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <window id="basicWindow">
  2. <layout type="vertical">
  3. <splitter type = "vertical" id = "main">
  4. <splitter type = "horizontal" id = "indicators">
  5. <decoration name="Bean Temperature" type="vertical">
  6. <lcdtemperature id = "beans" />
  7. </decoration>
  8. <decoration name="Air Temperature" type="vertical">
  9. <lcdtemperature id = "environment" />
  10. </decoration>
  11. <decoration name="Batch Timer" type="vertical">
  12. <lcdtimer format="mm:ss" id="batch" />
  13. </decoration>
  14. </splitter>
  15. <widget id="widget">
  16. <layout type="horizontal">
  17. <button name="Start Batch" type="push" id="startbutton" />
  18. <button name="Stop Batch" type="annotation" id="stopbutton" series="1" column="3" annotation="End" />
  19. <spinbox id="manometer" series="1" column="3" min="0" max="10" step="0.1" decimals="1" />
  20. <button name="New Sample" type="annotation" id="sample" series="1" column="3" annotation="Sample %1" />
  21. </layout>
  22. </widget>
  23. <splitter type="horizontal" id="logsplit">
  24. <measurementtable id="log">
  25. <column>Time</column>
  26. <column>Bean</column>
  27. <column>Air</column>
  28. <column>Note</column>
  29. <column>.</column>
  30. <column>.</column>
  31. <column>.</column>
  32. </measurementtable>
  33. <graph id="graph" />
  34. </splitter>
  35. </splitter>
  36. </layout>
  37. <menu name="File">
  38. <item id="open" shortcut="Ctrl+O">Open…</item>
  39. <item id="save" shortcut="Ctrl+S">Save…</item>
  40. <item id="export">Export CSV…</item>
  41. <item id="quit" shortcut="Ctrl+Q">Quit</item>
  42. </menu>
  43. <menu name="Batch">
  44. <item id="new" shortcut="Ctrl+N">New Batch…</item>
  45. </menu>
  46. <menu name="Log">
  47. <item id="clear" shortcut="Ctrl+L">Clear Log</item>
  48. <separator />
  49. <item id="ms">Millisecond View</item>
  50. <item id="1s">1 Second View</item>
  51. <item id="5s">5 Second View</item>
  52. <item id="10s">10 Second View</item>
  53. <item id="15s">15 Second View</item>
  54. <item id="30s">30 Second View</item>
  55. <item id="1m">1 Minute View</item>
  56. <separator />
  57. <item id="manual" shortcut="Ctrl+E">Manual Entry</item>
  58. </menu>
  59. <program>
  60. lc = 1;
  61. this.restoreSizeAndPosition('window');
  62. var vsplit = findChildObject(this, 'main');
  63. vsplit.restoreState("script/mainSplitter");
  64. var isplit = findChildObject(this, 'indicators');
  65. isplit.restoreState("script/instrumentSplitter");
  66. var lsplit = findChildObject(this, 'logsplit');
  67. lsplit.restoreState("script/logSplitter");
  68. var log = findChildObject(this, 'log');
  69. this.show();
  70. log.restoreState("script/log", 7);
  71. var window = this;
  72. this.aboutToClose.connect(function() {
  73. window.saveSizeAndPosition("window");
  74. vsplit.saveState("script/mainSplitter");
  75. isplit.saveState("script/instrumentSplitter");
  76. lsplit.saveState("script/logSplitter");
  77. log.saveState("script/log", 7);
  78. loggingWindow = undefined;
  79. });
  80. vsplit.restoreState("script/mainSplitter");
  81. isplit.restoreState("script/instrumentSplitter");
  82. lsplit.restoreState("script/logSplitter");
  83. var device = new DAQ('Dev1');
  84. var bchannel = device.newChannel(DAQ.Fahrenheit, DAQ.TypeJ);
  85. var achannel = device.newChannel(DAQ.Fahrenheit, DAQ.TypeJ);
  86. device.setClockRate(2.0);
  87. device.start();
  88. beanDisplay = findChildObject(this, 'beans');
  89. envDisplay = findChildObject(this, 'environment');
  90. bchannel.newData.connect(beanDisplay.setValue);
  91. achannel.newData.connect(envDisplay.setValue);
  92. var epoch = new QTime;
  93. epoch = epoch.currentTime;
  94. var boffset = new MeasurementTimeOffset(epoch);
  95. var aoffset = new MeasurementTimeOffset(epoch);
  96. badapt = new MeasurementAdapter(1);
  97. aadapt = new MeasurementAdapter(2);
  98. bzero = new ZeroEmitter(1);
  99. azero = new ZeroEmitter(2);
  100. bchannel.newData.connect(boffset.newMeasurement);
  101. achannel.newData.connect(aoffset.newMeasurement);
  102. boffset.measurement.connect(badapt.newMeasurement);
  103. aoffset.measurement.connect(aadapt.newMeasurement);
  104. bchannel.newData.connect(bzero.newMeasurement);
  105. achannel.newData.connect(azero.newMeasurement);
  106. var graph = findChildObject(this, 'graph');
  107. bzero.measurement.connect(log.newMeasurement);
  108. bzero.measurement.connect(graph.newMeasurement);
  109. azero.measurement.connect(log.newMeasurement);
  110. azero.measurement.connect(graph.newMeasurement);
  111. var timer = findChildObject(this, 'batch');
  112. timer.autoReset = true;
  113. var start = findChildObject(this, 'startbutton');
  114. start.clicked.connect(function() {
  115. var epoch = new QTime();
  116. epoch = epoch.currentTime();
  117. timer.startTimer();
  118. boffset.setZeroTime(epoch);
  119. aoffset.setZeroTime(epoch);
  120. bzero.emitZero();
  121. azero.emitZero();
  122. aadapt.measurement.connect(log.newMeasurement);
  123. aadapt.measurement.connect(graph.newMeasurement);
  124. badapt.measurement.connect(log.newMeasurement);
  125. badapt.measurement.connect(graph.newMeasurement);
  126. if(typeof(currentBatchInfo) == 'undefined') { } else {
  127. var query = new QSqlQuery();
  128. query.exec("SELECT now()::timestamp without time zone");
  129. query.next();
  130. var result = query.value(0);
  131. var timefield = findChildObject(currentBatchInfo, 'time');
  132. timefield.text = result.replace('T', ' ');
  133. }
  134. });
  135. start.setFocus();
  136. var spin = findChildObject(this, 'manometer');
  137. spin.annotation.connect(log.newAnnotation);
  138. var stop = findChildObject(this, 'stopbutton');
  139. stop.annotation.connect(log.newAnnotation);
  140. stop.clicked.connect(timer.stopTimer);
  141. stop.clicked.connect(function() {
  142. badapt.measurement.disconnect(log.newMeasurement);
  143. badapt.measurement.disconnect(graph.newMeasurement);
  144. aadapt.measurement.disconnect(log.newMeasurement);
  145. aadapt.measurement.disconnect(graph.newMeasurement);
  146. spin.resetChange();
  147. if(typeof(currentBatchInfo) == 'undefined') { } else {
  148. var duration = log.lastTime(lc);
  149. var durfield = findChildObject(currentBatchInfo, 'duration');
  150. durfield.text = duration;
  151. log.clearOutputColumns();
  152. log.addOutputTemperatureColumn(lc);
  153. log.addOutputTemperatureColumn(lc + 1);
  154. log.addOutputAnnotationColumn(lc + 2);
  155. var filename = log.saveTemporary();
  156. currentBatchInfo.tempData = filename;
  157. currentBatchInfo.raise();
  158. currentBatchInfo.activateWindow();
  159. }
  160. });
  161. var sample = findChildObject(this, 'sample');
  162. sample.annotation.connect(log.newAnnotation);
  163. var openMenu = findChildObject(this, 'open');
  164. var window = this;
  165. openMenu.triggered.connect(function() {
  166. var filename = QFileDialog.getOpenFileName(window, 'Open Log…', QSettings.value('script/lastDir', '') + '/');
  167. if(filename != '') {
  168. var file = new QFile(filename);
  169. var input = new XMLInput(file, 1);
  170. input.newTemperatureColumn.connect(log.setHeaderData);
  171. input.newAnnotationColumn.connect(log.setHeaderData);
  172. input.measure.connect(graph.newMeasurement);
  173. input.measure.connect(log.newMeasurement);
  174. input.annotation.connect(log.newAnnotation);
  175. input.lastColumn.connect(function(c) {
  176. lc = c + 1;
  177. badapt.setColumn(c + 1);
  178. aadapt.setColumn(c + 2);
  179. bzero.setColumn(c + 1);
  180. azero.setColumn(c + 2);
  181. stop.setTemperatureColumn(c + 1);
  182. stop.setAnnotationColumn(c + 3);
  183. sample.setTemperatureColumn(c + 1);
  184. sample.setAnnotationColumn(c + 3);
  185. spin.setTemperatureColumn(c + 1);
  186. spin.setAnnotationColumn(c + 3);
  187. log.setHeaderData(c + 1, "Bean");
  188. log.setHeaderData(c + 2, "Air");
  189. log.setHeaderData(c + 3, "Note");
  190. });
  191. input.input();
  192. window.windowTitle = 'Typica - ' + baseName(filename);
  193. QSettings.setValue("script/lastDir", dir(filename));
  194. }
  195. });
  196. var quitMenu = findChildObject(this, 'quit');
  197. quitMenu.triggered.connect(function() {
  198. window.close();
  199. Application.quit();
  200. });
  201. var saveMenu = findChildObject(this, 'save');
  202. saveMenu.triggered.connect(function() {
  203. var filename = QFileDialog.getSaveFileName(window, "Save Log As…", QSettings.value("script/lastDir", "") + "/");
  204. if(filename != "") {
  205. var file = new QFile(filename);
  206. log.clearOutputColumns();
  207. log.addOutputTemperatureColumn(lc);
  208. log.addOutputTemperatureColumn(lc + 1);
  209. log.addOutputAnnotationColumn(lc + 2);
  210. log.saveXML(file);
  211. QSettings.setValue("script/lastDir", dir(filename));
  212. }
  213. });
  214. var exportMenu = findChildObject(this, 'export');
  215. exportMenu.triggered.connect(function() {
  216. var filename = QFileDialog.getSaveFileName(window, "Export CSV As…", QSettings.value("script/lastDir", "") + "/");
  217. if(filename != "") {
  218. var file = new QFile(filename);
  219. log.clearOutputColumns();
  220. log.addOutputTemperatureColumn(lc);
  221. log.addOutputTemperatureColumn(lc + 1);
  222. log.addOutputAnnotationColumn(lc + 2);
  223. log.saveCSV(file);
  224. QSettings.setValue("script/lastDir", dir(filename));
  225. }
  226. });
  227. var clear = findChildObject(this, 'clear');
  228. clear.triggered.connect(log.clear);
  229. clear.triggered.connect(graph.clear);
  230. clear.triggered.connect(function() {
  231. window.windowTitle = "Typica";
  232. log.setHeaderData(0, "Time");
  233. log.setHeaderData(1, "Bean");
  234. log.setHeaderData(2, "Air");
  235. log.setHeaderData(3, "Note");
  236. log.setHeaderData(4, "");
  237. log.setHeaderData(5, "");
  238. log.setHeaderData(6, "");
  239. lc = 1;
  240. badapt.setColumn(1);
  241. aadapt.setColumn(2);
  242. bzero.setColumn(1);
  243. azero.setColumn(2);
  244. stop.setTemperatureColumn(1);
  245. stop.setAnnotationColumn(3);
  246. sample.setTemperatureColumn(1);
  247. sample.setAnnotationColumn(3);
  248. spin.setTemperatureColumn(1);
  249. spin.setAnnotationColumn(3);
  250. });
  251. var v1 = findChildObject(this, 'ms');
  252. v1.triggered.connect(log.LOD_ms);
  253. var v2 = findChildObject(this, '1s');
  254. v2.triggered.connect(log.LOD_1s);
  255. var v3 = findChildObject(this, '5s');
  256. v3.triggered.connect(log.LOD_5s);
  257. var v4 = findChildObject(this, '10s');
  258. v4.triggered.connect(log.LOD_10s);
  259. var v5 = findChildObject(this, '15s');
  260. v5.triggered.connect(log.LOD_15s);
  261. var v6 = findChildObject(this, '30s');
  262. v6.triggered.connect(log.LOD_30s);
  263. var v7 = findChildObject(this, '1m');
  264. v7.triggered.connect(log.LOD_1m);
  265. var manual = findChildObject(this, 'manual');
  266. manual.triggered.connect(function() {
  267. var entry = new LogEditWindow();
  268. entry.show();
  269. });
  270. var newMenu = findChildObject(this, 'new');
  271. newMenu.triggered.connect(function() {
  272. var bwindow = createWindow("batchWindow");
  273. bwindow.windowTitle = "Typica - New Batch";
  274. });
  275. </program>
  276. </window>