first commit

main
esea_info 3 years ago
commit 0bd7c5a26a
  1. 91
      .vscode/settings.json
  2. BIN
      __pycache__/configuration.cpython-38.pyc
  3. BIN
      __pycache__/dataplot.cpython-38.pyc
  4. BIN
      __pycache__/listctrl.cpython-38.pyc
  5. BIN
      __pycache__/myconfig.cpython-38.pyc
  6. BIN
      __pycache__/myexception.cpython-38.pyc
  7. BIN
      __pycache__/mylogger.cpython-38.pyc
  8. BIN
      __pycache__/mypanel.cpython-38.pyc
  9. BIN
      __pycache__/mypath.cpython-38.pyc
  10. BIN
      __pycache__/mythread.cpython-38.pyc
  11. BIN
      __pycache__/readcal.cpython-38.pyc
  12. BIN
      __pycache__/uart.cpython-38.pyc
  13. BIN
      __pycache__/viper.cpython-38.pyc
  14. BIN
      __pycache__/yiwinframe.cpython-38.pyc
  15. 33
      app.py
  16. 131
      calfile/attenuation_pure_water.DAT
  17. 27
      config.yml
  18. 32
      configuration.py
  19. 892
      data/20210305/ABSORPTI.DAT
  20. 466
      dataplot.py
  21. BIN
      icon.ico
  22. 32
      listctrl.py
  23. 187
      myconfig.py
  24. 14
      myexception.py
  25. 285
      mylogger.py
  26. 137
      mypanel.py
  27. 277
      mypath.py
  28. 126
      mythread.py
  29. 71
      mytime.py
  30. 1020
      readcal.py
  31. 3
      retrieve.yml
  32. 200
      uart.py
  33. BIN
      uiconfig/__pycache__/ui_com_setting.cpython-38.pyc
  34. BIN
      uiconfig/__pycache__/ui_filepath_setting.cpython-38.pyc
  35. BIN
      uiconfig/__pycache__/ui_log_setting.cpython-38.pyc
  36. BIN
      uiconfig/__pycache__/ui_pathsn_setting.cpython-38.pyc
  37. BIN
      uiconfig/__pycache__/ui_plot_setting.cpython-38.pyc
  38. BIN
      uiconfig/__pycache__/uiabout.cpython-38.pyc
  39. BIN
      uiconfig/__pycache__/uihelp.cpython-38.pyc
  40. BIN
      uiconfig/__pycache__/uilogging.cpython-38.pyc
  41. BIN
      uiconfig/__pycache__/uioscar.cpython-38.pyc
  42. BIN
      uiconfig/__pycache__/uiport.cpython-38.pyc
  43. BIN
      uiconfig/__pycache__/uiprofiler.cpython-38.pyc
  44. BIN
      uiconfig/__pycache__/uiramses.cpython-38.pyc
  45. BIN
      uiconfig/__pycache__/uisensor.cpython-38.pyc
  46. BIN
      uiconfig/__pycache__/uisurface.cpython-38.pyc
  47. BIN
      uiconfig/__pycache__/uiviper.cpython-38.pyc
  48. 110
      uiconfig/ui_algorithm.py
  49. 138
      uiconfig/ui_com_setting.py
  50. 92
      uiconfig/ui_filepath_setting.py
  51. 100
      uiconfig/ui_log_setting.py
  52. 100
      uiconfig/ui_pathsn_setting.py
  53. 100
      uiconfig/ui_plot_setting.py
  54. 60
      uiconfig/uiabout.py
  55. 58
      uiconfig/uihelp.py
  56. 124
      uiconfig/uisensor.py
  57. 427
      viper.py
  58. 766
      yiwinframe.py

@ -0,0 +1,91 @@
{
// ()
"editor.fontSize": 16,
// #editor.wordWrap# wordWrapColumn bounded 100
"editor.wordWrapColumn": 100,
// tab true false
"editor.detectIndentation": false,
// tab
"editor.tabSize": 4,
//
"editor.formatOnSave": false,
// vscode
"breadcrumbs.enabled": true,
// prettier ,C_cpp
"prettier.semi": false,
// prettier
"prettier.singleQuote": true,
// 'none' - ' es5' - ES5 'all' -
"prettier.trailingComma": "none",
//
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
// , ctrl+
"editor.mouseWheelZoom": true,
"editor.defaultFormatter": "ms-python.vscode-pylance",
"files.encoding":"utf8",
// python tab4
"[python]": {
"editor.insertSpaces": true,
"editor.tabSize": 4
},
// astyle,astyle -C c++ java
// "astyle.executable": "D:\\AStyle\\bin\\astyle.exe", //window
// "astyle.executable": "/usr/bin/astyle", // linux
// "astyle.additional_languages": [
// "c",
// "cpp",
// "*.h",
// ],
// "astyle.cmd_options": [
// // -----------------------------------------------------------
// // "--style=ansi", //ANSI
// // "--style=kr", //Kernighan&Ritchie
// "--style=linux", //Linux
// //"--style=gnu", //GNU
// // "--style=java", //Java
// "--indent=spaces=4", //4
// "--indent-preproc-block",
// "--pad-oper", //
// "--pad-header",
// "--unpad-paren",
// "--suffix=none",
// "--align-pointer=name",
// "--lineend=linux",
// "--convert-tabs", //TAB
// "--verbose",
// // "--delete-empty-lines", //
// //"--pad-paren-in", //
// "--unpad-paren", //
// ],
// pylint --python pylint
// "python.linting.enabled": true,
// "python.linting.pylintEnabled": true,
// "python.linting.lintOnSave": true,
// "python.linting.pylintPath": "D:\\pylint\\bin\\pylint.exe",
// "python.linting.pylintArgs": [
// "--rcfile={path}/.pylintrc",
// "--extension-pkg-whitelist=PyQt5",
// "--disable=invalid-name,missing-module-docstring",
// "--disable=W0612,W0631,W0703,W0621,W0613,W0611,W1308,C0411,C0111,C0103,C0301,C0304,C0305,E1101,R0913,R0914,R0915,R0903" ,
// ],
// ,
"terminal.integrated.defaultProfile.windows" : "PowerShell",
// "terminal.integrated.defaultProfile.windows" : "Git Bash",
// "terminal.integrated.defaultProfile.windows" : "Windows PowerShell",
// "terminal.integrated.defaultProfile.windows": "Ubuntu-20.04 (WSL)",
"python.defaultInterpreterPath": "python3", // python3 python
"code-runner.executorMap": {
"python":"python3 -u $fullFileName"
},
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,33 @@
#! python3
# -*- encoding: utf-8 -*-
'''
@File : app.py
@Time : 2021/09/12 12:38:46
@Author : Jim
@Version : 1.0
@Desp :
'''
# VERSION = "3.3.2"
# LASTDATE = "2021-09-20"
import wx
from yiwinframe import YiwinFrame
from mylogger import log
from myconfig import VERSION,LASTDATE,COMPANY
class YiwinApp(wx.App):
def OnInit(self):
self.myframe = YiwinFrame( u'奕枫水体吸收系数测量软件 v1.0', parent=None)
self.myframe.statusBar.SetStatusText( u" 版权所有 " + COMPANY
+" Version "+ VERSION + " "+ LASTDATE, 1 ) #给状态栏设文字
self.myframe.Show(True)
return True
if __name__ == "__main__":
log.info(f"******** Shanghai Yiwin Instrument@Equipment Company *********", __name__, "", "")
log.info(f"******** Viper attenuation Software .... *********", __name__, "", "")
app = YiwinApp( )
app.MainLoop()

@ -0,0 +1,131 @@
[Spectrum]
Version = 1
IDData = VIPER_A05D_2021-07-09_12-19-30_Absorption_505
IDDevice = VIPER_A05D
IDDataType = SPECTRUM
IDDataTypeSub1 = attenuation coefficient of pure water
IDDataTypeSub2 = SAMPLE
IDDataTypeSub3 =
DateTime = 2021-07-09 12:19:30
PositionLatitude = 0
PositionLongitude = 0
Comment =
CommentSub1 =
CommentSub2 =
CommentSub3 =
IDMethodType =
MethodName =
Mission = 1 ; 54.1849 ; ;
MissionSub = 0
RecordType = 0
[Attributes]
Averaging = 1
CalFactor = 39.6348
Deviation = 54.1849
FlashCount = 1
IDBasisSpec = 1607002963
IDDataBack =
IDDataCal =
IntegrationTime = 512
Maximum = 1.06247
P31 = 0
P31e = 0
PathLength = 150
PathLengthCustomOn = 0
RAWDynamic = 65535
SQIBase = 0.02
Salinity = 0
SpectrumType = Absorption
Temperature = 29.8437
Unit1 = $01 $01 Wavelength nm
Unit2 = $09 $08 Absorption 1
Unit3 = $09 $08 Absorption 1
Unit4 = $f1 $00 Status
lampLEDs = 255
lampReference = 20293
p999 = 0
tempLampModule = 29.8437
tempLampPower = 29.875
tempMainCPU = 34.0625
tempSpectrometer = 32.75
[END] of [Attributes]
[DATA]
0 8 0 0
360 0.0158 0.0007 0
365 0.0149 0.0007 0
370 0.0142 0.0007 0
375 0.0133 0.0007 1
380 0.0125 0.0007 0
385 0.0119 0.0007 0
390 0.0114 0.0007 0
395 0.0108 0.0007 0
400 0.0104 0.0007 0
405 0.0101 0.0007 0
410 0.0098 0.0007 0
415 0.0096 0.0006 0
420 0.00924 0.0006 14
425 0.00928 0.0006 13
430 0.00925 0.0006 14
435 0.0094 0.0006 13
440 0.01025 0.0006 12
445 0.01121 0.0005 11
450 0.01272 0.0005 11
455 0.01292 0.0005 10
460 0.01299 0.0005 9
465 0.01311 0.0005 9
470 0.0135 0.0006 8
475 0.0142 0.0005 7
480 0.0154 0.0005 6
485 0.0161 0.0004 6
490 0.0174 0.0004 5
495 0.0196 0.0004 5
500 0.0226 0.0005 6
505 0.0277 0.0005 6
510 0.0345 0.0006 7
515 0.0416 0.0006 6
520 0.0428 0.0005 6
525 0.0435 0.0008 8
530 0.0451 0.0007 7
535 0.0469 0.0008 8
540 0.049 0.0008 7
545 0.0526 0.0008 7
550 0.058 0.0007 6
555 0.061 0.0007 6
560 0.0632 0.0007 5
565 0.0655 0.0014 9
570 0.0708 0.001 6
575 0.0784 0.0014 8
580 0.0908 0.0011 6
585 0.1111 0.0012 6
590 0.1362 0.0013 6
595 0.1682 0.001 5
600 0.2234 0.0011 4
605 0.2587 0.0012 4
610 0.2653 0.0012 4
615 0.2687 0.0015 5
620 0.2764 0.0009 3
625 0.2842 0.0014 4
630 0.2924 0.001 4
635 0.302 0.0017 5
640 0.3116 0.0011 4
645 0.3257 0.0017 5
650 0.3407 0.0012 4
655 0.3717 0.0015 4
660 0.4107 0.001 3
665 0.4296 0.0016 4
670 0.4396 0.0011 3
675 0.4486 0.0016 4
680 0.4656 0.0011 3
685 0.4866 0.0012 3
690 0.5166 0.0012 3
695 0.5595 0.0014 4
700 0.6245 0.001 3
705 0.7045 0.0015 4
710 0.8275 0.0009 3
715 1.0075 0.0014 3
720 1.2315 0.0011 3
725 1.4894 0.0011 3
[END] of [DATA]
[END] of Spectrum

@ -0,0 +1,27 @@
algorithm:
'A720': 0
'PureWater': 0
'PureWater2': 0
comsetting:
baudrate: 9600
bytesize: 8
parity: N
port: COM1
stopbit: 1
device:
UIPath: 150
UISN: A05D
logsetting:
LogInterval: 1
RefreshInterval: 0
plotsetting:
LineBegin: 0
LineInterval: 1
register:
DataBeginAddress: 2614
SNAddress: 2980
SNLen: 5
WLBeginAddress: 2102
count: 3
functioncode: 3
slaveaddress: 1

@ -0,0 +1,32 @@
from pathlib import Path, PurePath
from mylogger import log
from readcal import ReadCal
from myconfig import CAL_DIR, DATA_DIR, FILE_MARK, DeviceType
class Configuration:
def __init__(self, ) -> None:
log.info(f"Viper Configure init: ", __name__, "", "")
self.device_type = None
self.configuration =None
pass
def setSystemCfgDict(self, cfg:dict) -> None:
self.configuration = cfg
log.info(f"self.configuration : {self.configuration} ", __name__, "", "")
pass
def get_wl_from_datafile(self, fpath) -> None:
# self.cfgtool = Config()
if fpath.exists( ):
res = ReadCal.read_columns_set_by_mark( fpath, FILE_MARK, 1 )
self.configuration.update({ "wavelength" : res[1][0] })
pass
def getCalConfiguration(self) -> None:
pass

@ -0,0 +1,892 @@
[Spectrum]
Version = 1
IDData = VIPER_A05D_2011-01-28_00-00-32_Absorption_956
IDDevice = VIPER_A05D
DateTime = 2011-01-28 00:00:32
Comment =
CommentSub1 =
CommentSub2 =
CommentSub3 =
IDDataType = SPECTRUM
IDDataTypeSub1 = ABSORPTION
IDDataTypeSub2 = SAMPLE
Mission = 1 ; 12.1014 ; ;
[Attributes]
SpectrumType = Absorption
Averaging = 1
CalFactor = 323.875
FlashCount = 1
IntegrationTime = 64
PathLength = 150
Temperature = 21.7187
lampReference = 20728
lampLEDs = 255
tempLampModule = 21.7187
tempLampPower = 21.8125
tempSpectrometer = 27.875
tempMainCPU = 29.375
Deviation = 12.1014
Maximum = 0.127814
IDBasisSpec = 1607002963
SQIBase = 0.02
RAWDynamic = 65535
Unit1 = $01 $01 Wavelength nm
Unit2 = $09 $08 Absorption 1
Unit3 = $09 $08 Absorption 1
Unit4 = $f1 $00 Status
[END] of [Attributes]
[DATA]
0 5 0 0
348.449 0.127814 0 0
350.582 0.11374 0 0
352.714 0.112956 0 0
354.846 0.112141 0 0
356.978 0.113478 0 0
359.109 0.113652 0 0
361.239 0.112536 0 0
363.37 0.112693 0 0
365.499 0.113707 0 0
367.629 0.114538 0 0
369.757 0.114091 0 0
371.886 0.113129 0 0
374.014 0.112497 0 0
376.141 0.112543 0 0
378.268 0.113452 0 0
380.394 0.113834 0 0
382.52 0.113713 0 0
384.646 0.113458 0 0
386.771 0.113924 0 0
388.895 0.115218 0 0
391.019 0.116083 0 0
393.142 0.116546 0 0
395.265 0.115786 0 0
397.388 0.115939 0 0
399.509 0.115761 0 0
401.631 0.1153 0 0
403.751 0.115491 0 0
405.872 0.115647 0 0
407.991 0.115151 0 0
410.11 0.115626 0 0
412.229 0.116548 0 0
414.347 0.118101 0 0
416.465 0.118035 0 0
418.582 0.116925 0 0
420.698 0.115402 0 0
422.814 0.113735 0 0
424.929 0.113218 0 0
427.044 0.114775 0 0
429.158 0.116581 0 0
431.271 0.117034 0 0
433.384 0.117575 0 0
435.497 0.11764 0 0
437.608 0.118782 0 0
439.72 0.119549 0 0
441.83 0.121309 0 0
443.94 0.122246 0 0
446.049 0.122688 0 0
448.158 0.12367 0 0
450.266 0.12358 0 0
452.374 0.123454 0 0
454.481 0.122483 0 0
456.587 0.121352 0 0
458.693 0.120174 0 0
460.798 0.118698 0 0
462.902 0.116801 0 0
465.006 0.115501 0 0
467.109 0.114403 0 0
469.211 0.113701 0 0
471.313 0.113681 0 0
473.414 0.113321 0 0
475.514 0.112773 0 0
477.614 0.113746 0 0
479.713 0.113536 0 0
481.812 0.116502 0 0
483.909 0.116058 0 0
486.007 0.116526 0 0
488.103 0.114908 0 0
490.199 0.116429 0 0
492.294 0.114168 0 0
494.388 0.115586 0 0
496.482 0.114446 0 0
498.575 0.113854 0 0
500.667 0.112686 0 0
502.758 0.11393 0 0
504.849 0.112698 0 0
506.939 0.111642 0 0
509.028 0.111282 0 0
511.117 0.111762 0 0
513.205 0.11071 0 0
515.292 0.111922 0 0
517.378 0.113175 0 0
519.464 0.112928 0 0
521.549 0.112811 0 0
523.633 0.113126 0 0
525.717 0.113392 0 0
527.799 0.113505 0 0
529.881 0.113887 0 0
531.962 0.113784 0 0
534.043 0.114851 0 0
536.122 0.113209 0 0
538.201 0.113538 0 0
540.279 0.113283 0 0
542.356 0.113044 0 0
544.433 0.112063 0 0
546.508 0.111686 0 0
548.583 0.111008 0 0
550.658 0.110703 0 0
552.731 0.110154 0 0
554.803 0.109367 0 0
556.875 0.109456 0 0
558.946 0.109302 0 0
561.016 0.108354 0 0
563.085 0.108635 0 0
565.153 0.108339 0 0
567.221 0.108883 0 0
569.288 0.109004 0 0
571.353 0.109164 0 0
573.419 0.108922 0 0
575.483 0.108629 0 0
577.546 0.108983 0 0
579.609 0.109142 0 0
581.67 0.108994 0 0
583.731 0.108436 0 0
585.791 0.108665 0 0
587.85 0.107621 0 0
589.908 0.107676 0 0
591.965 0.106535 0 0
594.022 0.105538 0 0
596.077 0.103036 0 0
598.132 0.101463 0 0
600.186 0.100313 0 0
602.238 0.0984701 0 0
604.29 0.0978697 0 0
606.341 0.0968281 0 0
608.392 0.0973058 0 0
610.441 0.0968114 0 0
612.489 0.0944351 0 0
614.537 0.0942494 0 0
616.583 0.0941368 0 0
618.629 0.0945533 0 0
620.673 0.0931584 0 0
622.717 0.0916116 0 0
624.76 0.0916241 0 0
626.801 0.0926359 0 0
628.842 0.0909737 0 0
630.882 0.0903093 0 0
632.921 0.0891894 0 0
634.959 0.0906699 0 0
636.996 0.0912185 0 0
639.032 0.0906486 0 0
641.067 0.0902244 0 0
643.102 0.0899626 0 0
645.135 0.0900885 0 0
647.167 0.0920863 0 0
649.198 0.0905681 0 0
651.228 0.090085 0 0
653.258 0.0889907 0 0
655.286 0.0890961 0 0
657.313 0.0885218 0 0
659.339 0.0879637 0 0
661.364 0.0879287 0 0
663.389 0.0864832 0 0
665.412 0.0867878 0 0
667.434 0.0864328 0 0
669.455 0.0912282 0 0
671.475 0.0889504 0 0
673.494 0.0877137 0 0
675.513 0.0872359 0 0
677.53 0.0904399 0 0
679.546 0.0894157 0 0
681.561 0.0864097 0 0
683.574 0.0874475 0 0
685.587 0.0876873 0 0
687.599 0.0856188 0 0
689.61 0.0818516 0 0
691.619 0.078733 0 0
693.628 0.0829921 0 0
695.636 0.0773868 0 0
697.642 0.0758 0 0
699.647 0.0795865 0 0
701.652 0.0750983 0 0
703.655 0.0713695 0 0
705.657 0.0708702 0 0
707.658 0.0715209 0 0
709.658 0.0678586 0 0
711.657 0.0620032 0 0
713.655 0.0536908 0 0
715.651 0.0621843 0 0
717.647 0.0471298 0 0
719.641 0.0310415 0 0
721.634 0.0411625 0 0
[END] of [DATA]
[END] of [Spectrum]
[Spectrum]
Version = 1
IDData = VIPER_A05D_2011-01-28_00-01-04_Absorption_160
IDDevice = VIPER_A05D
DateTime = 2011-01-28 00:01:04
Comment =
CommentSub1 =
CommentSub2 =
CommentSub3 =
IDDataType = SPECTRUM
IDDataTypeSub1 = ABSORPTION
IDDataTypeSub2 = SAMPLE
Mission = 1 ; 13.5109 ; ;
[Attributes]
SpectrumType = Absorption
Averaging = 1
CalFactor = 323.812
FlashCount = 1
IntegrationTime = 64
PathLength = 150
Temperature = 21.7812
lampReference = 20724
lampLEDs = 255
tempLampModule = 21.7812
tempLampPower = 21.8437
tempSpectrometer = 27.9375
tempMainCPU = 29.3125
Deviation = 13.5109
Maximum = 0.123204
IDBasisSpec = 1607002963
SQIBase = 0.02
RAWDynamic = 65535
Unit1 = $01 $01 Wavelength nm
Unit2 = $09 $08 Absorption 1
Unit3 = $09 $08 Absorption 1
Unit4 = $f1 $00 Status
[END] of [Attributes]
[DATA]
0 5 0 0
348.449 0.108085 0 0
350.582 0.10192 0 0
352.714 0.10706 0 0
354.846 0.109759 0 0
356.978 0.111303 0 0
359.109 0.113366 0 0
361.239 0.112528 0 0
363.37 0.112052 0 0
365.499 0.113259 0 0
367.629 0.114201 0 0
369.757 0.113857 0 0
371.886 0.112792 0 0
374.014 0.112201 0 0
376.141 0.112261 0 0
378.268 0.113023 0 0
380.394 0.113304 0 0
382.52 0.113249 0 0
384.646 0.112358 0 0
386.771 0.113042 0 0
388.895 0.113877 0 0
391.019 0.114588 0 0
393.142 0.115162 0 0
395.265 0.114966 0 0
397.388 0.115377 0 0
399.509 0.115393 0 0
401.631 0.114693 0 0
403.751 0.115193 0 0
405.872 0.115299 0 0
407.991 0.114797 0 0
410.11 0.115215 0 0
412.229 0.116395 0 0
414.347 0.117736 0 0
416.465 0.117751 0 0
418.582 0.116494 0 0
420.698 0.115208 0 0
422.814 0.113344 0 0
424.929 0.112895 0 0
427.044 0.11412 0 0
429.158 0.116002 0 0
431.271 0.116312 0 0
433.384 0.116362 0 0
435.497 0.116765 0 0
437.608 0.117822 0 0
439.72 0.118828 0 0
441.83 0.12058 0 0
443.94 0.121688 0 0
446.049 0.122383 0 0
448.158 0.123141 0 0
450.266 0.123204 0 0
452.374 0.122973 0 0
454.481 0.121994 0 0
456.587 0.120883 0 0
458.693 0.119155 0 0
460.798 0.118027 0 0
462.902 0.11581 0 0
465.006 0.114698 0 0
467.109 0.113399 0 0
469.211 0.111818 0 0
471.313 0.111491 0 0
473.414 0.112154 0 0
475.514 0.111309 0 0
477.614 0.1114 0 0
479.713 0.111655 0 0
481.812 0.113382 0 0
483.909 0.113187 0 0
486.007 0.114004 0 0
488.103 0.114976 0 0
490.199 0.114088 0 0
492.294 0.112901 0 0
494.388 0.112421 0 0
496.482 0.111632 0 0
498.575 0.112724 0 0
500.667 0.109042 0 0
502.758 0.112645 0 0
504.849 0.109365 0 0
506.939 0.108869 0 0
509.028 0.109577 0 0
511.117 0.110742 0 0
513.205 0.109466 0 0
515.292 0.110859 0 0
517.378 0.111149 0 0
519.464 0.111518 0 0
521.549 0.11156 0 0
523.633 0.112085 0 0
525.717 0.112538 0 0
527.799 0.11314 0 0
529.881 0.112739 0 0
531.962 0.112797 0 0
534.043 0.114011 0 0
536.122 0.112618 0 0
538.201 0.112746 0 0
540.279 0.112775 0 0
542.356 0.112288 0 0
544.433 0.111321 0 0
546.508 0.110755 0 0
548.583 0.110041 0 0
550.658 0.109749 0 0
552.731 0.1095 0 0
554.803 0.109152 0 0
556.875 0.109147 0 0
558.946 0.108567 0 0
561.016 0.107955 0 0
563.085 0.108047 0 0
565.153 0.107941 0 0
567.221 0.108294 0 0
569.288 0.108127 0 0
571.353 0.108807 0 0
573.419 0.108418 0 0
575.483 0.10778 0 0
577.546 0.108123 0 0
579.609 0.10827 0 0
581.67 0.108208 0 0
583.731 0.107326 0 0
585.791 0.107585 0 0
587.85 0.106841 0 0
589.908 0.106934 0 0
591.965 0.105943 0 0
594.022 0.104301 0 0
596.077 0.102476 0 0
598.132 0.100827 0 0
600.186 0.0995318 0 0
602.238 0.0975342 0 0
604.29 0.0969724 0 0
606.341 0.0954195 0 0
608.392 0.0954239 0 0
610.441 0.0950918 0 0
612.489 0.0934964 0 0
614.537 0.0925861 0 0
616.583 0.0919505 0 0
618.629 0.0927997 0 0
620.673 0.0923686 0 0
622.717 0.0907163 0 0
624.76 0.0908813 0 0
626.801 0.0903943 0 0
628.842 0.0900869 0 0
630.882 0.0884865 0 0
632.921 0.0881195 0 0
634.959 0.0889955 0 0
636.996 0.0898027 0 0
639.032 0.0891579 0 0
641.067 0.0873659 0 0
643.102 0.0883067 0 0
645.135 0.0879073 0 0
647.167 0.0890207 0 0
649.198 0.0895822 0 0
651.228 0.0893833 0 0
653.258 0.0880755 0 0
655.286 0.0869999 0 0
657.313 0.0888984 0 0
659.339 0.0877311 0 0
661.364 0.087686 0 0
663.389 0.0841387 0 0
665.412 0.085539 0 0
667.434 0.085637 0 0
669.455 0.0860182 0 0
671.475 0.0872101 0 0
673.494 0.0873932 0 0
675.513 0.0833971 0 0
677.53 0.0860587 0 0
679.546 0.0844616 0 0
681.561 0.083438 0 0
683.574 0.081583 0 0
685.587 0.0835701 0 0
687.599 0.0804411 0 0
689.61 0.0818398 0 0
691.619 0.077305 0 0
693.628 0.0760186 0 0
695.636 0.0737182 0 0
697.642 0.0735939 0 0
699.647 0.071516 0 0
701.652 0.0702327 0 0
703.655 0.0650611 0 0
705.657 0.0642871 0 0
707.658 0.0610527 0 0
709.658 0.0576016 0 0
711.657 0.0497871 0 0
713.655 0.0544937 0 0
715.651 0.0495205 0 0
717.647 0.0400808 0 0
719.641 0.0219393 0 0
721.634 0.0469534 0 0
[END] of [DATA]
[END] of [Spectrum]
[Spectrum]
Version = 1
IDData = VIPER_A05D_2011-01-28_00-04-05_Absorption_299
IDDevice = VIPER_A05D
DateTime = 2011-01-28 00:04:05
Comment =
CommentSub1 =
CommentSub2 =
CommentSub3 =
IDDataType = SPECTRUM
IDDataTypeSub1 = ABSORPTION
IDDataTypeSub2 = SAMPLE
Mission = 1 ; 13.9479 ; ;
[Attributes]
SpectrumType = Absorption
Averaging = 1
CalFactor = 323.844
FlashCount = 1
IntegrationTime = 64
PathLength = 150
Temperature = 21.75
lampReference = 20726
lampLEDs = 255
tempLampModule = 21.75
tempLampPower = 21.875
tempSpectrometer = 28.25
tempMainCPU = 29.375
Deviation = 13.9479
Maximum = 0.136324
IDBasisSpec = 1607002963
SQIBase = 0.02
RAWDynamic = 65535
Unit1 = $01 $01 Wavelength nm
Unit2 = $09 $08 Absorption 1
Unit3 = $09 $08 Absorption 1
Unit4 = $f1 $00 Status
[END] of [Attributes]
[DATA]
0 5 0 0
348.449 0.136324 0 0
350.582 0.115176 0 0
352.714 0.114441 0 0
354.846 0.112615 0 0
356.978 0.113951 0 0
359.109 0.114539 0 0
361.239 0.112815 0 0
363.37 0.113144 0 0
365.499 0.1139 0 0
367.629 0.114873 0 0
369.757 0.114149 0 0
371.886 0.113016 0 0
374.014 0.112233 0 0
376.141 0.112262 0 0
378.268 0.113251 0 0
380.394 0.113654 0 0
382.52 0.11373 0 0
384.646 0.113448 0 0
386.771 0.113978 0 0
388.895 0.115102 0 0
391.019 0.115808 0 0
393.142 0.116609 0 0
395.265 0.115901 0 0
397.388 0.115861 0 0
399.509 0.115663 0 0
401.631 0.115167 0 0
403.751 0.115485 0 0
405.872 0.115502 0 0
407.991 0.115006 0 0
410.11 0.115343 0 0
412.229 0.116448 0 0
414.347 0.117901 0 0
416.465 0.117905 0 0
418.582 0.116813 0 0
420.698 0.115501 0 0
422.814 0.113723 0 0
424.929 0.113218 0 0
427.044 0.114715 0 0
429.158 0.116798 0 0
431.271 0.117102 0 0
433.384 0.117102 0 0
435.497 0.117733 0 0
437.608 0.11865 0 0
439.72 0.119671 0 0
441.83 0.121463 0 0
443.94 0.12224 0 0
446.049 0.122777 0 0
448.158 0.123801 0 0
450.266 0.123525 0 0
452.374 0.123514 0 0
454.481 0.122707 0 0
456.587 0.121213 0 0
458.693 0.120166 0 0
460.798 0.118996 0 0
462.902 0.11735 0 0
465.006 0.115601 0 0
467.109 0.114995 0 0
469.211 0.113431 0 0
471.313 0.113728 0 0
473.414 0.11379 0 0
475.514 0.114624 0 0
477.614 0.115014 0 0
479.713 0.114796 0 0
481.812 0.116206 0 0
483.909 0.1187 0 0
486.007 0.11938 0 0
488.103 0.118761 0 0
490.199 0.119528 0 0
492.294 0.117262 0 0
494.388 0.11753 0 0
496.482 0.115877 0 0
498.575 0.116129 0 0
500.667 0.114075 0 0
502.758 0.114874 0 0
504.849 0.112829 0 0
506.939 0.112414 0 0
509.028 0.111622 0 0
511.117 0.112507 0 0
513.205 0.111392 0 0
515.292 0.112179 0 0
517.378 0.112893 0 0
519.464 0.112905 0 0
521.549 0.112788 0 0
523.633 0.113245 0 0
525.717 0.113706 0 0
527.799 0.114254 0 0
529.881 0.113681 0 0
531.962 0.113468 0 0
534.043 0.114488 0 0
536.122 0.113524 0 0
538.201 0.113845 0 0
540.279 0.113161 0 0
542.356 0.112822 0 0
544.433 0.111895 0 0
546.508 0.111622 0 0
548.583 0.111193 0 0
550.658 0.110593 0 0
552.731 0.109754 0 0
554.803 0.109837 0 0
556.875 0.109253 0 0
558.946 0.108863 0 0
561.016 0.108534 0 0
563.085 0.108625 0 0
565.153 0.10885 0 0
567.221 0.108636 0 0
569.288 0.109328 0 0
571.353 0.109585 0 0
573.419 0.108959 0 0
575.483 0.108569 0 0
577.546 0.108726 0 0
579.609 0.10938 0 0
581.67 0.108931 0 0
583.731 0.108217 0 0
585.791 0.108494 0 0
587.85 0.108091 0 0
589.908 0.107552 0 0
591.965 0.107027 0 0
594.022 0.105639 0 0
596.077 0.103081 0 0
598.132 0.101632 0 0
600.186 0.100361 0 0
602.238 0.0978726 0 0
604.29 0.0978547 0 0
606.341 0.0959855 0 0
608.392 0.0967197 0 0
610.441 0.096281 0 0
612.489 0.0948728 0 0
614.537 0.0936888 0 0
616.583 0.0941201 0 0
618.629 0.0950297 0 0
620.673 0.0939001 0 0
622.717 0.0916821 0 0
624.76 0.0917877 0 0
626.801 0.092899 0 0
628.842 0.0915353 0 0
630.882 0.090197 0 0
632.921 0.0900162 0 0
634.959 0.0904379 0 0
636.996 0.0906262 0 0
639.032 0.0905148 0 0
641.067 0.0902132 0 0
643.102 0.0904966 0 0
645.135 0.090077 0 0
647.167 0.0931446 0 0
649.198 0.0929734 0 0
651.228 0.0895644 0 0
653.258 0.0913102 0 0
655.286 0.0902204 0 0
657.313 0.0907106 0 0
659.339 0.0906925 0 0
661.364 0.0917014 0 0
663.389 0.0897471 0 0
665.412 0.0899862 0 0
667.434 0.0911066 0 0
669.455 0.0925955 0 0
671.475 0.0924066 0 0
673.494 0.0874022 0 0
675.513 0.0897929 0 0
677.53 0.0955232 0 0
679.546 0.0922561 0 0
681.561 0.0908758 0 0
683.574 0.0905933 0 0
685.587 0.0926588 0 0
687.599 0.0886542 0 0
689.61 0.0891296 0 0
691.619 0.0854017 0 0
693.628 0.0855025 0 0
695.636 0.0842639 0 0
697.642 0.0807852 0 0
699.647 0.0854365 0 0
701.652 0.07816 0 0
703.655 0.0797006 0 0
705.657 0.0788991 0 0
707.658 0.0736432 0 0
709.658 0.0671164 0 0
711.657 0.0635526 0 0
713.655 0.0577297 0 0
715.651 0.0664879 0 0
717.647 0.0489089 0 0
719.641 0.0403429 0 0
721.634 0.0440485 0 0
[END] of [DATA]
[END] of [Spectrum]
[Spectrum]
Version = 1
IDData = VIPER_A05D_2011-01-28_00-04-17_Absorption_782
IDDevice = VIPER_A05D
DateTime = 2011-01-28 00:04:17
Comment =
CommentSub1 =
CommentSub2 =
CommentSub3 =
IDDataType = SPECTRUM
IDDataTypeSub1 = ABSORPTION
IDDataTypeSub2 = SAMPLE
Mission = 1 ; 13.4412 ; ;
[Attributes]
SpectrumType = Absorption
Averaging = 1
CalFactor = 323.766
FlashCount = 1
IntegrationTime = 64
PathLength = 150
Temperature = 21.8437
lampReference = 20721
lampLEDs = 255
tempLampModule = 21.8437
tempLampPower = 21.875
tempSpectrometer = 28.25
tempMainCPU = 29.4375
Deviation = 13.4412
Maximum = 0.123031
IDBasisSpec = 1607002963
SQIBase = 0.02
RAWDynamic = 65535
Unit1 = $01 $01 Wavelength nm
Unit2 = $09 $08 Absorption 1
Unit3 = $09 $08 Absorption 1
Unit4 = $f1 $00 Status
[END] of [Attributes]
[DATA]
0 5 0 0
348.449 0.10921 0 0
350.582 0.106249 0 0
352.714 0.105195 0 0
354.846 0.108626 0 0
356.978 0.111923 0 0
359.109 0.114493 0 0
361.239 0.113352 0 0
363.37 0.113044 0 0
365.499 0.113505 0 0
367.629 0.114128 0 0
369.757 0.11401 0 0
371.886 0.112603 0 0
374.014 0.111936 0 0
376.141 0.111843 0 0
378.268 0.112687 0 0
380.394 0.113114 0 0
382.52 0.112869 0 0
384.646 0.111981 0 0
386.771 0.112436 0 0
388.895 0.113517 0 0
391.019 0.11404 0 0
393.142 0.114612 0 0
395.265 0.114632 0 0
397.388 0.114846 0 0
399.509 0.114851 0 0
401.631 0.114871 0 0
403.751 0.115197 0 0
405.872 0.115325 0 0
407.991 0.11484 0 0
410.11 0.115362 0 0
412.229 0.11637 0 0
414.347 0.1177 0 0
416.465 0.117591 0 0
418.582 0.116502 0 0
420.698 0.114842 0 0
422.814 0.1131 0 0
424.929 0.112616 0 0
427.044 0.11372 0 0
429.158 0.115484 0 0
431.271 0.115557 0 0
433.384 0.115916 0 0
435.497 0.116502 0 0
437.608 0.117354 0 0
439.72 0.118454 0 0
441.83 0.120266 0 0
443.94 0.121645 0 0
446.049 0.122079 0 0
448.158 0.123031 0 0
450.266 0.122925 0 0
452.374 0.122868 0 0
454.481 0.121753 0 0
456.587 0.120446 0 0
458.693 0.119326 0 0
460.798 0.117968 0 0
462.902 0.11599 0 0
465.006 0.113837 0 0
467.109 0.11301 0 0
469.211 0.111439 0 0
471.313 0.111222 0 0
473.414 0.11099 0 0
475.514 0.11188 0 0
477.614 0.110008 0 0
479.713 0.110535 0 0
481.812 0.112125 0 0
483.909 0.11235 0 0
486.007 0.110902 0 0
488.103 0.112517 0 0
490.199 0.11306 0 0
492.294 0.111639 0 0
494.388 0.111179 0 0
496.482 0.110239 0 0
498.575 0.111034 0 0
500.667 0.110069 0 0
502.758 0.110104 0 0
504.849 0.10934 0 0
506.939 0.108707 0 0
509.028 0.107879 0 0
511.117 0.110376 0 0
513.205 0.109624 0 0
515.292 0.110353 0 0
517.378 0.110075 0 0
519.464 0.111713 0 0
521.549 0.111439 0 0
523.633 0.111188 0 0
525.717 0.111954 0 0
527.799 0.113031 0 0
529.881 0.112574 0 0
531.962 0.112225 0 0
534.043 0.113628 0 0
536.122 0.112248 0 0
538.201 0.112604 0 0
540.279 0.11195 0 0
542.356 0.111843 0 0
544.433 0.110936 0 0
546.508 0.110427 0 0
548.583 0.110015 0 0
550.658 0.10992 0 0
552.731 0.10846 0 0
554.803 0.108746 0 0
556.875 0.108695 0 0
558.946 0.108357 0 0
561.016 0.107934 0 0
563.085 0.107459 0 0
565.153 0.107969 0 0
567.221 0.107848 0 0
569.288 0.107727 0 0
571.353 0.108068 0 0
573.419 0.108107 0 0
575.483 0.107759 0 0
577.546 0.107757 0 0
579.609 0.108146 0 0
581.67 0.108133 0 0
583.731 0.107197 0 0
585.791 0.106876 0 0
587.85 0.106707 0 0
589.908 0.106796 0 0
591.965 0.105353 0 0
594.022 0.103984 0 0
596.077 0.102093 0 0
598.132 0.100495 0 0
600.186 0.0986265 0 0
602.238 0.096471 0 0
604.29 0.0970756 0 0
606.341 0.0955266 0 0
608.392 0.0946823 0 0
610.441 0.0941084 0 0
612.489 0.0931622 0 0
614.537 0.092011 0 0
616.583 0.0915196 0 0
618.629 0.0924397 0 0
620.673 0.0916639 0 0
622.717 0.0902531 0 0
624.76 0.0889851 0 0
626.801 0.0903655 0 0
628.842 0.089774 0 0
630.882 0.0878642 0 0
632.921 0.087469 0 0
634.959 0.0883135 0 0
636.996 0.0893167 0 0
639.032 0.0876719 0 0
641.067 0.0867012 0 0
643.102 0.0886909 0 0
645.135 0.0868806 0 0
647.167 0.0880887 0 0
649.198 0.0881187 0 0
651.228 0.0890211 0 0
653.258 0.0873401 0 0
655.286 0.0854753 0 0
657.313 0.0858908 0 0
659.339 0.0866596 0 0
661.364 0.085676 0 0
663.389 0.0855105 0 0
665.412 0.0835606 0 0
667.434 0.0843269 0 0
669.455 0.0862712 0 0
671.475 0.087192 0 0
673.494 0.0864687 0 0
675.513 0.0811654 0 0
677.53 0.0830458 0 0
679.546 0.0837456 0 0
681.561 0.0815851 0 0
683.574 0.0831213 0 0
685.587 0.0811132 0 0
687.599 0.0800009 0 0
689.61 0.0791275 0 0
691.619 0.0740054 0 0
693.628 0.0774927 0 0
695.636 0.0705968 0 0
697.642 0.0692218 0 0
699.647 0.0703695 0 0
701.652 0.0660184 0 0
703.655 0.0638062 0 0
705.657 0.061031 0 0
707.658 0.0542104 0 0
709.658 0.057598 0 0
711.657 0.0550848 0 0
713.655 0.0425706 0 0
715.651 0.0445557 0 0
717.647 0.0297176 0 0
719.641 0.0237477 0 0
721.634 0.0383917 0 0
[END] of [DATA]
[END] of [Spectrum]

@ -0,0 +1,466 @@
# import numpy as np
from pathlib import Path
class DataPlot():
'''
从文件读取数据出来成待显示数据
'''
# def __init__(self, mypanel, ):
def __init__(self, ):
# self.mypanel = mypanel
# self.__eventManager = eventManger
# self.dataSaveFile = DATA_FNAME_WITHOUT_WATER
# self.axes_title = "Water Attenuation Coefficient"
# self.axes_xlabel = "Wavelength (nm)"
# self.axes_ylabel = "Attenuation Coefficient m(-1)"
# self.axes_title = "Attenuation Coefficient Demo"
self.demo_time = ''
self.demo_wl = [] # 纯水
self.demo_data = [] # 纯水
self.wavelength = None
self.data_one = None
self.data_multi = None
# self.mode = "one" # multi
# self.begin_line = None
# self.line_interval = None
self.fpath :Path = Path()
self.total_lines = 0
self.token = ";"
# self.MPL = myPanel.MPL_Panel(self) # 调用自己建立的 panel 类
# self.Figure = self.MPL.Figure
# self.axes = self.MPL.axes
# self.FigureCanvas = self.MPL.FigureCanvas
def set_file_path( self, fpath:Path ):
self.fpath = fpath
pass
def set_wavelength(self):
pass
# def set_mode(self, mode ="one"):
# self.mode = mode
# pass
def set_token(self, token =";"):
self.token = token
pass
def set_begin_line( self, lineno = 0 ):
self.begin_line = lineno
pass
def set_line_interval( self, line_interval = 0 ):
self.line_interval = line_interval
pass
def get_total_lines( self, ):
''' 大文件 '''
count = 0
thefile = open( self.fpath, 'rb')
while True:
buffer = thefile.read(8192*1024)
if not buffer:
break
count += buffer.count(b'\n')
self.total_lines = count + 1
def get_wavelength_from_file( self, ):
tmp = self.get_first_line()
self.wavelength = tmp.split(self.token)[1:]
pass
def get_reverse_x_lineno( self, x ):
line = self.__get_reverse_x_lineno(x)
line = line.split(self.token)
return line[0], line[1:]
pass
def get_multi_by_x_m_n( self, x,m,n ):
# res_time = []
# res_lines = []
lines = self.__get_reverse_x_m_n_line(x,m,n)
# print(f'+++++ {lines}')
# for i in range(len(lines)):
# ln =
# res_time.append( lines[i] [0] )
# res_lines.append( lines[i][1:] )
# return res_time, res_lines
return lines
pass
def __get_reverse_x_lineno(self, x):
"""
获得倒数第x行
"""
try:
# filesize = os.path.getsize(self.fpath)
filesize = self.fpath.stat().st_size
if filesize == 0:
return None
else:
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'
offset = -8 # initialize offset
while -offset < filesize: # offset cannot exceed file size
fp.seek(offset, 2) # read # offset chars from eof(represent by number '2')
lines = fp.readlines() # read from fp to eof
if len(lines) >= x+1: # if contains at least 2 lines
return lines[-1*x] # then last line is totally included
else:
offset *= 2 # enlarge offset
fp.seek(0)
lines = fp.readlines()
if len(lines) < x:
raise Exception("行数有误,请重试")
return lines[-1*x]
except FileNotFoundError:
print(self.fpath.name + ' not found!')
return None
def __get_reverse_x_m_n_line(self, x, m=1, n=1):
"""
获得倒数第x行, 间隔m行, 共取n个行
"""
print(f'__get_reverse_x_m_n_line {x} {self.fpath}')
min_lines = x + m*n
res_lines = []
try:
# filesize = os.path.getsize(self.fpath)
filesize = self.fpath.stat().st_size
if filesize == 0:
return None
else:
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'x
offset = -8 # initialize offset
while -offset < filesize: # offset cannot exceed file size
fp.seek( offset, 2 ) # read # offset chars from eof(represent by number '2')
lines = fp.readlines() # read from fp to eof
if len(lines) >= min_lines+1 :
for i in range(n):
res_lines.append( lines[-1*(x+m*i)].decode())
return res_lines
else:
offset *= 2 # enlarge offset
fp.seek( 0 )
lines = fp.readlines( )
if len(lines) < min_lines:
raise Exception("行数有误,请重试")
for i in range(n):
res_lines.append( lines[-1*(x+m*i)].decode())
return res_lines
print(res_lines)
except FileNotFoundError:
print(self.fpath.name + ' not found!')
return None
def get_first_line(self, ):
firstline = ''
with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'x
firstline = fp.readline()
return firstline.decode()
def get_last_line(self,filename:Path):
"""
获得最后一行
:param filename: file name
:return: last line or None for empty file
"""
try:
filesize = filename.stat().st_size
if filesize == 0:
return None
else:
with open(filename, 'rb') as fp: # to use seek from end, must use mode 'rb'
offset = -8 # initialize offset
while -offset < filesize: # offset cannot exceed file size
fp.seek(offset, 2) # read # offset chars from eof(represent by number '2')
lines = fp.readlines() # read from fp to eof
if len(lines) >= 2: # if contains at least 2 lines
return lines[-1] # then last line is totally included
else:
offset *= 2 # enlarge offset
fp.seek(0)
lines = fp.readlines()
return lines[-1]
except FileNotFoundError:
print(filename + ' not found!')
return None
def tail(file, taillines=500, return_str=True, avg_line_length=None):
"""
大文件的尾行小文件会导致报错
taillines : 读取尾部多少行
avg_line_length:每行字符平均数,
return_str:返回类型默认为字符串False为列表
offset:每次循环相对文件末尾指针偏移数
f.tell() 当前指针位置
f.seek(a,b) a 偏移量 b:0 1 2 文件头 当前位置 文件尾部
"""
with open(file, errors='ignore') as f:
if not avg_line_length:
f.seek(0, 2)
f.seek(f.tell() - 3000)
avg_line_length = int(3000 / len(f.readlines())) + 10
f.seek(0, 2)
end_pointer = f.tell()
offset = taillines * avg_line_length
if offset > end_pointer:
f.seek(0, 0)
lines = f.readlines()[-taillines:]
return "".join(lines) if return_str else lines
offset_init = offset
i = 1
while len(f.readlines()) < taillines:
location = f.tell() - offset
f.seek(location)
i += 1
offset = i * offset_init
if f.tell() - offset < 0:
f.seek(0, 0)
break
else:
f.seek(end_pointer - offset)
lines = f.readlines()
if len(lines) >= taillines:
lines = lines[-taillines:]
return "".join(lines) if return_str else lines
# def makeMsg(self,key,value):
# """
# 事件对象:制造事件
# 将事件写入event 并send
# """
# # event = eventManager.Event( type_ = eventManager.EVENT_MSG)
# event.dict[key] = value
# # 发送事件
# self.__eventManager.SendEvent(event)
if __name__ == "__main__":
d = DataPlot()
# def plot_demo( self, time_, data ,wavelength):
# '''
# @ 根据数据画demo曲线
# '''
# x = np.array( wavelength ).astype(np.float)
# datetime_ = str(time_ )
# y = np.array(data).astype(np.float)
# self.mypanel.axes.clear() # 清空上次画的内容
# self.mypanel.axes.set_title( self.axes_title )
# self.mypanel.axes.set_xlabel( self.axes_xlabel )
# self.mypanel.axes.set_ylabel( self.axes_ylabel )
# self.mypanel.axes.plot(x, y, color="green", linewidth=0.5 , label=datetime_ )
# self.mypanel.axes.legend()
# self.mypanel.axes.grid(True)
# self.mypanel.FigureCanvas.draw()
# def plot_one( self, time_, data ,wavelength):
# '''
# @ 根据数据画一条曲线
# @ 参数 data
# '''
# x = np.array( wavelength ).astype(np.float)
# datetime_ = str(time_ )
# y = np.array(data).astype(np.float)
# self.mypanel.axes.clear() # 清空上次画的内容
# self.mypanel.axes.set_title( self.axes_title )
# self.mypanel.axes.set_xlabel( self.axes_xlabel )
# self.mypanel.axes.set_ylabel( self.axes_ylabel )
# self.mypanel.axes.plot(x, y, color="green", linewidth=0.5 , label=datetime_ )
# self.mypanel.axes.legend()
# self.mypanel.axes.grid(True)
# self.mypanel.FigureCanvas.draw()
# def plotOne( self, data ):
# '''
# @ 根据数据画一条曲线
# @ 参数 data
# '''
# x = np.array( self.wavelength ).astype(np.float)
# datetime_ = data[0]
# y = np.array(data[1:]).astype(np.float)
# self.mypanel.axes.clear() # 清空上次画的内容
# self.mypanel.axes.set_title( self.axes_title )
# self.mypanel.axes.set_xlabel( self.axes_xlabel )
# self.mypanel.axes.set_ylabel( self.axes_ylabel )
# self.mypanel.axes.plot(x, y, color="green", linewidth=0.5 , label=datetime_ )
# self.mypanel.axes.legend()
# self.mypanel.axes.grid(True)
# self.mypanel.FigureCanvas.draw()
# def OnPlot(self, wl, fpath ):
# """
# * 查看历史曲线
# * 默认从最后一条记录读取
# """
# temp = self.__get_last_line( fpath ).decode().split(TOKEN)
# time_ = temp[0]
# data = temp[1:]
# # 加判断波长
# print(fpath)
# if len(data) > len( wl ):
# for i in range( len(data)-len(wl) ):
# data.pop()
# self.plot_one( time_ , data, wl )
# def plotSeven(self,wavelength,d):
# '''
# * 根据数据画七条曲线
# * 兼容数量不够七条的
# '''
# # myDebug.MyDebug.log_info( ":::::::::::: Class : %s -> Function : get_file_list " % ( __name__, ) )
# # myDebug.MyDebug.log_ctl( " d len : %s " % ( len(d), ) )
# # myDebug.MyDebug.log_ctl( " d : %s " % ( d, ) )
# x = np.array( wavelength ).astype(np.float)
# self.mypanel.axes.clear() # 清空上次画的内容
# self.mypanel.axes.set_title( self.axes_title )
# self.mypanel.axes.set_xlabel( self.axes_xlabel )
# self.mypanel.axes.set_ylabel( self.axes_ylabel )
# # 处理 data
# length = len(d)
# data = []
# for s in d:
# ss = s.split(TOKEN)
# ss0 = ss[0]
# ss1 = ss[1:]
# # 去掉尾部多余
# if len(ss1) > len( wavelength ):
# for i in range( len(ss1)-len(wavelength) ):
# ss1.pop()
# data.append( [ss0, ss1] )
# print( " data : %s " % ( len(data) , ) )
# if length >=1 :
# print( " data[0][0] %s " % (data[0][0],))
# d0 = data[0][0]
# y0 =np.array(data[0][1]).astype(np.float)
# self.mypanel.axes.plot(x, y0, 'r', linewidth=0.5 , label = d0 )
# # len(data) =2
# if len(data) >=2 :
# d1 = data[1][0]
# y1 =np.array(data[1][1]).astype(np.float)
# self.mypanel.axes.plot(x, y1, color='orange', linewidth=0.5 , label=d1 )
# # len(data) =3
# if len(data) >=3 :
# d2 = data[2][0]
# y2 =np.array(data[2][1]).astype(np.float)
# self.mypanel.axes.plot(x, y2, 'y', linewidth=0.5 , label=d2 )
# # len(data) =4
# if len(data) >=4 :
# d3 = data[3][0]
# y3 =np.array(data[3][1]).astype(np.float)
# self.mypanel.axes.plot(x, y3, 'g', linewidth=0.5 , label=d3 )
# # len(data) =5
# if len(data) >=5 :
# d4 = data[4][0]
# y4 =np.array(data[4][1]).astype(np.float)
# self.mypanel.axes.plot(x, y4, 'c', linewidth=0.5 , label=d4 )
# # len(data) =6
# if len(data) >=6 :
# d5 = data[5][0]
# y5 =np.array(data[5][1]).astype(np.float)
# self.mypanel.axes.plot(x, y5, 'b', linewidth=0.5 , label=d5 )
# # len(data) =7
# if len(data) >=7 :
# d6 = data[6][0]
# y6 =np.array(data[6][1]).astype(np.float)
# self.mypanel.axes.plot(x, y6, color='purple', linewidth=0.5 , label=d6 )
# self.mypanel.axes.legend()
# self.mypanel.axes.grid( True )
# self.mypanel.FigureCanvas.draw()
# def OnPlot_7(self, wl, fpath):
# """
# 最后间隔七条
# 默认间隔数为1
# """
# result_line = []
# count = 0
# thefile = open( fpath, 'rb')
# while True:
# buffer = thefile.read(8192*1024)
# if not buffer:
# break
# count += buffer.count(b'\n')
# count = count + 1
# self.makeMsg(1, u" 文件共有 " + str(count) + " 行" )
# # self.statusBar.SetStatusText(u" 文件共有 "+str(count)+" 行",0)
# # 判断文件是否已有数据
# if count == 0:
# #print('文件没有内容!')
# self.makeMsg(2, u"数据文件没有记录!" )
# # with wx.MessageDialog(self, u"数据文件没有记录!", u"错误提示", wx.OK )as dlg:
# # dlg.ShowModal()
# elif count < 8:
# for i in range(count-1):
# result_line.append(linecache.getline( fpath, count-i).strip("\n"))
# else:
# for i in range(7):
# result_line.append(linecache.getline( fpath, count-i).strip("\n"))
# # 画7天的图像
# thefile.close()
# self.plotSeven( wl,result_line )
# def OnPlot_D(self, wl,fpath, interval, begin):
# """
# 指定位置间隔七条
# 考虑数据是否够
# """
# # print( "i am plot d")
# # self.readConfig()
# result_line = []
# count = 0
# thefile = open( fpath, 'rb')
# while True:
# buffer = thefile.read(8192*1024)
# if not buffer:
# break
# count += buffer.count(b'\n')
# count = count + 1
# self.makeMsg(1, u" 文件共有 "+str(count)+" 行" )
# # 判断文件绘图参数设置是否正确
# if count == 0:
# #print('文件没有内容!')
# self.makeMsg(2, u"数据文件没有记录!" )
# # with wx.MessageDialog(self, u"数据文件没有记录!", u"错误提示", wx.OK )as dlg:
# # dlg.ShowModal()
# elif ( interval*7 + begin ) < (count-1):
# for i in range(7):
# result_line.append( linecache.getline( fpath,count-begin-i*interval ).strip("\n") )
# else:
# for i in range( ( (count-1)-begin )//interval ):
# result_line.append(linecache.getline( fpath,count-begin-i*interval ).strip("\n") )
# # 画7天的图像
# thefile.close()
# self.plotSeven( wl, result_line )

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,32 @@
from myconfig import TOKEN
import wx
class Listctrl(wx.Panel):
'''
# 需要在 Frame 实例化一个实例
# 改变需要对实例化后的进行操作
'''
def __init__(self, parent ):
'''
* panel 初始化后的样子
'''
# self.para_setting = para
super(Listctrl,self).__init__(parent)
self.locale = wx.Locale(wx.LANGUAGE_CHINESE_SIMPLIFIED)
self.SetBackgroundColour('lightgrey')
self.box = wx.BoxSizer(wx.HORIZONTAL)
self.list_ctrl = wx.ListCtrl(self, -1, style = wx.LC_REPORT | wx.LC_SORT_DESCENDING)
self.list_ctrl.SetBackgroundColour( 'lightgrey' )
self.list_ctrl.InsertColumn(0, u'测量时间', width = 180)
self.list_ctrl.InsertColumn(1, u'花粉_Pollen', width = 180)
i = 1
self.list_ctrl.SetFont( wx.Font( 11, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False ) )
self.box.Add(self.list_ctrl,1,wx.EXPAND)
self.SetSizer(self.box)
self.Fit()

@ -0,0 +1,187 @@
#! python3
# -*- encoding: utf-8 -*-
'''
@File : myconfig.py
@Time : 2023/03/01 15:28:20
@Author : Jim @ Yiwin
@Version : 1.0
@Contact : jim@yi-win.com
@Descrip : SysConfig
'''
import yaml
from enum import Enum
from pathlib import Path
VERSION = "3.5.0"
LASTDATE = "2023-03-7"
COMPANY = u"奕枫仪器"
CURRENT_DIR = Path()
DATA_DIR = "data"
CAL_DIR = "calfile"
OUTPUT_DIR = "output"
YAML_FILE_NAME = "config.yml"
RETRIEVE_CFG_FILE = "retrieve.yml"
PURE_WATER_FNAME = "attenuation_pure_water.DAT"
FILE_MARK = ['Spectrum', 'DATA']
SAVE_EXT_NAME = ".csv"
INTERVAL = 1.0
SEPARATOR = ";"
TOKEN = ";"
NEWLINE = "\n"
class DeviceType(Enum) :
VIPER = 1
OSCAR = 2
SC6 = 3
DEVICE = {
"UIPath" : 150 ,
"UISN" : "A05D"
}
# 一次最多 256个字节,步长<128, 字节数<256,浮点数最多63个
# viper 2100 2462 352/2 = 171, 一次60个
# oscar 2100 2329 230/2 = 116 一次60个
REGISTER = {
"slaveaddress" : 1,
"functioncode" : 3,
"SNAddress" : 10, # 测试使用2980
"SNLen" : 5,
"WLBeginAddress" : 2102, # 2100+2
"DataBeginAddress" : 2614, # 2612+2
"count" : 3 #oscar 2 viper 3
}
COMSETTING = {
"port" : "COM1" ,
"baudrate" : 9600,
'bytesize' : 8,
'parity' : "N",
'stopbit' : 1
}
PLOTSETTING = {
"LineInterval" : 1 ,
"LineBegin" : 0
}
LOGSETTING= {
"LogInterval" : 1,
"RefreshInterval" : 0
}
ALGORITHM = {
"A720" : 0, # 0: 720 11项平均值法, 1: 720 附近两个点插值 2: 720 为0
"PureWater" : 0, # 0 :包含纯水系数 1: 不包含纯水系数
"PureWater2" : 0
}
RETRIEVE = {
# "Enable" : 1,
"BeginWL" : 360,
"EndWL" : 721,
"Interval" : 1
}
FILEPATH = {
"path" : ''
}
class MyConfig(object):
"""
如上预定义数据
先写一个yaml 文件出来修改后读文件数据就可以
"""
def __init__(self) -> None:
self.device_sn = ""
self.system_cfg = {}
self.cfg_path = Path()
self.yml_cfg_file = self.cfg_path.joinpath(YAML_FILE_NAME)
self.retrieve_cfg_file = Path(RETRIEVE_CFG_FILE)
self.getSystemCfg() # 默认的值
def getSystemCfg(self,)->None:
'''
获得默认的值
'''
self.system_cfg = {}
self.system_cfg.update( {"device":DEVICE} )
self.system_cfg.update( {"register":REGISTER} )
self.system_cfg.update( {"plotsetting":PLOTSETTING} )
self.system_cfg.update( {"logsetting":LOGSETTING} )
self.system_cfg.update( {"comsetting":COMSETTING} )
self.system_cfg.update( {"algorithm":ALGORITHM} )
self.system_cfg.update( {"filepath":FILEPATH} )
pass
def getDictByAttr(self, *args) -> dict:
ret = {}
if len(args) == 0:
return ret
if len(args) == 1:
if not hasattr( self, args[0] ):
return ret
tmp = getattr( self, args[0] )
if isinstance( tmp, dict ):
ret.update(tmp)
return ret
if len(args) == 2:
if not hasattr(self, args[0]):
return ret
if not isinstance(getattr(self, args[0]), dict):
return ret
tmp: dict = getattr(self, args[0])
if not tmp.__contains__(args[1]):
return ret
tmp2 = tmp[args[1]]
if isinstance(tmp2, dict):
ret.update(tmp2)
return ret
if len(args) > 2:
return ret
pass
# 设置字典对应的键值
def set_attr(self, d: dict, k, v) -> bool:
if d.__contains__(k):
d.update({k: v})
return True
return False
def write_yaml(self, d: dict):
with open(self.yml_cfg_file, "w", encoding = "utf-8") as f:
yaml.dump(d, f)
def read_yaml(self ) -> dict:
# self.write_yaml(self.system_cfg)
with open(self.yml_cfg_file, "r", encoding="utf-8") as f:
content = f.read() # conent 读出来是字符串
d = yaml.load(content, Loader=yaml.FullLoader) # 用load方法转字典
return d
def write_rtv_yaml(self, d: dict):
with open(self.retrieve_cfg_file, "w", encoding="utf-8") as f:
yaml.dump(d, f)
def read_rtv_yaml(self ) -> dict:
with open(self.retrieve_cfg_file, "r", encoding="utf-8") as f:
content = f.read() # conent 读出来是字符串
d = yaml.load(content, Loader=yaml.FullLoader) # 用load方法转字典
return d
def set_retrieve(self) -> dict:
retrieve = {}
# retrieve.update({"enable": RETRIEVE["Enable"]})
retrieve.update({"beginWL": RETRIEVE["BeginWL"]})
retrieve.update({"endWL": RETRIEVE["EndWL"]})
retrieve.update({"interval": RETRIEVE["Interval"]})
self.write_rtv_yaml(retrieve)
return retrieve
pass
if __name__ == "__main__":
pass

@ -0,0 +1,14 @@
class TCPIPException(Exception):
def __init__(self, message="TCPIP 自定义异常"):
self.message = "TCPIP exception : " + message
class SerialException(Exception):
def __init__(self, message="Serial 自定义异常"):
self.message = "serial exception : " + message
class MyException(Exception):
def __init__(self, message=" 自定义异常"):
self.message = "自定义异常: " + message

@ -0,0 +1,285 @@
# coding=utf-8
'''
单例模式日志 -- 使用一次关闭 handler
这种方法优缺点
缺点 输出的format 需要自己定义 并过滤
过滤要看是否以什么开头或包含什么
优点 不占用文件资源占用系统资源小
调用 log.info( ) log.error()
'''
import logging
import logging.handlers
import os
import time
import threading
# from config import LOG_PATH,LOG_LEVEL,LOG_ENABLED,LOG_FORMAT, \
# LOG_TO_CONSOLE,LOG_TO_FILE
MY_LOGGER_NAME = "DefaultLogger"
LOG_ENABLED = True # 是否启用日志
LOG_TO_CONSOLE = True # 是否启用控制台输出日志
LOG_TO_FILE = False # 是否启用文件输出
LOG_COLOR_ENABLE = True # 是否启用颜色日志
LOGGER_DIR = "logs"
LOGGER_PATH = os.path.join( os.path.dirname(__file__), LOGGER_DIR )
LOGGER_FILENAME = os.path.join( LOGGER_PATH, 'logs.log' )
"""
logging.INFO , logging.DEBUG , logging.WARNING , logging.ERROR ,
"""
LOG_LEVEL = logging.INFO # 日志等级DEBUG INFO WARNIG ERROR
# LOG_LEVEL = logging.DEBUG
# LOG_LEVEL = logging.WARNING
"""
# LOG_FORMAT = " %(name)s - %(module)s - %(filename)s - %(lineno)d | %(levelname)s : %(message)s"
# LOG_FORMAT = "%(levelname)s - %(asctime)s - process: %(process)d - threadname: %(thread)s " \
# "- %(filename)s - %(funcName)s - %(lineno)d - %(module)s " \
# "- %(message)s "
# LOG_FORMAT = "%(asctime)s - %(thread)s " \
# "- %(levelname)s ::: %(message)s "
# '[%(asctime)s] |%(thread)s| %(levelname)-6s: %(message)s'
# fm = '%(levelname):%(levelno)s:%(name)s:%(funcName)s:%(asctime):%(pathname):%(filename):%(module):%(thread):%(threadName)'
# 此处日志颜色,修改日志颜色是通过 Filter实现的
"""
LOG_FORMAT = '%(levelname)s\t[%(asctime)s] %(package)s:%(classname)s:%(funcname)s \t>> %(message)s'
"""
# 此处日志颜色,修改日志颜色是通过 Filter实现的
"""
LOG_FORMAT_COLOR_DICT = {
'ERROR' : "\033[31mERROR\033[0m",
'INFO' : "\033[36mINFO\033[0m",
'DEBUG' : "\033[1mDEBUG\033[0m",
'WARN' : "\033[33mWARN\033[0m",
'WARNING' : "\033[33mWARNING\033[0m",
'CRITICAL': "\033[35mCRITICAL\033[0m",
}
"""
# Filter 用法, 以package class function 过滤 __package__ __class__
# log.error( f"{__package__}::{__class__.__name__}::{sys._getframe().f_code.co_name} >> ")
# log.error( f"PacakgeName::ClassName::FunctionName:: ")
# LOGGER_FILTER_PACKAGE=[] 为空, 则Filter不起作用
# 不为空,则只显示定义的报名
# LOGGER_FILTER_CLASS=[] 为空, 则Filter不起作用
# 不为空,则只显示定义的类或
# LOGGER_FILTER_FUNCNAME=[] 为空, 则Filter不起作用
# 不为空,则只显示定义的函数
"""
# LOGGER_FILTER_PACKAGE = [ "test_logger" ] # 包名,文件名去 .py??
LOGGER_FILTER_PACKAGE = [ ]
LOGGER_FILTER_CLASS = [ ] # 类名,文件名去 .py??
# LOGGER_FILTER_CLASS = [ "LogTest" ]
# LOGGER_FILTER_FUNCNAME = [ "test1","test" ] # 函数名
LOGGER_FILTER_FUNCNAME = [ ]
LOGGER_FILTER_LEVELNAME = [ ] # INFO DEBUG WARNING
class PackageFilter(logging.Filter):
def __init__(self, filter_word:list = []):
self.filter_word = filter_word
pass
def filter(self, record: logging.LogRecord) -> bool:
if self.filter_word is not None:
return record.package in self.filter_word
class ClassFilter(logging.Filter):
def __init__(self, filter_word:list = []):
self.filter_word = filter_word
pass
def filter(self, record: logging.LogRecord) -> bool:
if self.filter_word is not None:
return record.classname in self.filter_word
pass
class FunctionFilter(logging.Filter):
def __init__(self, filter_word:list = []):
self.filter_word = filter_word
pass
def filter(self, record:logging.LogRecord) -> bool:
if self.filter_word is not None:
return record.funcname in self.filter_word
class LevelNameFilter(logging.Filter):
def __init__(self, filter_word:list = []):
self.filter_word = filter_word
pass
def filter(self, record:logging.LogRecord) -> bool:
if self.filter_word is not None:
return record.levelname in self.filter_word
class ColorFilter(logging.Filter):
def __init__(self,):
pass
def filter(self, record: logging.LogRecord) -> bool:
record.levelname = LOG_FORMAT_COLOR_DICT.get(record.levelname)
return True
class Log(object):
_instance_lock = threading.Lock()
def __new__(cls, *args, **kwargs):
if not hasattr(Log, "_instance"):
with Log._instance_lock:
if not hasattr(Log, "_instance"):
Log._instance = object.__new__(cls)
return Log._instance
def __init__(self, loggername = "DefaultLog" ):
# 文件命名 os.path.join(): 将多个路径组合后返回
self.logger_filepath = LOGGER_FILENAME
self.loggername = loggername
self.level = LOG_LEVEL
# 日志输出格式
fm = LOG_FORMAT
self.formatter = logging.Formatter( fm )
# 生成记录器对象
self.logger = logging.getLogger( self.loggername )
self.logger.setLevel(LOG_LEVEL)
# 日志过滤
self.__add_filter()
def __console(self, level, message, extra={} ):
# 添加 handler
self.__add_handler()
# 判断日志级别
if level == logging.INFO:
self.logger.info( message, extra=extra)
elif level == logging.DEBUG:
self.logger.debug(message,extra=extra)
elif level == logging.WARNING:
self.logger.warning(message,extra=extra)
elif level == logging.ERROR:
self.logger.error(message,extra=extra)
# removeHandler在记录日志之后移除句柄,避免日志输出重复问题
self.__remove_handler()
# if LOG_TO_FILE and self.file_handler:
# self.logger.removeHandler(self.file_handler)
# # 关闭打开的文件
# self.file_handler.close()
# if LOG_TO_CONSOLE and self.stream_handler:
# self.logger.removeHandler(self.stream_handler)
# # 关闭打开的文件
# self.stream_handler.close()
pass
# debug < info< warning< error< critical
# debug模式
def debug(self, message, package="Unknown", classname="Unknown", funcname="Unknown" ):
self.__console(logging.DEBUG, message, extra={"package":package, "classname":classname, "funcname":funcname} )
# self.__remove_handler()
# info模式
def info(self, message, package="Unknown", classname="Unknown", funcname="Unknown" ):
self.__console(logging.INFO, message, extra={"package":package, "classname":classname, "funcname":funcname} )
# self.__remove_handler()
# warning模式
def warning(self, message, package="Unknown", classname="Unknown", funcname="Unknown"):
self.__console(logging.WARNING, message, extra={"package":package, "classname":classname, "funcname":funcname} )
# self.__remove_handler()
# error模式
def error(self, message, package="Unknown", classname="Unknown", funcname="Unknown"):
self.__console(logging.ERROR, message, extra={"package":package, "classname":classname, "funcname":funcname} )
# self.__remove_handler()
def __add_filter(self ):
if len( LOGGER_FILTER_PACKAGE ) > 0 :
self.logger.addFilter( PackageFilter( filter_word=LOGGER_FILTER_PACKAGE ) )
if len( LOGGER_FILTER_CLASS ) > 0 :
self.logger.addFilter( ClassFilter( filter_word=LOGGER_FILTER_CLASS ) )
if len( LOGGER_FILTER_FUNCNAME ) > 0 :
self.logger.addFilter( FunctionFilter( filter_word=LOGGER_FILTER_FUNCNAME ) )
if len(LOGGER_FILTER_LEVELNAME) > 0 :
self.logger.addFilter( LevelNameFilter( filter_word=LOGGER_FILTER_LEVELNAME ) )
def __add_handler(self ):
if LOG_ENABLED and LOG_TO_FILE:
# 考虑使用 RotatingFileHandler TimedRotatingFileHandler防止日志过大
# RotatingFileHandler("test", "a", 4096, 2, "utf-8")
# TimedRotatingFileHandler(filename=LOG_PATH+"thread_", when="D", interval=1, backupCount=7)
self.file_handler = logging.handlers.TimedRotatingFileHandler(filename=self.logger_filepath, when='D', interval=1, backupCount=30, encoding='utf-8')
# self.file_handler = logging.FileHandler( self.logger_filepath, encoding='utf-8' )
self.file_handler.setFormatter( self.formatter )
# self.file_handler.setLevel( LOG_LEVEL )
# if LOG_COLOR_ENABLE: # 文件日志无需加彩色
# self.file_handler.addFilter( ColorFilter( ) )
self.logger.addHandler(self.file_handler)
if LOG_ENABLED and LOG_TO_CONSOLE:
# 创建一个StreamHandler,用于输出到控制台
self.stream_handler = logging.StreamHandler()
self.stream_handler.setFormatter(self.formatter)
# self.stream_handler.setLevel( LOG_LEVEL )
if LOG_COLOR_ENABLE:
self.stream_handler.addFilter( ColorFilter( ) )
self.logger.addHandler(self.stream_handler)
def __remove_handler(self ):
if LOG_TO_FILE and self.file_handler:
self.logger.removeHandler(self.file_handler)
if len(self.logger.handlers)>0:
self.logger.handlers.pop()
# 关闭打开的文件
self.file_handler.close()
if LOG_TO_CONSOLE and self.stream_handler:
self.logger.removeHandler(self.stream_handler)
if len(self.logger.handlers)>0:
self.logger.handlers.pop()
# 关闭控制台
self.stream_handler.close()
def __remove_handler2(self ):
if LOG_ENABLED and LOG_TO_CONSOLE:
self.logger.removeHandler(self.stream_handler)
self.logger.handlers.pop()
# 关闭控制台
self.stream_handler.close()
if LOG_ENABLED and LOG_TO_FILE:
self.logger.removeHandler(self.file_handler)
self.logger.handlers.pop()
# 关闭打开的文件
self.file_handler.close()
log = Log( loggername = "DefaultLog")
"""
filename: 指定日志文件名
filemode: 和file函数意义相同指定日志文件的打开模式wa
format: 指定输出的格式和内容format可以输出很多有用信息显示的条目可以是以下内容
%(levelname) 日志级别的名字格式
%(levelno)s 日志级别的数字表示
%(name)s 日志名字 loggername
%(funcName)s 函数名字
%(asctime) 日志时间可以使用datefmt去定义时间格式如上图
%(pathname) 脚本的绝对路径
%(filename) 脚本的名字
%(module) 模块的名字
%(thread): thread id
%(threadName) 线程的名字
"""
"""
文件名行号 函数名, 要在调用的时候想办法了
# 绝对路径
print( __file__ )
print( sys.argv[0] )
# 文件名
print( os.path.basename(__file__) )
print( os.path.basename(sys.argv[0]) )
self.__class__.__name__
self.__class__.__name__, get_current_function_name()
logger名 __name__
"""

@ -0,0 +1,137 @@
import wx
import numpy as np
from enum import Enum
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas #FigureCanvasWxAgg
from matplotlib.backends.backend_wx import NavigationToolbar2Wx as NavigationToolbar # FIgure 导航
from matplotlib.figure import Figure
class LineColor(Enum):
RED = 0
ORANGE = 1
YELLOW = 2
GREEN = 3
CYAN = 4
BLUE = 5
PURPLE = 6
class Plot(wx.Panel):
'''
# 需要在 Frame 实例化一个实例
# 改变需要对实例化后的进行操作
'''
'''
Matplotlib Panel 单独拿出来画图
可以 __do_layout
可以 __add_widgets
可以 button事件
可以鼠标事件
'''
def __init__(self,parent):
'''
* panel 初始化后的样子
'''
super(Plot,self).__init__(parent)
# 本地化语言
self.locale = wx.Locale(wx.LANGUAGE_CHINESE_SIMPLIFIED)
self.Figure = Figure(figsize=(4,3)) # 4,3 为英寸
self.axes = self.Figure.add_axes([0.1,0.1,0.8,0.8],facecolor="lightgray") # 坐标系起始位置
self.FigureCanvas = FigureCanvas(self,-1,self.Figure)
#继承鼠标移动显示鼠标处坐标的事件
# self.FigureCanvas.mpl_connect('motion_notify_event',self.MPLOnMouseMove)
# self.NavigationToolbar = NavigationToolbar(self.FigureCanvas)
# self.StaticText = wx.StaticText(self,-1,label=u'坐标信息')
# self.SubBoxSizer = wx.BoxSizer(wx.HORIZONTAL)
# self.SubBoxSizer.Add(self.NavigationToolbar,proportion =0, border = 2,flag = wx.ALL | wx.EXPAND)
# self.SubBoxSizer.Add(self.StaticText,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND)
self.TopBoxSizer = wx.BoxSizer(wx.VERTICAL)
# self.TopBoxSizer.Add(self.SubBoxSizer,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND)
self.TopBoxSizer.Add(self.FigureCanvas,proportion =-10, border = 2,flag = wx.ALL | wx.EXPAND)
self.SetSizer(self.TopBoxSizer)
self.purewater_legend = ("Pure Water Attenuation Coefficient"
,"Wavelength (nm)"
,"Attenuation Coefficient m(-1)" )
def set_axes_title(self,title):
self.axes.set_title(title)
def set_axes_xlabel(self,x):
self.axes.set_xlabel(x)
def set_axes_ylable(self,y):
self.axes.set_ylabel(y)
def set_title_x_y(self,title, x, y):
self.axes.set_title(title)
self.axes.set_xlabel(x)
self.axes.set_ylabel(y)
def plot_one( self, time_, wavelength:np.ndarray, data:np.ndarray, color="green" ):
self.axes.plot(wavelength, data, color=color, linewidth=0.5 , label=time_ )
self.axes.legend( )
self.axes.grid( True )
self.FigureCanvas.draw()
def plot_multi( self, time_, wavelength:np.ndarray, data:np.ndarray ):
len_ = len(data)
for i in range(len_):
self.axes.plot(wavelength, data[i], color=LineColor(i).name.lower(), linewidth=0.5 , label=time_[i] )
# self.axes.legend(time_)
self.axes.grid(True)
self.FigureCanvas.draw()
def clear_past( self, ):
self.axes.clear()
# def MPLOnMouseMove(self,event):
# '''
# * 显示坐标值
# '''
# ex=event.xdata#这个数据类型是numpy.float64
# ey=event.ydata#这个数据类型是numpy.float64
# if ex and ey :
# #可以将numpy.float64类型转化为float类型,否则格式字符串可能会出错
# self.StaticText.SetLabel('%10.5f,%10.5f' % (float(ex),float(ey)))
class MyPanel(wx.Panel):
"""docstring for MyPanel."""
def __init__(self, *arg, **kwarg):
super(MyPanel, self).__init__( *arg,**kwarg)
self.SetBackgroundColour("#F2F2F2")
self.sb = wx.StaticBox( self, label='系统信息', pos = (30,30) )
self.sbs = wx.StaticBoxSizer( self.sb, orient=wx.VERTICAL )
self.vbox1 = wx.BoxSizer(wx.VERTICAL)
self.staticText0 = wx.StaticText(self , label='',size=(60, 30), style=wx.ALIGN_CENTRE_VERTICAL )
self.staticText1 = wx.StaticText(self, -1,size=(600, -1),
label='''\n上海奕枫仪器设备有限公司
\n电话: 021-54270075
\n网站: http://www.yi-win.com
\n邮件: sales@yi-win.com
\n描述: AWRAMS离线数据处理 ''' )
self.vbox1.Add(self.staticText0, flag=wx.TOP|wx.LEFT, border=5)
self.vbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
# self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
# self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.vbox1, flag=wx.TOP|wx.LEFT, border= 5)
self.SetSizer(self.sbs)
def setStaticText(self, msg:str):
self.staticText1.SetLabel(msg)

@ -0,0 +1,277 @@
from pathlib import PurePath, Path
# from myconfig import NEWLINE,TOKEN,SEPARATOR
"""
"""
class MyDir(object):
"""
操作方法:设置base tuple_dir header
设置的是路径, 文件名要 ifNotNewFile 传入
调用方法
self.mydir.setBaseDir(path)
self.mydir.newDirIfNot()
self.mydir.newFileIfNot(file_name)
self.mydir.setHeader(header_list, TOKEN, header_str)
if self.mydir.checkHeader() == 0:
self.mydir.writeHeader()
if self.mydir.checkHeader() == -1:
pass
self.mydir.setContent(header_list, TOKEN, header_str)
self.mydir.writeContent()
"""
def __init__(self) -> None:
self.base_dir = Path()
self.dir_tuple = ()
self.header = []
self.header_str = ""
self.content = []
self.content_str = ""
self.current_dir = None
self.current_filepath = None
pass
def getDir(self,):
return self.current_dir
pass
def setBaseDir(self, dir: Path):
self.base_dir = dir
self.current_dir = self.base_dir
pass
def setDir(self, t:tuple=()):
self.dir_tuple = t
if len(self.dir_tuple) == 0 :
self.current_dir = self.base_dir
else:
self.current_dir = self.base_dir.joinpath( *t )
pass
def getDirFromBaseAndTuple(self, base_dir:Path, dir_tuple: tuple):
'''外部调用返回路径'''
ret_path = base_dir
t = dir_tuple
if len(t) == 0 :
ret_path = ret_path
else:
ret_path = ret_path.joinpath( *t )
return ret_path
pass
def setHeader(self, headerlist:list, headerSeperator: str = ";", headerinfo: str = None):
header_str = ""
if len(headerlist) == 0:
return
if headerinfo != None:
header_str = headerinfo + headerSeperator
for hl in headerlist:
header_str = header_str + str(hl) + headerSeperator
self.header_str = header_str[:-1]
pass
def setContent(self, contentlist: list, contentSeperator: str = ";", contentinfo: str = None):
content_str = ""
if len(contentlist) == 0:
return
if contentinfo != None:
content_str = contentinfo + contentSeperator
tmp_str = ""
for cl in contentlist:
tmp_str = tmp_str + str(cl) + contentSeperator
self.content_str = content_str + tmp_str[:-1]
pass
def newDirIfNot(self,) -> None:
# self.current_path = self.base_path.joinpath(self.path_tuple)
self.current_dir.mkdir(parents=True, exist_ok=True)
pass
def newFileIfNot(self, fname: str) -> None:
self.newDirIfNot()
self.current_filepath = self.current_dir.joinpath(fname)
if not self.current_filepath.exists():
with open(self.current_filepath, 'a') as f:
pass
return
pass
def getCurrentFileSize(self,):
return self.current_filepath.stat().st_size
def getFirstline(self,):
first_line = ""
with open(self.current_filepath, 'r') as f: # 打开文件
first_line = f.readline() # 取第一行
return first_line.strip('\n').strip('\r')
def checkHeader(self,) -> int:
'''
返回:
0 : 文件为空,可以直接写header
1 : header对应上 无需处理
-1: 需要提醒用户保存数据后,删除文件后再处理
'''
if self.getCurrentFileSize() == 0:
return 0
first_line = self.getFirstline()
# print(f"firstline: {first_line}" )
# print(f"header_str: {self.header_str}" )
if first_line == self.header_str:
return 1
return -1
pass
def writeHeader(self,) -> None:
with open(self.current_filepath, "a") as f:
f.write(self.header_str)
return None
pass
def writeContent(self,new_line="\n") -> None:
with open(self.current_filepath, "a") as f:
f.write(new_line+self.content_str)
return None
pass
def is_dir_empty(self, ):
'''文件夹是否为空'''
has_next = next(self.current_dir.iterdir(), None)
if has_next is None:
return True
return False
def is_file_empty(self,):
'''文件是否为空'''
if self.current_dir.stat().st_size ==0:
return True
return False
def deleteDir(self,):
'''文件夹是否为空'''
try:
if self.current_dir.exists():
self.current_dir.rmdir()
except OSError as e:
raise Exception(e)
return True
## 其他需求
def get_child_dir(self,) -> list:
ret = []
tmp_dir = self.current_dir.glob("**/")
for td in tmp_dir:
if td.is_dir():
ret.append(td.relative_to(self.current_dir))
return ret
pass
def get_child_dir_only(self,) -> list:
ret = []
for d in self.current_dir.iterdir():
if d.is_dir():
ret.append(d.relative_to(self.current_dir))
return ret
pass
def get_files_from_currentdir(self, fmt:str="*/*" ) -> list:
'''fmt: * */* */*/*'''
ret = []
tmp_dir = self.current_dir.glob(fmt)
print(tmp_dir)
for td in tmp_dir:
if td.is_file():
ret.append(td)
return ret
pass
def sort_dir_and_check( self, dirs:list ):
'''相对目录排序,目录最后一级'''
ret = []
if len(dirs) == 0:
return ret
tmp = {}
tmp_lst = []
for d in dirs:
last:str = d.parts[-1]
if last.isdigit() :
tmp.update( {last:d} )
tmp_lst.append(int(last))
pass
tmp_lst.sort()
for t in tmp:
ret.append(tmp.get(str(t)))
pass
return ret
def sort_filepath_and_check(self, path_files:list):
'''相对目录排序,目录最后一级'''
ret = []
if len(path_files) == 0:
return ret
tmp = {}
tmp_lst = []
for d in path_files:
last:str = d.stem
if last.isdigit() :
tmp.update( {last:d} )
tmp_lst.append(int(last))
pass
tmp_lst.sort()
for t in tmp:
ret.append(tmp.get(str(t)))
pass
return ret
def group_and_sort_filepath(self,path_files:list):
ret = {}
# dirs_lst = []
# len_files = len(path_files)
# if len_files == 0:
# return False
# for pf in path_files:
# pf_dir:str = pf.parts[-2]
# if pf_dir.isdigit() and int(pf_dir) not in dirs_lst:
# dirs_lst.append( int(pf_dir) )
# dirs_lst.sort()
def check_dirs(self, dirs:list, begin:int =0, step:int=1):
'''检查目录是否从begin开始递增'''
len_dirs = len(dirs)
if len_dirs == 0:
return False
for i in range(begin,len_dirs,step) :
if dirs[i].parts[-1] != str(i) :
return False
return True
def check_path_files(self,path_files:list,begin:int =0, step:int=1):
'''检查文件名从begin开始递增'''
len_files = len(path_files)
if len_files == 0:
return False
for i in range(begin,len_files,step) :
if path_files[i].stem != str(i) :
return False
return True
if __name__ == "__main__":
mp = MyDir()
mp.setBaseDir(Path())
print(mp.current_dir)
# t = ("test_dir","1","11")
t = ("test_dir", )
mp.setDir( t )
print(mp.current_dir)
cd = mp.get_child_dir_only()
c = mp.sort_dir_and_check(cd)
print(cd )
print(c )

@ -0,0 +1,126 @@
import threading
import time
class Mythead(threading.Thread):
'''线程守护'''
def __init__(self ):
super(Mythead, self).__init__()
pass
def set_task(self, func, *args):
self.func = func
self.args = args
def run(self):
# print(f" --- {len(self.args)}")
if len(self.args) > 0:
self.func(self.args)
else:
self.func( )
class Multithread(threading.Thread):
'''
多线程
子线程.join() -> ( 设置在start之后, 等所有阻塞线程运行完, 再运行主线程 )
子线程.setDaemon(True) -> 设置子线程A为守护线程, 主线程所在的进程内所有非守护线程统统运行完毕,
无论子线程A有没有结束, 程序都结束
Method:
'''
def __init__(self):
super(Multithread, self).__init__()
self.__tasks = []
self.act = []
# self.__block = False
pass
# def set_task( self, tasks ):
# self.__tasks = tasks
def add_task(self, func, daemon=False, join=True,args=()):
tmp_dict = {}
tmp_dict.update( {"func" : func})
if daemon == True:
tmp_dict.update( {"daemon" : True})
else:
tmp_dict.update( {"daemon" : False})
if join == True:
tmp_dict.update( {"join" : True})
else:
tmp_dict.update( {"join" : False})
if args == ():
tmp_dict.update( {"args" : ()})
else:
tmp_dict.update( {"args" : args})
self.__tasks.append( tmp_dict )
def remove_tasks(self, ):
self.__tasks = []
self.act = []
def add_task_2_act(self, task):
t = threading.Thread( target = task['func'], args = task['args'] )
self.act.append(t)
t.start()
def execute_one_act(self,i):
if self.__tasks[i]['join']:
self.act[i].join() # 子线程阻塞完毕再运行主线程
pass
def prepare_tasks(self):
self.act = []
for task in self.__tasks:
self.add_task_2_act(task)
def execute_tasks(self):
try:
for i in range( len(self.act) ):
self.execute_one_act( i )
pass
except Exception as e:
print(e)
def prepare_tasks(self):
self.act = []
for task in self.__tasks:
t = threading.Thread( target = task['func'], args = task['args'] )
self.act.append(t)
t.start()
def simultaneously_execute_tasks(self):
self.prepare_tasks()
self.execute_tasks()
def sequently_execute_tasks(self):
for task in self.__tasks:
t = threading.Thread( target = task['func'], args = task['args'] )
t.start()
t.join()
def t1(self):
print("thread1...")
time.sleep(10)
print("thread1... after sleep...")
def t2(self):
print("thread2...")
time.sleep(5)
print("thread2... after sleep...")
def t3(self):
print("thread3...")
time.sleep(3)
print("thread3... after sleep...")
if __name__ == '__main__':
mt = Multithread()
mt.add_task(mt.t1)
mt.add_task(mt.t2)
mt.add_task(mt.t3)
# mt.prepare_tasks() # 线程同步运行
# mt.execute_tasks()
# mt.simultaneously_execute_tasks()
mt.sequently_execute_tasks()

@ -0,0 +1,71 @@
from datetime import datetime, timedelta
# import locale
# locale.setlocale(locale.LC_ALL, '')
TIME_STR = "2022-06-10 16:16:16"
STD_TIME_STR_FMT = "%Y-%m-%d %H:%M:%S" # 小写y是两位年份
CUR_TIME_STR_FMT = "%Y-%m-%d %H:%M:%S"
class MyTime(object):
"""
操作方法:设置base tuple_path header
调用方法
self.mytime = Mytime()
self.mytime.setCurrentTimeStrFmt()
print(self.mytime.cur_datetime)
s
"""
def __init__(self) -> None:
self.cur_time_str_fmt = "%Y-%m-%d %H:%M:%S"
self.std_time_str_fmt = "%Y-%m-%d %H:%M:%S"
self.cur_time_str = ""
self.std_time_str = ""
self.cur_datetime = ""
pass
def setCurrentTimeStrFmt(self, s):
self.cur_time_str_fmt = s
pass
def setStdTimeStrFmt(self, s):
self.std_time_str_fmt = s
pass
def setCurrentTimeStr(self, s):
self.cur_time_str = s
self.cur_datetime = datetime.strptime(self.cur_time_str, self.cur_time_str_fmt)
pass
def setStdTimeStr(self, s):
self.std_time_str = s
self.cur_datetime = datetime.strptime(
self.std_time_str, STD_TIME_STR_FMT)
pass
def Current2STD(self):
# self.cur_datetime = datetime.strptime(self.cur_time_str , CUR_TIME_STR_FMT)
self.std_time_str = datetime.strftime(
self.cur_datetime, STD_TIME_STR_FMT)
pass
def STD2Current(self, format: str):
# self.cur_datetime = datetime.strptime(self.std_time_str , STD_TIME_STR_FMT)
self.cur_time_str = datetime.strftime(
self.cur_datetime, CUR_TIME_STR_FMT)
pass
def timeDelta(self, days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0):
self.cur_datetime = self.cur_datetime + \
timedelta(days=0, seconds=0, microseconds=0,
milliseconds=0, minutes=0, hours=0, weeks=0)
pass
if __name__ == "__main__":
s = "2023-02-07 14:02:46"
mt = MyTime()
mt.setCurrentTimeStr(s)
print(mt.cur_datetime)
pass

File diff suppressed because it is too large Load Diff

@ -0,0 +1,3 @@
beginWL: 360
endWL: 721
interval: 1

@ -0,0 +1,200 @@
import serial
import struct
import time
class Uart(object):
def __init__(self,):
self.ser = serial.Serial()
self.__buf = b''
self.command = b''
self._is_connected = False
self.begin_time = None
pass
def set_serial_para(self, port="COM1",baudrate=9600,bytesize=8,parity="N", stopbit=1, timeout = 4):
self.port = port
self.ser.port = port
self.ser.baudrate = baudrate
self.ser.bytesize = bytesize
self.ser.parity = parity
self.ser.stopbits = stopbit
self.ser.timeout = timeout
def set_modbus(self, slaveaddress=1, functioncode=3, beginaddress=0, step=5 ):
self.slaveaddress = slaveaddress
self.functioncode = functioncode
self.beginaddress = beginaddress
self.step = step
self.command = self.__get_modbus_command()
self.rcv_len = 2*self.step + 5 # 16bit
def connect(self,):
try:
self.ser.open()
if self.ser.isOpen():
self._is_connected = True
self.ser.close()
except Exception as e:
self._is_connected = False
# SerialException(f"KH3000 can not open port : {self.ser.port}")
if self.ser is not None and self.ser.isOpen():
self.ser.close()
return self._is_connected
def disconnect(self,):
if self._is_connected or self.ser.isOpen():
self.ser.close()
self._is_received = False
self._is_connected = False
pass
def write(self,) -> None:
try:
self.ser.open()
if self.ser.isOpen():
self.ser._is_connected = True
except Exception as e:
self.ser. _is_connected = False
if self.ser._is_connected:
self.begin_time = time.time()
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
# print(f"========= command {self.command.hex() }")
self.ser.write(self.command)
# if isHex:
# data = bytes.fromhex(data)
# self.ser.write(bytes(data))
# else:
# self.ser.write(bytes(data, encoding='utf8')+b'\x0A\x0D')
def receive(self,):
self.flush()
while 1:
if not self._is_receiving:
break
if self.ser.in_waiting: # 这个接收是随机的
for _ in range(self.ser.in_waiting):
# print( type(_serial.read(1)))
temp = self.ser.read(1) # 可以直接读取指定长度
self.__buf = self.__buf + temp
if len(self.__buf) >= self.rcv_len:
break
if time.time() - self.begin_time > self.ser.timeout:
self.__buf = b''
break
self._is_receiving = False
def OneMeasure(self) -> bytes:
if not self.ser.isOpen():
self.ser.open()
self._is_receiving = True
self.__buf = b''
self.receive()
if len(self.__buf)>=self.rcv_len and not self._is_receiving :
return self.__buf
return b''
pass
def reset_input_buffer(self)->None:
self.ser.reset_input_buffer()
pass
def reset_output_buffer(self)->None:
self.ser.reset_output_buffer()
pass
def flush(self)->None:
self.ser.flush()
pass
def IsOpen(self)->bool:
return self._is_connected
pass
def IsReceived(self)->bool:
return self._is_received
pass
def getResult(self)->bytes:
return self.__buf
pass
def add_crc16( self, buf:bytes ):
'''
一般发送命令都是'01030000000A'这样的字符串
输入test2 = '01030000000A'
输出0xc5cd
hexstr[2:].upper() 去掉
'''
crc = 0xFFFF
for pos in buf:
crc ^= pos
for i in range(8):
if ((crc & 1) != 0):
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
return ((crc & 0xff) << 8) + (crc >> 8)
# return hex(((crc & 0xff) << 8) + (crc >> 8))[2:].upper()
def crc16Check(self,buf:bytes):
if len(buf) > 4 :
crc = self.add_crc16(buf[:-2])
if (crc & 0xff) == buf[-1] and (crc >> 8)== buf[-2]:
return True
else:
return False
else:
return False
def __get_modbus_command(self, ):
res = b''
res = res + self.slaveaddress.to_bytes(1, byteorder="big")
res = res + self.functioncode.to_bytes(1, byteorder="big")
res = res + self.beginaddress.to_bytes(2, byteorder="big")
res = res + self.step.to_bytes(2, byteorder="big")
crc = self.add_crc16(res)
hi = (crc >> 8).to_bytes(1, byteorder="big")
lo = (crc & 0xff).to_bytes(1, byteorder="big")
return res + hi + lo
pass
if __name__ == '__main__':
# 字符串转字节
u = Uart()
s = "01030000000A"
sss = b'\x01\x03\x00\x00\x00\x0A\xC5\xCD'
print(bytes.fromhex(s))
print(bytearray.fromhex(s))
print( u.add_crc16(bytes.fromhex(s)) )
print("00000000000000000000000000000000000")
print(sss[:-2])
if u.crc16Check(sss):
print("TRUE,...")
else:
print("fffffffffffff")
# 数字转字节
a = 1024
b=a.to_bytes(2, byteorder='big') # 2个字节
a.from_bytes(b'\x04\x00', byteorder='big')
# ASCIIunpack
data = "a"
bytes(data, encoding='utf8')
# struct 打包转字节
ss = struct.pack('>H', 8) # unpack
print(ss)
pass

@ -0,0 +1,110 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import wx
# from configobj import ConfigObj
from myconfig import MyConfig
from myconfig import YAML_FILE_NAME
class UI_Algorithm(wx.Dialog):
"""
@description : 算法配置
"""
def __init__(self, parent, id):
# 串口页面配置
super(UI_Algorithm, self).__init__( parent ,id = id )
self.config = MyConfig()
self.InitUI()
self.SetSize((400, 400))
self.SetTitle(" 算法配置 ")
def InitUI(self):
self.config_yml = self.config.read_yaml()
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sb = wx.StaticBox(self.panel, label='算法配置')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel, label='浊度校正 ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL )
self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) )
tmp = self.get_str_from_config( "algorithm", "A720" )
if tmp is not None:
self.textCtrl1.SetValue(tmp)
self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5)
self.hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText2 = wx.StaticText(self.panel, label='包含纯水: ' ,size=(60, -1))
# self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config( "algorithm", "2" )
if tmp is not None:
self.textCtrl2.SetValue(tmp)
self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox3 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText3 = wx.StaticText(self.panel, label='纯水: ' ,size=(60, -1))
# self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl3 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config( "algorithm", "3" )
if tmp is not None:
self.textCtrl3.SetValue(tmp)
self.hbox3.Add(self.staticText3, flag=wx.TOP|wx.LEFT, border=5)
self.hbox3.Add(self.textCtrl3,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox3, flag=wx.TOP|wx.LEFT, border=5)
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'保存配置')
self.closeButton = wx.Button(self, label='Close')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5)
# 添加 vbox 到panel
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def get_str_from_config( self, section, key ):
return str(self.config_yml[section][key])
pass
def set_config_by_section_key_val( self, section, key, val ):
# print(f" {key} current type {type( self.config_yml[section][key] )}")
if type( self.config_yml[section][key] ) == int:
self.config_yml[section][key] = int(val)
elif type( self.config_yml[section][key] ) == float:
self.config_yml[section][key] = float(val)
else:
self.config_yml[section][key] = val
pass
def saveData(self, e):
pass
def OnClose(self, e):
self.Destroy()
def OnSave(self, e):
success = True
# 赋值字典,写入文件
self.set_config_by_section_key_val( 'algorithm',"1",self.textCtrl1.GetValue( ) )
self.set_config_by_section_key_val( 'algorithm',"2",self.textCtrl2.GetValue( ) )
self.set_config_by_section_key_val( 'algorithm',"3",self.textCtrl2.GetValue( ) )
self.config.write_yaml(self.config_yml)
del self.config
if success:
self.EndModal(wx.ID_OK)

@ -0,0 +1,138 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import wx
from myconfig import MyConfig
from myconfig import YAML_FILE_NAME
class UI_Com_Setting(wx.Dialog):
"""
@description : Com 配置
"""
def __init__(self, parent,id):
# 串口页面配置
super(UI_Com_Setting, self).__init__( parent ,id=id )
self.config = MyConfig()
self.InitUI()
self.SetSize((400, 400))
self.SetTitle(" 设置串口参数 ")
def InitUI(self):
self.config_yml = self.config.read_yaml()
# print(self.config_yml['comsetting'])
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sb = wx.StaticBox(self.panel, label='设置串口')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel, label='串口号: ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL )
self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) )
tmp = self.get_str_from_config("comsetting",'port')
if tmp is not None:
self.textCtrl1.SetValue(tmp)
self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5)
self.hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText2 = wx.StaticText(self.panel, label='波特率: ' ,size=(60, -1))
# self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config("comsetting",'baudrate')
if tmp is not None:
self.textCtrl2.SetValue(tmp)
self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox3 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText3 = wx.StaticText(self.panel, label='数据位: ' ,size=(60, -1))
# self.staticText3_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl3 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config("comsetting",'bytesize')
if tmp is not None:
self.textCtrl3.SetValue(tmp)
self.hbox3.Add(self.staticText3, flag=wx.TOP|wx.LEFT, border=5)
self.hbox3.Add(self.textCtrl3,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox3.Add(self.staticText3_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox3, flag=wx.TOP|wx.LEFT, border=5)
self.hbox4 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText4 = wx.StaticText(self.panel, label='奇偶性: ' ,size=(60, -1))
# self.staticText3_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl4 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config("comsetting",'parity')
if tmp is not None:
self.textCtrl4.SetValue(tmp)
self.hbox4.Add(self.staticText4, flag=wx.TOP|wx.LEFT, border=5)
self.hbox4.Add(self.textCtrl4,flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add( self.hbox4, flag=wx.TOP|wx.LEFT, border=5 )
self.hbox5 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText5 = wx.StaticText(self.panel, label='停止位: ' ,size=(60, -1))
# self.staticText3_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl5 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config("comsetting",'stopbit')
if tmp is not None:
self.textCtrl5.SetValue(tmp)
self.hbox5.Add(self.staticText5, flag=wx.TOP|wx.LEFT, border=5)
self.hbox5.Add(self.textCtrl5, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add( self.hbox5, flag=wx.TOP|wx.LEFT, border=5 )
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'保存配置')
self.closeButton = wx.Button(self, label='Close')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5)
# 添加 vbox 到panel
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def get_str_from_config( self, section, key ):
return str(self.config_yml[section][key])
pass
def set_config_by_section_key_val( self, section, key, val ):
# print(f" {key} current type {type( self.config_yml[section][key] )}")
if type( self.config_yml[section][key] ) == int:
self.config_yml[section][key] = int(val)
elif type( self.config_yml[section][key] ) == float:
self.config_yml[section][key] = float(val)
else:
self.config_yml[section][key] = val
pass
def saveData( self, e ):
pass
def OnClose( self, e ):
self.Destroy()
def OnSave(self, e):
success = True
# 赋值字典,写入文件
self.set_config_by_section_key_val("comsetting", 'port', self.textCtrl1.GetValue( ))
self.set_config_by_section_key_val("comsetting", 'baudrate', self.textCtrl2.GetValue( ))
self.set_config_by_section_key_val("comsetting", 'bytesize', self.textCtrl3.GetValue( ))
self.set_config_by_section_key_val("comsetting", 'parity', self.textCtrl4.GetValue( ))
self.set_config_by_section_key_val("comsetting", 'stopbit', self.textCtrl5.GetValue( ))
self.config.write_yaml(self.config_yml)
del self.config
if success:
self.EndModal(wx.ID_OK)

@ -0,0 +1,92 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import wx
# from configobj import ConfigObj
from myconfig import MyConfig
from myconfig import YAML_FILE_NAME
class UI_Filepath_Setting(wx.Dialog):
"""
@description : 文件路径 配置
"""
def __init__(self, parent,id):
# 串口页面配置
super(UI_Filepath_Setting, self).__init__( parent ,id=id )
self.config = MyConfig()
self.InitUI()
self.SetSize((400, 400))
self.SetTitle(" 设置文件路径 ")
def InitUI(self):
self.config_yml = self.config.read_yaml()
# self.sensor = self.config_sensor.get(self.did)
# print(self.config_sensor)
# print(self.sensor)
self.panel = wx.Panel( self )
self.vbox = wx.BoxSizer( wx.VERTICAL )
self.sb = wx.StaticBox(self.panel, label='文件路径 配置')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel, label='文件路径: ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL )
self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) )
tmp = self.get_str_from_config("filepath","path")
if tmp is not None:
self.textCtrl1.SetValue(tmp)
self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5)
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'保存配置')
self.closeButton = wx.Button(self, label='Close')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5)
# 添加 vbox 到panel
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def get_str_from_config( self, section, key ):
return str(self.config_yml[section][key])
pass
def set_config_by_section_key_val( self, section, key, val ):
# print(f" {key} current type {type( self.config_yml[section][key] )}")
if type( self.config_yml[section][key] ) == int:
self.config_yml[section][key] = int(val)
elif type( self.config_yml[section][key] ) == float:
self.config_yml[section][key] = float(val)
else:
self.config_yml[section][key] = val
pass
def saveData(self, e):
pass
def OnClose(self, e):
self.Destroy()
def OnSave(self, e):
success = True
# 赋值字典,写入文件
self.set_config_by_section_key_val('filepath',"file",self.textCtrl1.GetValue( ))
self.config_yml.write_yaml(self.config_sensor)
del self.config
if success:
self.EndModal(wx.ID_OK)

@ -0,0 +1,100 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import wx
# from configobj import ConfigObj
from myconfig import MyConfig
from myconfig import YAML_FILE_NAME
class UI_Log_Setting(wx.Dialog):
"""
@description : Sensor 配置
"""
def __init__(self, parent, id):
# 串口页面配置
super(UI_Log_Setting, self).__init__( parent ,id = id )
self.config = MyConfig()
self.InitUI()
self.SetSize((400, 400))
self.SetTitle(" 设置光程 序列号 ")
def InitUI(self):
self.config_yml = self.config.read_yaml()
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sb = wx.StaticBox(self.panel, label='设置光程 序列号')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel, label='采集间隔: ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL )
self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) )
tmp = self.get_str_from_config( "logsetting", "LogInterval" )
if tmp is not None:
self.textCtrl1.SetValue(tmp)
self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5)
self.hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText2 = wx.StaticText(self.panel, label='保存间隔: ' ,size=(60, -1))
# self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config( "logsetting", "RefreshInterval" )
if tmp is not None:
self.textCtrl2.SetValue(tmp)
self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5)
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'保存配置')
self.closeButton = wx.Button(self, label='Close')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5)
# 添加 vbox 到panel
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def get_str_from_config( self, section, key ):
return str(self.config_yml[section][key])
pass
def set_config_by_section_key_val( self, section, key, val ):
# print(f" {key} current type {type( self.config_yml[section][key] )}")
if type( self.config_yml[section][key] ) == int:
self.config_yml[section][key] = int(val)
elif type( self.config_yml[section][key] ) == float:
self.config_yml[section][key] = float(val)
else:
self.config_yml[section][key] = val
pass
def saveData(self, e):
pass
def OnClose(self, e):
self.Destroy()
def OnSave(self, e):
success = True
# 赋值字典,写入文件
self.set_config_by_section_key_val('logsetting',"LogInterval",self.textCtrl1.GetValue( ))
self.set_config_by_section_key_val('logsetting',"RefreshInterval",self.textCtrl2.GetValue( ))
self.config.write_yaml(self.config_yml)
del self.config
if success:
self.EndModal(wx.ID_OK)

@ -0,0 +1,100 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import wx
# from configobj import ConfigObj
from myconfig import MyConfig
from myconfig import YAML_FILE_NAME
class UI_PathSN_Setting(wx.Dialog):
"""
@description : 设置光程 序列号
"""
def __init__(self, parent,id):
# 串口页面配置
super(UI_PathSN_Setting, self).__init__( parent ,id=id )
self.config = MyConfig()
self.InitUI()
self.SetSize((400, 400))
self.SetTitle(" 设置光程 序列号 ")
def InitUI(self):
self.config_yml = self.config.read_yaml()
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sb = wx.StaticBox(self.panel, label='设置光程 序列号')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel, label='光 程: ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL )
self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) )
tmp = self.get_str_from_config( "device", "UIPATH" )
if tmp is not None:
self.textCtrl1.SetValue(tmp)
self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5)
self.hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText2 = wx.StaticText(self.panel, label='序列号: ' ,size=(60, -1))
# self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config( "device", "UISN" )
if tmp is not None:
self.textCtrl2.SetValue(tmp)
self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5)
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'保存配置')
self.closeButton = wx.Button(self, label='Close')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5)
# 添加 vbox 到panel
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def get_str_from_config( self, section, key ):
return str(self.config_yml[section][key])
pass
def set_config_by_section_key_val( self, section, key, val ):
# print(f" {key} current type {type( self.config_yml[section][key] )}")
if type( self.config_yml[section][key] ) == int:
self.config_yml[section][key] = int(val)
elif type( self.config_yml[section][key] ) == float:
self.config_yml[section][key] = float(val)
else:
self.config_yml[section][key] = val
pass
def saveData(self, e):
pass
def OnClose(self, e):
self.Destroy()
def OnSave(self, e):
success = True
# 赋值字典,写入文件
self.set_config_by_section_key_val('device',"UIPATH",self.textCtrl1.GetValue( ))
self.set_config_by_section_key_val('device',"UISN",self.textCtrl2.GetValue( ))
self.config.write_yaml(self.config_yml)
del self.config
if success:
self.EndModal(wx.ID_OK)

@ -0,0 +1,100 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import wx
# from configobj import ConfigObj
from myconfig import MyConfig
from myconfig import YAML_FILE_NAME
class UI_Plot_Setting(wx.Dialog):
"""
@description : 绘图 配置
"""
def __init__(self, parent, id):
# 串口页面配置
super(UI_Plot_Setting, self).__init__( parent ,id = id )
self.config = MyConfig()
self.InitUI()
self.SetSize((400, 400))
self.SetTitle(" 绘图 序列号 ")
def InitUI(self):
self.config_yml = self.config.read_yaml()
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sb = wx.StaticBox(self.panel, label='绘图 序列号')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel, label='起始行号 ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL )
self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) )
tmp = self.get_str_from_config( "plotsetting", "LineBegin" )
if tmp is not None:
self.textCtrl1.SetValue(tmp)
self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5)
self.hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText2 = wx.StaticText(self.panel, label='间隔行号: ' ,size=(60, -1))
# self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.get_str_from_config( "plotsetting", "LineInterval" )
if tmp is not None:
self.textCtrl2.SetValue(tmp)
self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5)
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'保存配置')
self.closeButton = wx.Button(self, label='Close')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5)
# 添加 vbox 到panel
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def get_str_from_config( self, section, key ):
return str(self.config_yml[section][key])
pass
def set_config_by_section_key_val( self, section, key, val ):
# print(f" {key} current type {type( self.config_yml[section][key] )}")
if type( self.config_yml[section][key] ) == int:
self.config_yml[section][key] = int(val)
elif type( self.config_yml[section][key] ) == float:
self.config_yml[section][key] = float(val)
else:
self.config_yml[section][key] = val
pass
def saveData(self, e):
pass
def OnClose(self, e):
self.Destroy()
def OnSave(self, e):
success = True
# 赋值字典,写入文件
self.set_config_by_section_key_val('plotsetting',"LineBegin",self.textCtrl1.GetValue( ))
self.set_config_by_section_key_val('plotsetting',"LineInterval",self.textCtrl2.GetValue( ))
self.config.write_yaml(self.config_yml)
del self.config
if success:
self.EndModal(wx.ID_OK)

@ -0,0 +1,60 @@
import wx
# 设置串口参数的对话框类
class About(wx.Dialog):
def __init__(self, *args, **kwds):
# 参数调入后初始化
super(About, self).__init__(*args, **kwds)
self.InitUI()
self.SetSize((400, 400))
self.SetTitle("使用帮助")
def InitUI(self):
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sb = wx.StaticBox(self.panel, label='使用帮助')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel,
label='''\n上海奕枫仪器设备有限公司
电话: 021-54270075
网站: http://www.yi-win.com
邮件: sales@yi-win.com ''' )
self.hbox1.Add(self.staticText1)
self.sbs.Add(self.hbox1)
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'确认')
self.closeButton = wx.Button(self, label='关闭')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag=wx.LEFT, border=5)
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def saveData(self, e):
pass
def OnClose(self, e):
self.Destroy()
def OnSave(self, e):
self.EndModal(wx.ID_OK)

@ -0,0 +1,58 @@
import wx
# 设置串口参数的对话框类
class Help(wx.Dialog):
def __init__(self, *args, **kwds):
# 参数调入后初始化
super(Help, self).__init__(*args, **kwds)
self.InitUI()
self.SetSize((400, 400))
self.SetTitle("使用帮助")
def InitUI(self):
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sb = wx.StaticBox(self.panel, label='使用帮助')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel,
label='''\n上海奕枫仪器设备有限公司
电话: 021-54270075
网站: http://www.yi-win.com
邮件: sales@yi-win.com ''' )
self.hbox1.Add(self.staticText1)
self.sbs.Add(self.hbox1)
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'确认')
self.closeButton = wx.Button(self, label='关闭')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag=wx.LEFT, border=5)
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def saveData(self, e):
pass
def OnClose(self, e):
self.Destroy()
def OnSave(self, e):
self.EndModal(wx.ID_OK)

@ -0,0 +1,124 @@
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import wx
# from configobj import ConfigObj
from myconfig import MyConfig
from myconfig import YAML_FILE_NAME
class UISensor(wx.Dialog):
"""
@description : Sensor 配置
"""
def __init__(self, parent, id, did):
# 参数调入后初始化
self.did = did
super(UISensor, self).__init__( parent, id=id )
self.config = MyConfig()
self.InitUI()
self.SetSize((400, 400))
self.SetTitle(" 设置页面 串口 采集间隔 ")
def InitUI(self):
self.config_sensor = self.config.read_yaml()
# self.sensor = self.config_sensor.get(self.did)
# print(self.config_sensor)
# print(self.sensor)
self.panel = wx.Panel(self)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.sb = wx.StaticBox(self.panel, label='设置页面')
self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL)
self.hbox1 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText1 = wx.StaticText(self.panel, label='Lsky: ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL )
self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) )
tmp = self.getSnByDidAndFunc("Lsky",self.did)
if tmp is not None:
self.textCtrl1.SetValue(tmp)
self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5)
self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5)
self.hbox2 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText2 = wx.StaticText(self.panel, label='Esky: ' ,size=(60, -1))
# self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.getSnByDidAndFunc("Esky",self.did)
if tmp is not None:
self.textCtrl2.SetValue(tmp)
self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5)
self.hbox3 = wx.BoxSizer(wx.HORIZONTAL)
self.staticText3 = wx.StaticText(self.panel, label='Lwater: ' ,size=(60, -1))
# self.staticText3_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1))
self.textCtrl3 = wx.TextCtrl(self.panel, value="",size=(250,25))
tmp = self.getSnByDidAndFunc("Lwater",self.did)
if tmp is not None:
self.textCtrl3.SetValue(tmp)
self.hbox3.Add(self.staticText3, flag=wx.TOP|wx.LEFT, border=5)
self.hbox3.Add(self.textCtrl3,flag=wx.TOP|wx.LEFT, border=5)
# self.hbox3.Add(self.staticText3_1, flag=wx.TOP|wx.LEFT, border=5)
self.sbs.Add(self.hbox3, flag=wx.TOP|wx.LEFT, border=5)
self.panel.SetSizer(self.sbs)
self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL)
self.okButton = wx.Button(self, label=u'保存配置')
self.closeButton = wx.Button(self, label='Close')
self.hbox_0.Add(self.okButton)
self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5)
# 添加 vbox 到panel
self.vbox.Add(self.panel, proportion=1,
flag=wx.ALL | wx.EXPAND, border=5)
self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10)
self.SetSizer(self.vbox)
self.okButton.Bind(wx.EVT_BUTTON, self.OnSave)
self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
def getSnByDidAndFunc(self,func,did):
temp:dict = self.config_sensor.get(did)
for v in temp.values():
if v["FUNC"] == func:
return v["SN"]
return None
pass
def setSnByDidAndFunc(self,func,did,val):
temp:dict = self.config_sensor.get(did)
for k,v in temp.items():
if v["FUNC"] == func:
temp[k]['SN'] =val
self.config_sensor.update({did:temp})
pass
def saveData(self, e):
pass
def OnClose(self, e):
self.Destroy()
def OnSave(self, e):
success = True
# 赋值字典,写入文件
self.setSnByDidAndFunc('Lsky',self.did,self.textCtrl1.GetValue( ))
self.setSnByDidAndFunc('Esky',self.did,self.textCtrl2.GetValue( ))
self.setSnByDidAndFunc('Lwater',self.did,self.textCtrl3.GetValue( ))
print(self.textCtrl3.GetValue( ))
print(self.config_sensor)
self.config.write_yaml(self.config_sensor)
del self.config
if success:
self.EndModal(wx.ID_OK)

@ -0,0 +1,427 @@
import numpy as np
import struct
import math
from myconfig import TOKEN, DATA_DIR, FILE_MARK, OUTPUT_DIR, CAL_DIR
from myconfig import PURE_WATER_FNAME,SAVE_EXT_NAME
from myconfig import MyConfig
from configuration import Configuration
from myexception import MyException
from mylogger import log
from mypath import MyDir
from mythread import Multithread
from readcal import ReadCal
from uart import Uart
from pathlib import Path, PurePath
from wx.lib.pubsub import pub
class Viper(object):
def __init__(self,):
self.cfg = {}
self.mydir = MyDir()
self.file_lst = []
self.raw_wavelength = []
self.raw_wavelength_np = np.array([])
self.purewater_wavelength = []
self.purewater_attenuation = []
self.output_wavelength = []
self.begin = 0
self.end = 0
self.dir :Path = Path()
self.datadir :Path = self.dir.joinpath(DATA_DIR)
self.output_dir:Path= self.datadir.joinpath(OUTPUT_DIR)
self.measure_time = ''
self.data = []
self.res = b''
self.msg = {"type":"", "data":{}}
self.__get_purewater_wl_and_data()
self.purewater_after_interp = None
self.uart = Uart()
self.uart_thread = Multithread()
pass
def set_cfg(self, cfg):
self.cfg = cfg
self.ui_sn = self.cfg['device']['UISN']
pass
# def set_read_para(self, cfg):
# self.cfg = cfg
# self.ui_sn = self.cfg['device']['UISN']
# pass
# def set_uart_para(self, cfg):
# self.cfg = cfg
# self.ui_sn = self.cfg['device']['UISN']
# pass
def __set_msg(self, typ, d):
self.msg = {}
self.msg.update( {"type":typ} )
self.msg.update( {"data":d} )
pass
# def file_deal_thread(self, func) -> list:
# self.get_data_files()
# self.__deal_file_lst(func)
# pass
def get_data_files(self,) -> list:
# 读取配置文件
self.mydir.setBaseDir(Path(self.datadir))
self.file_lst = self.mydir.get_files_from_currentdir(fmt="*/*.DAT")
def get_begin_end(self,) -> list:
# 读取配置文件
for i in range( len(self.raw_wavelength)):
if self.raw_wavelength[i]<self.cfg['retrieve']['beginWL'] \
and self.raw_wavelength[i+1]>self.cfg['retrieve']['beginWL']:
self.begin = i+1
pass
if self.raw_wavelength[i]<self.cfg['retrieve']['endWL'] \
and self.raw_wavelength[i+1]>self.cfg['retrieve']['endWL']:
self.end = i+2
break
self.get_output_wavelength()
msg = "起始波长 : "+ str(self.output_wavelength[0]) +" , 结束波长 : "+ str(self.output_wavelength[-1])
log.info(msg, __name__, '','')
self.__set_msg ("notice", msg )
pub.sendMessage(self.msg)
def get_output_wavelength(self,) :
self.output_wavelength = self.raw_wavelength[self.begin:self.end]
pass
# def __deal_file_lst(self,func):
# for fl in self.file_lst:
# log.info(f"-> {fl} ",__name__,"deal_file_lst")
# # 判断序列号是否一致file_lst
# if not self.__check_sn_from_datafile(fl):
# raise MyException( "文件的序列号和系统设置不一致" )
# # 判断原始波长是否为空
# if self.raw_wavelength == []:
# self.__get_raw_wl_from_datafile(self.file_lst[0])
# # 获得截取的开始 结束点
# self.get_begin_end()
# # 纯水插值
# self.interpo_pure_water()
# # 准备储存数据文件
# self.__prepare_for_save()
# ReadCal.read_columns_sets_by_mark_callback(
# fl, FILE_MARK, self.deal_measure_time_data, 1)
# print("beign to func.....")
# func( self.measure_time, self.data )
# self.__set_msg( "notice", "文件处理完毕" )
# pub.sendMessage( "update", msg = self.msg )
def deal_file_lst(self, ):
for fl in self.file_lst:
log.info(f"-> {fl} ",__name__,"deal_file_lst")
# 判断序列号是否一致file_lst
if not self.__check_sn_from_datafile(fl):
raise MyException( "文件的序列号和系统设置不一致" )
# 判断原始波长是否为空
if self.raw_wavelength == []:
self.__get_raw_wl_from_datafile(self.file_lst[0])
# 获得截取的开始 结束点
self.get_begin_end()
# 纯水插值
self.interpo_pure_water()
# 准备储存数据文件
self.__prepare_for_save()
ReadCal.read_columns_sets_by_mark_callback(
fl, FILE_MARK, self.deal_measure_time_data, 1)
self.__set_msg( "notice", "文件处理完毕" )
pub.sendMessage( "update", msg = self.msg )
def deal_measure_time_data(self, sn, res_time, res_data):
log.info(f" -> time : {res_time}",__name__, "deal_one_measure_time_data")
log.info(f" -> datalen : {len(res_data)} ",__name__, "deal_one_measure_time_data")
for i in range(len(res_time)):
data = self.convert_str_2_float_list( res_data[i][0][self.begin:self.end] )
# 浊度校正
data = self.correction_turbidity( np.array(data) )
# 纯水校正
data = self.correction_pure_water( data )
# 取对数,光程归一 ?? 纯水校正,是吸光度校正还是系数校正
data = ( data * (1000 * math.log(10,math.e)))/self.cfg['device']['UIPath']
data = data.tolist()
# print(data)
self.mydir.setContent( data , TOKEN, res_time[i] )
self.mydir.writeContent()
self.measure_time = res_time[i]
self.data = data
self.__set_msg( "data", {"time":res_time[i], "data":data } )
pub.sendMessage("update", msg=self.msg)
# pub.sendMessage("update", msg=res_data[i][0][self.begin:self.end])
def __check_sn_from_datafile(self, fpath) -> bool:
# 读取配置文件
sn = ReadCal.readFileSNbyIDDevice(fpath)
if sn == self.ui_sn:
return True
return False
def __get_raw_wl_from_datafile(self, fpath) -> None:
# 读取配置文件
_, raw_wl = ReadCal.read_columns_set_by_mark(fpath, FILE_MARK, 0)
self.raw_wavelength = self.convert_str_2_float_list (raw_wl[0])
self.raw_wavelength_np = np.array(raw_wl[0])
return None
def __prepare_for_save(self,) -> bool:
self.mydir.setBaseDir(self.output_dir)
self.mydir.newDirIfNot()
self.mydir.newFileIfNot(self.ui_sn+SAVE_EXT_NAME)
self.mydir.setHeader(self.output_wavelength, TOKEN, self.ui_sn)
if self.mydir.checkHeader() == 0:
self.mydir.writeHeader()
if self.mydir.checkHeader() == -1:
# self.popDialog(" 文件头不一致, 请备份到其他目录,并在该目录下删除")
raise MyException(" 文件头不一致, 请备份到其他目录,并在该目录下删除")
def interpo_pure_water(self):
self.purewater_after_interp = np.interp(
np.array(self.output_wavelength)
, np.array(self.purewater_wavelength)
, np.array(self.purewater_attenuation)
)
pass
def correction_turbidity(self, data:np.ndarray ):
'''浊度校正, 吸光度
0 : 默认11项平均
1 : 720
2 : 不浊度校正
'''
log.debug( "correction_turbidity .....",__name__, 'correction_turbidity' )
if self.cfg['algorithm']['A720'] == 0:
count = data.shape[0]
tmp = 0.0
for i in range(count-11,count,1):
tmp = tmp + data[i]
tmp = tmp/11
return data - tmp
pass
if self.cfg['algorithm']['A720'] == 1:
count = data.shape[0]
tmp = data[count] - (self.output_wavelength[count]-720) * (data[count] -data[count-1]) \
/ (self.output_wavelength[count]-self.output_wavelength[count-1])
print(f"tmp .... {tmp}")
return data-tmp
pass
if self.cfg['algorithm']['A720'] == 2:
return data
return data
pass
def correction_pure_water(self, data:np.ndarray ):
'''浊度校正
0 : 不变
1 : 减去纯水
'''
if self.cfg['algorithm']['PureWater'] == 0:
return data
pass
if self.cfg['algorithm']['PureWater'] == 1:
return data - self.purewater_after_interp
pass
return data
pass
def __get_purewater_wl_and_data(self ):
log.info(f" == ",__name__,'__get_purewater_wl_and_data')
caldir = self.dir.joinpath(CAL_DIR )
cal_fpath = caldir.joinpath( PURE_WATER_FNAME)
if cal_fpath.exists():
_, res_data = ReadCal.read_columns_sets_by_mark(
cal_fpath, FILE_MARK, 0, 1)
self.purewater_wavelength = self.convert_str_2_float_list( res_data[0][0])
self.purewater_attenuation = self.convert_str_2_float_list(res_data[0][1])
def set_serial(self, )-> None:
self.uart.set_serial_para(
self.cfg['comsetting']['port']
,self.cfg['comsetting']['baudrate']
,self.cfg['comsetting']['bytesize']
,self.cfg['comsetting']['parity']
,self.cfg['comsetting']['stopbit']
)
def set_modbus(self, beginaddress, step)-> None:
self.uart.set_modbus(
self.cfg['register']['slaveaddress']
,self.cfg['register']['functioncode']
,beginaddress
,step
)
def sn_uart_thread(self, func)-> None:
self.set_serial()
self.uart_thread.remove_tasks()
self.set_modbus( self.cfg['register']['SNAddress'], self.cfg['register']['SNLen'] )
self.uart_thread.add_task( self.device_sn, args=(func,) )
self.uart_thread.sequently_execute_tasks()
pass
def wl_uart_thread(self, func)-> None:
self.res = b''
self.set_serial()
self.uart_thread.remove_tasks()
for i in range(self.cfg['register']['count']):
log.debug(f" -> i {i}", __name__,"wl_uart_thread")
self.set_modbus( self.cfg['register']['WLBeginAddress'] + i*120, 120 )
log.debug(f" command -> {self.uart.command.hex()} ")
self.uart_thread.add_task( self.device_wl, args=() )
self.uart_thread.sequently_execute_tasks()
self.uart_thread.remove_tasks()
# self.uart_thread.add_task_2_act( )
# self.uart_thread.execute_one_act()
self.raw_wavelength = self.convert_buf_2_float(self.res)
# 获得截取的开始 结束点
self.get_begin_end()
self.get_output_wavelength()
msg = "起始波长 : "+str(self.output_wavelength[0]) +" , 结束波长 : "+ str(self.output_wavelength[-1])
log.info(msg)
self.__set_msg ("notice", msg )
pub.sendMessage(self.msg)
func( self.output_wavelength )
# self.__set_msg( "wl", {} )
# pub.sendMessage("update", msg= self.msg)
def log_uart_thread(self, func)-> None:
self.res = b''
self.set_serial()
self.uart_thread.remove_tasks()
for i in range(self.cfg['register']['count']):
self.set_modbus( self.cfg['register']['DataBeginAddress'] + i * 120, 120 )
self.uart_thread.add_task( self.device_log, args=( ) )
self.uart_thread.sequently_execute_tasks()
self.uart_thread.remove_tasks()
pass
data = self.convert_buf_2_float(self.res)
data = data[self.begin:self.end]
func(data)
def device_sn(self, func)-> None:
self.res =b''
self.uart.disconnect()
self.uart.connect()
self.uart.write()
self.res = self.uart.OneMeasure()
sn = self.res[-6:-2].decode()
self.res = b''
func( sn )
# pub.sendMessage("update",msg=self.msg)
def device_wl(self, )-> None:
# self.res =b''
# log.warning(" -->", __name__, "device_wl")
self.uart.disconnect()
self.uart.connect()
self.uart.write()
tmp = self.uart.OneMeasure()
self.res = self.res + tmp[3:len(tmp)-2]
def device_log(self, )-> None:
# self.res =b''
self.uart.disconnect()
self.uart.connect()
self.uart.write()
tmp = self.uart.OneMeasure()
self.res = self.res + tmp[3:len(tmp)-2]
def convert_buf_2_float(self, buff, byteOrder= "big" )-> None:
res = []
log.debug(f" === {len(buff)}== {buff}", __name__, 'convert_buf_2_float')
len_ = len(buff)
if len_%4 != 0:
return res
if byteOrder == "big":
for i in range( int(len_/4) ):
tmp = struct.unpack(">f", buff[i*4: i*4+4] )
res.append( round(tmp[0],3) )
else:
for i in range( int(len_/4) ):
tmp = struct.unpack(">f", buff[i*4: i*4+4] )
res.append(round(tmp[0],3))
return res
pass
def convert_str_2_float_list(self, lst )-> None:
res = []
for l in lst:
res.append(float(l))
return res
pass
def set_raw_wavelength_from_device(self, lst):
self.raw_wavelength = lst
pass
if __name__ == '__main__':
data = np.array([3,4,5,6])
print(data.shape[0])
print(data[3])
print(data-1)
# if self.syscfg['retrieve']['enable'] == 0:
# self.mydir.setHeader(self.raw_wavelength,TOKEN,self.ui_sn)
# if self.mydir.checkHeader()==0:
# self.mydir.writeHeader()
# if self.mydir.checkHeader()==-1:
# self.popDialog(" 文件头不一致, 请备份到其他目录,并在该目录下删除")
# raise MyException(" 文件头不一致, 请备份到其他目录,并在该目录下删除")
# res_time,res_data = ReadCal.read_columns_sets_by_mark( fl, FILE_MARK, 1 )
# for i in range( len(res_time) ):
# self.__deal_one_measure_time_data(res_time[i], res_data[i])
# pass
# pass
# # 需要插值处理波长
# if self.syscfg['retrieve']['enable'] == 1:
# self.mydir.setHeader(self.new_wavelength.tolist(),TOKEN,self.ui_sn)
# if self.mydir.checkHeader()==0:
# self.mydir.writeHeader()
# if self.mydir.checkHeader()==-1:
# self.popDialog(" 文件头不一致, 请备份到其他目录,并在该目录下删除")
# raise MyException(" 文件头不一致, 请备份到其他目录,并在该目录下删除")
# # res_data 不用带回调的函数callback 会导致多组数据拼接??
# res_time,res_data = ReadCal.read_columns_sets_by_mark( fl, FILE_MARK, 1 )
# log.warning(f" ==== {len(res_time)}" )
# log.warning(res_time)
# log.warning(f" ==== {len(res_data[0])}" )
# log.warning(f" ==== { res_data[0] }" )
# for i in range( len(res_time) ):
# self.__deal_one_measure_time_data(res_time[i], res_data[0][i])
# pass
# pass

@ -0,0 +1,766 @@
import wx
import os
import time
import threading
import numpy as np
from pathlib import Path,PurePath
from wx.lib.pubsub import pub
# from configobj import ConfigObj
from listctrl import Listctrl
# from mypanel import MyPanel
from mypanel import Plot
from uiconfig.ui_com_setting import UI_Com_Setting
from uiconfig.ui_filepath_setting import UI_Filepath_Setting
from uiconfig.ui_pathsn_setting import UI_PathSN_Setting
from uiconfig.ui_plot_setting import UI_Plot_Setting
from uiconfig.ui_log_setting import UI_Log_Setting
from uiconfig.uiabout import About
from uiconfig.uihelp import Help
from myconfig import DeviceType,YAML_FILE_NAME,RETRIEVE_CFG_FILE
from myconfig import TOKEN,DATA_DIR,FILE_MARK,OUTPUT_DIR,SAVE_EXT_NAME
from myconfig import MyConfig
from configuration import Configuration
# from awrams import AWRAMS,HandHeldBuf
from myexception import MyException
from mylogger import log
from mypath import MyDir
from mythread import Mythead
from readcal import ReadCal
from uart import Uart
from viper import Viper
from dataplot import DataPlot
# -定义菜单ID,关联Event-------------------------
"""
# 菜单 文件 -- 处理文件
设备 -- 序列 波长 测量
设置 -- 串口 光程 文件路径 绘图参数 采集设置
作图 -- 最后一条曲线 最后七条 指定位置七条
帮助
"""
ID_MEASURE = 1
ID_DEAL_FILE = 2
ID_DEVICE_SN = 3
ID_DEVICE_WL = 4
ID_DEVICE_LOG = 5
ID_COM_SETTING = 6
ID_PATH_SN = 7
ID_FILE_PATH = 8
ID_PLOT_SETTING = 9
ID_LOG_SETTING = 10
ID_DEVICE_STOP = 11
ID_PLOT_ONE = 15
ID_PLOT_SEVEN = 16
ID_PLOT_RULE = 17
ID_HELP = 21
ID_ABOUT = 22
class YiwinFrame( wx.Frame ):
'''将buf类传进来'''
def __init__(self, title, parent, size=(900, 750)):
self.device_id = 2
self.device_type = DeviceType.VIPER.name
self.raw_wavelength = []
self.new_wavelength = []
self.device_wavelength = []
self.device_data = []
self.output_wavelength = []
self.output_wl_ndarray = np.array([])
self.syscfg = {}
self.sensor_cfg = {}
self.retrieve = {}
self.calinfo_is_ok = False
self.title = title
self.dir :Path = Path()
self.datadir :Path = self.dir.joinpath(DATA_DIR)
self.output_dir:Path = self.datadir.joinpath(OUTPUT_DIR)
self.save_fname :Path = Path()
self.result = ''
self.displayData:list = []
self.interval = 0
self.measure_time = time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())
super(YiwinFrame, self).__init__( parent, title=self.title, size = size )
self.BoxSizer = wx.BoxSizer(wx.HORIZONTAL) # 建立一个Boxsizer
self.SetSizer(self.BoxSizer)
self.Centre(wx.BOTH)
# 建立 listctrl panel 放到BoxSizer
self.listctrl_panel = Listctrl( self ) # 调用自己建立的 Listctrl panel 类
self.BoxSizer.Add( self.listctrl_panel, proportion =-10, border = 2, flag = wx.ALL | wx.EXPAND)
self.list_ctrl = self.listctrl_panel.list_ctrl
# 隐藏 等待show
self.listctrl_panel.Hide()
self.plotpanel = Plot( self ) # 调用自己建立的 Listctrl panel 类
self.BoxSizer.Add( self.plotpanel, proportion =-10, border = 0, flag = wx.ALL | wx.EXPAND)
# self.static_text = self.plotpanel.staticText1
# 隐藏 等待show
self.plotpanel.Show()
self.statusBar = self.CreateStatusBar() # 创建状态栏
self.statusBar.SetFieldsCount(2) # 状态栏分成3个区域
self.statusBar.SetStatusWidths([-1, -1]) # 区域宽度比列,用负数
self.statusBar.SetStatusText(u" 等待接收消息......", 0)
self.__set_menu() # 添加菜单
self.__attach_events() # 菜单事件
self.__set_properties()
# self.__read_config()
self.__setTimer()
log.info(f"system init....",__name__, "__init__")
self.mycfg = MyConfig()
self.mydir = MyDir()
self.mycfg.set_retrieve()
self.__read_config()
self.ui_sn = self.syscfg['device']['UISN']
self.device_sn = ''
self.file_sn = ''
self.interval = self.syscfg['logsetting']['LogInterval']
self.port = self.syscfg['comsetting']['port']
self.uart = Uart()
self.viper = Viper()
self.dataplot = DataPlot()
self.plot_pure_water()
pub.subscribe( self.updateDisplay, "update")
pass
def __set_menu(self):
'''
# 设置菜单
'''
self.menubar = wx.MenuBar()
fileMenu = wx.Menu()
fileMenu.Append(ID_DEAL_FILE, u'&处理文件', '...')
self.menubar.Append(fileMenu, u'&文件 ')
deviceMenu = wx.Menu()
deviceMenu.Append(ID_DEVICE_SN, u'&序列号', '...')
deviceMenu.AppendSeparator()
deviceMenu.Append(ID_DEVICE_WL, u'&波长', '...')
deviceMenu.AppendSeparator()
deviceMenu.Append(ID_DEVICE_LOG, u'&采集数据', '...')
deviceMenu.AppendSeparator()
deviceMenu.Append(ID_DEVICE_STOP, u'&停止采集', '...')
self.menubar.Append(deviceMenu, u'&设备 ')
settingMenu = wx.Menu()
settingMenu.Append(ID_COM_SETTING, u'&串口设置', '...')
settingMenu.AppendSeparator()
settingMenu.Append(ID_PATH_SN, u'&光程&序列号', ' ')
settingMenu.AppendSeparator()
settingMenu.Append(ID_FILE_PATH, u'&文件路径', ' ')
settingMenu.AppendSeparator()
settingMenu.Append(ID_PLOT_SETTING, u'&绘图设置', ' ')
settingMenu.AppendSeparator()
settingMenu.Append(ID_LOG_SETTING, u'&采集设置', ' ')
self.menubar.Append(settingMenu, u'&系统设置')
plotMenu = wx.Menu()
plotMenu.Append( ID_PLOT_ONE, u'&最后一条', '...' )
plotMenu.AppendSeparator()
plotMenu.Append( ID_PLOT_SEVEN, u'&最后七条', '...' )
plotMenu.AppendSeparator()
plotMenu.Append( ID_PLOT_RULE, u'&指定七条', '...' )
self.menubar.Append(plotMenu, u'&绘图 ')
aboutMenu = wx.Menu()
aboutMenu.Append( ID_HELP, u'&帮助', 'help...' )
aboutMenu.AppendSeparator()
aboutMenu.Append( ID_ABOUT, u'&关于我们', '关于我们...' )
self.menubar.Append( aboutMenu, u'&帮助')
self.SetMenuBar(self.menubar)
pass
def __set_properties(self):
self.SetSize((800, 600))
# self.SetTitle(u'传感器数据采集--上海奕枫仪器设备有限公司')
self.Centre()
def __attach_events(self):
'''
# 绑定菜单事件
'''
self.Bind(wx.EVT_MENU, self.OnDealFile, id = ID_DEAL_FILE)
self.Bind(wx.EVT_MENU, self.OnDeviceSN, id = ID_DEVICE_SN)
self.Bind(wx.EVT_MENU, self.OnDeviceWL, id = ID_DEVICE_WL)
self.Bind(wx.EVT_MENU, self.OnDeviceLog, id = ID_DEVICE_LOG)
self.Bind(wx.EVT_MENU, self.OnDeviceStop, id = ID_DEVICE_STOP)
self.Bind(wx.EVT_MENU, self.OnComSetting, id = ID_COM_SETTING)
self.Bind(wx.EVT_MENU, self.OnPathSNSetting, id = ID_PATH_SN)
self.Bind(wx.EVT_MENU, self.OnFilePathSetting, id = ID_FILE_PATH)
self.Bind(wx.EVT_MENU, self.OnPlotSetting, id = ID_PLOT_SETTING)
self.Bind(wx.EVT_MENU, self.OnLogSetting, id = ID_LOG_SETTING)
self.Bind(wx.EVT_MENU, self.OnPlotOne, id = ID_PLOT_ONE)
self.Bind(wx.EVT_MENU, self.OnPlotSeven, id = ID_PLOT_SEVEN)
self.Bind(wx.EVT_MENU, self.OnPlotRule, id = ID_PLOT_RULE)
self.Bind(wx.EVT_MENU, self.OnHelpConfig, id = ID_HELP)
self.Bind(wx.EVT_MENU, self.OnAboutConfig, id = ID_ABOUT)
pass
def __setTimer(self):
self.timer = wx.Timer(self) #创建定时器,菜单以后
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) #绑定一个定时器事件
pass
def updateDisplay(self,msg):
log.debug(f" updateDisplay 。。 {msg['data']}")
if msg['type'] == "notice":
self.__update_notice(msg['data'])
pass
if msg['type'] == "sn":
self.__update_sn(msg['data'])
pass
if msg['type'] == "wl":
self.__update_wl(msg['data'])
pass
if msg['type'] == "log":
self.__update_log(msg['data'] )
print(f" ...log update ...{msg['data']} " )
pass
if msg['type'] == "data":
# log.info(f" ... update .{msg['data']}........... " )
self.__update_data(msg['data'])
pass
pass
def __update_sn(self,sn):
if sn != self.ui_sn:
self.alterStatus_0(f" sn: {sn} 与系统sn {self.ui_sn} 一致")
self.popDialog(f" sn: {sn} 与系统sn {self.ui_sn} 一致")
raise MyException(f" sn: {sn} 与系统sn {self.ui_sn} 一致")
else:
self.alterStatus_0(f" sn: {sn} 与系统sn {self.ui_sn} 不一致")
pass
def __update_notice(self,msg):
log.debug(f" msg : {msg}")
self.alterStatus_0(msg)
pass
def __update_wl(self,wl):
log.debug(f" 获得的波长成功 : {wl}")
self.output_wavelength = wl
self.alterStatus_0( f" 获得的波长成功 " )
pass
def __update_log(self,d):
log.info(f" 获得的数据 {d}")
self.alterStatus_0( d)
def __update_data( self, d ):
'''对于文件过来的数据'''
log.debug(f" ", __name__," __update_data")
self.plotpanel.clear_past()
self.plotpanel.plot_one(
d['time']
,np.array(self.viper.output_wavelength)
,np.array(d['data'])
)
pass
def OnStart( self, event ):
log.info( f" OnStart....interval: { self.interval } minutes, port: { self.port} " )
interval_ms = int(self.interval) * 60 * 1000
self.timer.Start( interval_ms ) # 开始监测
def OnStop( self ,event ):
self.timer.Stop()
pass
def OnTimer(self, event):
''' 定时器实现 '''
# log.info( f"OnTimer .... " )
self.__OnDeviceLog(event)
pass
def __read_config(self,):
# 读取配置文件
self.syscfg = self.mycfg.read_yaml()
retrieve = self.mycfg.read_rtv_yaml()
self.syscfg.update( { "retrieve" : retrieve } )
def OnDealFile(self, e)-> None:
self.__OnDeviceStop()
log.info( f"OnDealFile: 处理测量文件", __name__, "", "" )
# 线程守护
self.mt = Mythead()
self.viper.set_cfg(self.syscfg)
try:
self.viper.get_data_files()
self.mt.set_task( self.viper.deal_file_lst )
self.mt.start()
self.alterStatus_0(" 处理完所有文件" )
except Exception as e:
self.alterStatus_0(e )
self.popDialog( e )
pass
def OnDeviceSN(self, e)-> None:
self.__OnDeviceStop()
log.info(f"OnDeviceSN: 获取device sn ", __name__, "", "")
# self.mt = Mythead()
self.viper.set_cfg(self.syscfg)
self.viper.set_serial()
# self.viper.set_modbus(self.syscfg['register']['SNAddress'], self.syscfg['register']['SNLen'])
try:
self.viper.sn_uart_thread( self.get_device_sn )
except Exception as e:
self.alterStatus_0(e )
self.popDialog( e )
self.alterStatus_0(" SN 匹配一致" )
pass
def get_device_sn(self,sn):
self.device_sn = sn
if self.device_sn != self.ui_sn:
log.error( " 设备SN 与系统设置不一致 错误 " )
pass
else:
log.info(" sn 匹配成功 ! ")
pass
def OnDeviceWL(self, e)-> None:
self.__OnDeviceStop()
log.info(f"OnDeviceWL: 获得device wavelength ... ", __name__, "", "")
if self.device_sn != '':
self.viper.set_cfg( self.syscfg )
self.viper.set_serial()
try:
self.viper.wl_uart_thread( self.get_device_wl )
except Exception as e:
self.alterStatus_0(e )
self.popDialog( e )
self.alterStatus_0(" 获取波长成功!" )
else:
self.popDialog('请获取设备序列号SN信息再试')
pass
def get_device_wl(self, wl_buf):
if len(wl_buf) != 0:
self.output_wavelength = wl_buf
self.output_wl_ndarray = np.array(self.output_wavelength)
else:
log.error( " 获取设备波长出错 " )
raise MyException( " 获取设备波长出错 " )
pass
def OnDeviceLog(self, e)-> None:
self.__OnDeviceStop()
log.info( f"OnDeviceLog: 采集数据 定时器采集", __name__, "", "" )
# !!!! 判断是否有波长和sn
if self.output_wavelength == []:
self.alterStatus_0( " 没有设备波长信息,请获取设备波长")
self.popDialog( " 没有设备波长信息,请获取设备波长")
raise MyException(" 没有设备波长信息,请获取设备波长")
self.__OnDeviceLog()
# 如何整点获取,如何快速获取
self.timer.Start( int(self.interval) * 60 * 1000 )
pass
def __OnDeviceLog(self,)-> None:
self.device_data = b''
self.mt = Mythead()
self.viper.set_cfg( self.syscfg )
self.viper.set_serial()
try:
self.viper.log_uart_thread( self.get_device_data )
except Exception as e:
self.alterStatus_0(e )
self.popDialog( e )
pass
def get_device_data( self, data_buf ):
if len(data_buf) != 0:
self.device_data = self.viper.convert_buf_2_float( data_buf )
self.plotpanel.clear_past()
self.plotpanel.plot_one(
time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())
, self.output_wl_ndarray
,np.array(data_buf)
)
else:
log.error( " 采集设备数据出错 " )
raise MyException(" 采集设备数据出错 ")
pass
def OnDeviceStop(self, e)-> None:
self.__OnDeviceStop()
pass
def __OnDeviceStop(self, )-> None:
if self.timer.IsRunning():
self.timer.Stop()
pass
def plot_pure_water(self,):
# self.dataplot.set_file_path()
self.__OnDeviceStop()
self.plotpanel.set_title_x_y( *self.plotpanel.purewater_legend )
time_ = time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())
wl = np.array(self.viper.purewater_wavelength)
att = np.array(self.viper.purewater_attenuation)
self.plotpanel.plot_one(time_, wl, att)
pass
def OnPlotOne(self,e):
self.dataplot.set_file_path( self.output_dir.joinpath(self.ui_sn+SAVE_EXT_NAME) )
self.dataplot.set_token(TOKEN)
# !! 判断波长,获得波长
wavelength:str = self.dataplot.get_first_line().strip('\n').strip('\r')
self.output_wavelength = wavelength.split(TOKEN)[1:]
self.output_wl_ndarray = np.array(self.output_wavelength).astype(np.float64)
line = self.dataplot.get_multi_by_x_m_n(1,1,1)
line = line[0].strip('\n').strip('\r').split(TOKEN)
tm = line[0]
line = np.array(line[1:]).astype(np.float64)
self.plotpanel.axes.clear()
self.plotpanel.plot_one( tm, self.output_wl_ndarray, line )
self.alterStatus_0( f" plot {tm}")
pass
def OnPlotSeven(self,e):
self.__OnDeviceStop()
times = []
lines = []
log.debug( f'+++ ',__name__, 'OnPlotSeven' )
self.dataplot.set_file_path( self.output_dir.joinpath( self.ui_sn+SAVE_EXT_NAME ) )
self.dataplot.set_token(TOKEN)
# !! 判断波长,获得波长
wavelength:str = self.dataplot.get_first_line().strip('\n').strip('\r')
self.output_wavelength = wavelength.split(TOKEN)[1:]
self.output_wl_ndarray = np.array(self.output_wavelength).astype(np.float64)
line_7 = self.dataplot.get_multi_by_x_m_n(1,1,7)
# log.warning( f'+++ {line_7} ',__name__, 'OnPlotSeven' )
for line in line_7:
line = line.strip('\n').strip('\r').split(TOKEN)
tm = line[0]
line = np.array(line[1:]).astype(np.float64)
times.append(tm)
lines.append( line )
self.plotpanel.axes.clear()
self.plotpanel.plot_multi( times, self.output_wl_ndarray, lines )
self.alterStatus_0( f" plot 7 ")
pass
def OnPlotRule(self,e):
self.__OnDeviceStop()
times = []
lines = []
log.debug( f'+++ ',__name__, 'OnPlotSeven' )
self.dataplot.set_file_path( self.output_dir.joinpath( self.ui_sn+SAVE_EXT_NAME ) )
self.dataplot.set_token(TOKEN)
# !! 判断波长,获得波长
wavelength:str = self.dataplot.get_first_line().strip('\n').strip('\r')
self.output_wavelength = wavelength.split(TOKEN)[1:]
self.output_wl_ndarray = np.array(self.output_wavelength).astype(np.float64)
line_7 = self.dataplot.get_multi_by_x_m_n(1,1,7)
# log.warning( f'+++ {line_7} ',__name__, 'OnPlotSeven' )
for line in line_7:
line = line.strip('\n').strip('\r').split(TOKEN)
tm = line[0]
line = np.array(line[1:]).astype(np.float64)
times.append( tm )
lines.append( line )
self.plotpanel.axes.clear()
self.plotpanel.plot_multi( times, self.output_wl_ndarray, lines )
self.alterStatus_0( f" plot designated ")
pass
def OnComSetting(self,e):
with UI_Com_Setting(
self,
-1 ) as Dialog_Sensor_Setting:
Dialog_Sensor_Setting.CenterOnParent()
resultLog = Dialog_Sensor_Setting.ShowModal()
if resultLog == wx.ID_OK:
log.info( " COM config dialog confirm, call back " )
self.__read_config()
pass
def OnPathSNSetting(self,e):
with UI_PathSN_Setting(
self,
-1 ) as Dialog_Sensor_Setting:
Dialog_Sensor_Setting.CenterOnParent()
resultLog = Dialog_Sensor_Setting.ShowModal()
if resultLog == wx.ID_OK:
log.info( " PathSN config dialog confirm, call back " )
self.__read_config()
pass
def OnFilePathSetting(self,e):
with UI_Filepath_Setting(
self,
-1 ) as Dialog_Sensor_Setting:
Dialog_Sensor_Setting.CenterOnParent()
resultLog = Dialog_Sensor_Setting.ShowModal()
if resultLog == wx.ID_OK:
log.info( " FilePath config dialog confirm, call back " )
self.__read_config()
pass
def OnPlotSetting(self,e):
with UI_Plot_Setting(
self,
-1 ) as Dialog_Sensor_Setting:
Dialog_Sensor_Setting.CenterOnParent()
resultLog = Dialog_Sensor_Setting.ShowModal()
if resultLog == wx.ID_OK:
log.info( " Plot config dialog confirm, call back " )
self.__read_config()
pass
def OnLogSetting(self,e):
with UI_Log_Setting(
self,
-1 ) as Dialog_Sensor_Setting:
Dialog_Sensor_Setting.CenterOnParent()
resultLog = Dialog_Sensor_Setting.ShowModal()
if resultLog == wx.ID_OK:
log.info( " Log config dialog confirm, call back " )
self.__read_config()
pass
def OnHelpConfig(self, e):
with Help(
self,
-1,
"") as Dialog_Help:
resultLog = Dialog_Help.ShowModal()
if resultLog == wx.ID_OK:
log.info("Help info")
pass
def OnAboutConfig(self, e):
with About(
self,
-1,
"") as Dialog_About:
resultLog = Dialog_About.ShowModal()
if resultLog == wx.ID_OK:
log.info("Aboutus")
pass
def OnOther(self, e):
pass
def OnQuit(self, e):
self.Close()
def alterStatus_0(self,msg):
self.statusBar.SetStatusText( msg, 0 )
def popDialog(self, msg, msg_type=u"错误提示"):
with wx.MessageDialog( self, msg, msg_type, wx.OK )as dlg:
dlg.ShowModal()
# class SerialThread(threading.Thread):
# """进度条类 """
# def __init__(self, parent):
# """
# :param parent: 主线程UI
# """
# super(SerialThread, self).__init__() # 继承
# self.parent = parent
# # log.info(f"SerialThread ... {self.parent.kh}")
# self.start()
# self.join()
# # self.setDaemon(True) # 设置为守护线程, 即子线程是守护进程,主线程结束子线程也随之结束。
# def stop(self):
# self.parent.kh.disconnect()
# log.info(" Serial stop.... ")
# pass
# def run(self):
# log.info(" Serial run.... ")
# wx.CallAfter(self.parent.OnRcv)
# wx.CallAfter(self.parent.update_process_bar, count) # 调用parent的函数
# wx.CallAfter(self.parent.close_process_bar) # destroy进度条
# def OnSerialThreadStart(self):
# self.m = SerialThread(self)
# pass
# def OnSerialThreadStop(self):
# self.m.stop()
# pass
# def OnDisplaySave(self):
# '''
# 保存数据 self.result
# '''
# log.info(f"OnDisplaySave ....")
# # self.m = SerialThread(self)
# # self.kh.flush()
# self.OnSerialThreadStart()
# def OnRcv( self ):
# log.info(f"OnRcv....")
# self.kh.setPort(self.port)
# if not self.OnDetectPort:
# MyException(f"Can not find port : {self.port}")
# log.info(f"{self.port} ok!")
# # if not self.kh:
# # self.kh = KH3000(self.port)
# # self.result = self.kh.OneMeasure()
# log.info( f"OnRcv success {self.result}", __class__.__name__ )
# self.OnSave()
# self.OnDisplay()
# pass
# def __get_data_files(self,) -> list:
# # 读取配置文件
# file_lst = []
# self.mydir.setBaseDir( Path(self.datadir) )
# file_lst = self.mydir.get_files_from_currentdir(fmt= "*/*.DAT")
# return file_lst
# def __check_sn_from_datafile(self,fpath) -> bool:
# # 读取配置文件
# sn = ReadCal.readFileSNbyIDDevice(fpath)
# if sn == self.ui_sn:
# return True
# return False
# def __get_raw_wl_from_datafile(self,fpath) -> list:
# # 读取配置文件
# _,raw_wl = ReadCal.read_columns_set_by_mark(fpath, FILE_MARK,0)
# return raw_wl
# def __deal_file_lst(self,file_lst):
# for fl in file_lst:
# # 判断序列号是否一致file_lst
# if not self.__check_sn_from_datafile(fl):
# self.onNotify("文件的序列号和系统设置不一致" )
# self.popDialog(" 文件的序列号和系统设置不一致")
# raise MyException("文件的序列号和系统设置不一致")
# # 判断原始波长是否为空
# if self.raw_wavelength == []:
# res = self.__get_raw_wl_from_datafile(file_lst[0])
# self.raw_wavelength = res[0]
# # 处理输出文件
# self.mydir.setBaseDir(self.output_dir)
# self.mydir.newDirIfNot()
# self.mydir.newFileIfNot(self.ui_sn+SAVE_EXT_NAME)
# if self.syscfg['retrieve']['enable'] == 0:
# self.mydir.setHeader(self.raw_wavelength,TOKEN,self.ui_sn)
# if self.mydir.checkHeader()==0:
# self.mydir.writeHeader()
# if self.mydir.checkHeader()==-1:
# self.popDialog(" 文件头不一致, 请备份到其他目录,并在该目录下删除")
# raise MyException(" 文件头不一致, 请备份到其他目录,并在该目录下删除")
# res_time,res_data = ReadCal.read_columns_sets_by_mark( fl, FILE_MARK, 1 )
# for i in range( len(res_time) ):
# self.__deal_one_measure_time_data(res_time[i], res_data[i])
# pass
# pass
# # 需要插值处理波长
# if self.syscfg['retrieve']['enable'] == 1:
# self.mydir.setHeader(self.new_wavelength.tolist(),TOKEN,self.ui_sn)
# if self.mydir.checkHeader()==0:
# self.mydir.writeHeader()
# if self.mydir.checkHeader()==-1:
# self.popDialog(" 文件头不一致, 请备份到其他目录,并在该目录下删除")
# raise MyException(" 文件头不一致, 请备份到其他目录,并在该目录下删除")
# # res_data 不用带回调的函数callback 会导致多组数据拼接??
# res_time,res_data = ReadCal.read_columns_sets_by_mark( fl, FILE_MARK, 1 )
# log.warning(f" ==== {len(res_time)}" )
# log.warning(res_time)
# log.warning(f" ==== {len(res_data[0])}" )
# log.warning(f" ==== { res_data[0] }" )
# for i in range( len(res_time) ):
# self.__deal_one_measure_time_data(res_time[i], res_data[0][i])
# pass
# pass
# def __deal_one_measure_time_data(self,res_time,res_data):
# if self.syscfg['retrieve']['enable'] == 0:
# self.mydir.setContent(res_data ,TOKEN,res_time )
# self.mydir.writeContent()
# # 插值处理
# if self.syscfg['retrieve']['enable'] == 1:
# # tmp_data = np.interp( self.new_wavelength, np.array(self.raw_wavelength) , np.array(res_data) )
# x = self.new_wavelength
# xp = np.array(self.raw_wavelength).astype(np.float32)
# fp = np.array(res_data).astype(np.float32)
# log.warning(f" {x}")
# log.warning(f" {xp.shape }")
# log.warning(f" { fp.shape }")
# tmp_data = np.interp( x, xp , fp )
# # tmp_data = np.interp( self.new_wavelength.tolist(), self.raw_wavelength , res_data[0] )
# self.mydir.setContent( tmp_data ,TOKEN, res_time )
# self.mydir.writeContent()
# pass
# def __deal_one_file(self,fpath):
# res_time,res_data = ReadCal.read_columns_sets_by_mark( fpath, FILE_MARK, 1 )
# for i in range( len(res_time) ):
# if self.syscfg['retrieve']['enable'] == 0:
# self.mydir.setContent(res_data[i],TOKEN,res_time[i])
# self.mydir.writeContent()
# # 插值处理
# if self.syscfg['retrieve']['enable'] == 1:
# self.mydir.setContent(res_data[i],TOKEN,res_time[i])
# self.mydir.writeContent()
# pass
# pass
# def __set_serial(self, )-> None:
# self.uart.set_serial_para(
# self.syscfg['comsetting']['port']
# ,self.syscfg['comsetting']['baudrate']
# ,self.syscfg['comsetting']['bytesize']
# ,self.syscfg['comsetting']['parity']
# ,self.syscfg['comsetting']['stopbit']
# )
# def __set_modbus(self, beginaddress, step)-> None:
# self.uart.set_modbus(
# self.syscfg['register']['slaveadress']
# ,self.syscfg['register']['functioncode']
# ,beginaddress
# ,step
# )
Loading…
Cancel
Save