|  | 1 | = EPICS講習会で使用しているテスト用の simulator (simFG) = | 
          
            |  | 2 |  | 
          
            |  | 3 | KEKで何度か開催されている[https://cerldev.kek.jp/trac/EpicsUsersJP/#EPICS%E5%85%A5%E9%96%80%E8%AC%9B%E7%BF%92%E4%BC%9A%E8%B3%87%E6%96%99%E3%81%AA%E3%81%A9 EPICS講習会]のstream deviceで使用してる simFG のソースコードです。 | 
          
            |  | 4 |  | 
          
            |  | 5 | ご自由にお使いください。 | 
          
            |  | 6 |  | 
          
            |  | 7 | {{{ | 
          
            |  | 8 | #!/usr/bin/python | 
          
            |  | 9 | import socketserver | 
          
            |  | 10 | import string | 
          
            |  | 11 | import sys | 
          
            |  | 12 | import time | 
          
            |  | 13 | import signal | 
          
            |  | 14 | import random | 
          
            |  | 15 | import math | 
          
            |  | 16 | import traceback | 
          
            |  | 17 | import re | 
          
            |  | 18 |  | 
          
            |  | 19 | HOST = '' | 
          
            |  | 20 | PORT = 9999 | 
          
            |  | 21 |  | 
          
            |  | 22 | class EchoHandler(socketserver.BaseRequestHandler): | 
          
            |  | 23 | def handle(self): | 
          
            |  | 24 | self.t0 = time.time() | 
          
            |  | 25 | print(time.ctime(self.t0), "  Connected from ", self.client_address) | 
          
            |  | 26 |  | 
          
            |  | 27 | # constant | 
          
            |  | 28 | self.freq = 0.2   # frequency | 
          
            |  | 29 | self.amp  = 5.0   # ammplitude | 
          
            |  | 30 | self.offset = 0.0 # offset | 
          
            |  | 31 |  | 
          
            |  | 32 | # inner command functions | 
          
            |  | 33 | def _getIDN(): | 
          
            |  | 34 | return "Simulator" | 
          
            |  | 35 |  | 
          
            |  | 36 | def _getVolt(): | 
          
            |  | 37 | return self.creRetStr() | 
          
            |  | 38 |  | 
          
            |  | 39 | def _getAmp(): | 
          
            |  | 40 | return '%f' % self.amp | 
          
            |  | 41 |  | 
          
            |  | 42 | def _getFreq(): | 
          
            |  | 43 | return '%f' % self.freq | 
          
            |  | 44 |  | 
          
            |  | 45 | def _getOffset(): | 
          
            |  | 46 | return '%f' % self.offset | 
          
            |  | 47 |  | 
          
            |  | 48 | def _getStat(): | 
          
            |  | 49 | return '%f,%f,%f' %(self.amp, self.freq, self.offset) | 
          
            |  | 50 |  | 
          
            |  | 51 | def _getInfo(): | 
          
            |  | 52 | return 'AMP:%f,FREQ:%f,OFFSET:%f' %(self.amp, self.freq, self.offset) | 
          
            |  | 53 |  | 
          
            |  | 54 | def _setAmp(buf): | 
          
            |  | 55 | val = self.checkarg(buf) | 
          
            |  | 56 | if val: | 
          
            |  | 57 | self.amp = val | 
          
            |  | 58 |  | 
          
            |  | 59 | def _setFreq(buf): | 
          
            |  | 60 | val = self.checkarg(buf) | 
          
            |  | 61 | if val: | 
          
            |  | 62 | self.freq = val | 
          
            |  | 63 |  | 
          
            |  | 64 | def _setOffset(buf): | 
          
            |  | 65 | val = self.checkarg(buf) | 
          
            |  | 66 | if val: | 
          
            |  | 67 | self.offset = val | 
          
            |  | 68 |  | 
          
            |  | 69 |  | 
          
            |  | 70 | # commands dictionary | 
          
            |  | 71 | cmnds = { | 
          
            |  | 72 | 'QUIT'  :{'set':None,             'qry':None}, | 
          
            |  | 73 | '*IDN'  :{'set':None,             'qry':_getIDN}, | 
          
            |  | 74 | 'VOLT'  :{'set':None,             'qry':_getVolt}, | 
          
            |  | 75 | 'AMP'   :{'set':_setAmp,          'qry':_getAmp}, | 
          
            |  | 76 | 'FREQ'  :{'set':_setFreq,         'qry':_getFreq}, | 
          
            |  | 77 | 'OFFSET':{'set':_setOffset,       'qry':_getOffset}, | 
          
            |  | 78 | 'STAT'  :{'set':None,             'qry':_getStat}, | 
          
            |  | 79 | 'INFO'  :{'set':None,             'qry':_getInfo} | 
          
            |  | 80 | } | 
          
            |  | 81 |  | 
          
            |  | 82 |  | 
          
            |  | 83 | flag = True | 
          
            |  | 84 | fid = self.request.makefile() | 
          
            |  | 85 | while flag: | 
          
            |  | 86 | receivedData = fid.readline() | 
          
            |  | 87 | if not receivedData: break | 
          
            |  | 88 | try: | 
          
            |  | 89 | # buf = string.strip(receivedData) | 
          
            |  | 90 | buf = receivedData.strip() | 
          
            |  | 91 | # sparate command string | 
          
            |  | 92 | # comd = string.upper(re.split('[ ?]', buf)[0]) | 
          
            |  | 93 | comd = re.split('[ ?]', buf)[0].upper() | 
          
            |  | 94 | if len(comd) >=3: | 
          
            |  | 95 | rtn = None | 
          
            |  | 96 | # if cmnds.has_key(comd): | 
          
            |  | 97 | if comd in cmnds.keys(): | 
          
            |  | 98 | cmndDic = cmnds[comd] | 
          
            |  | 99 | # "QUIT" is special command | 
          
            |  | 100 | if comd == "QUIT": | 
          
            |  | 101 | flag = False | 
          
            |  | 102 | else: | 
          
            |  | 103 | if buf[len(comd)] == '?': | 
          
            |  | 104 | if cmndDic['qry'] != None: | 
          
            |  | 105 | rtn = cmndDic['qry']() + '\r\n' | 
          
            |  | 106 | rtn = rtn.encode() | 
          
            |  | 107 | else: | 
          
            |  | 108 | if cmndDic['set'] != None: | 
          
            |  | 109 | cmndDic['set'](buf) | 
          
            |  | 110 |  | 
          
            |  | 111 | if rtn != None: | 
          
            |  | 112 | self.request.send(rtn) | 
          
            |  | 113 | except: | 
          
            |  | 114 | traceback.print_exc() | 
          
            |  | 115 | pass | 
          
            |  | 116 |  | 
          
            |  | 117 | fid.close() | 
          
            |  | 118 | self.request.close() | 
          
            |  | 119 | print(time.ctime(time.time()), "  Disconnected (from ", self.client_address, ")") | 
          
            |  | 120 |  | 
          
            |  | 121 | def checkarg(self, buf): | 
          
            |  | 122 | try: | 
          
            |  | 123 | c,v = buf.strip().split() | 
          
            |  | 124 | val = float(v) | 
          
            |  | 125 | except: | 
          
            |  | 126 | #traceback.print_exc() | 
          
            |  | 127 | val = None | 
          
            |  | 128 | return val | 
          
            |  | 129 |  | 
          
            |  | 130 | def creRetStr(self): | 
          
            |  | 131 | #random.seed() | 
          
            |  | 132 | t = time.time() - self.t0 | 
          
            |  | 133 | val = self.amp * math.sin(2*math.pi*self.freq*t) + random.random()*1.0 + self.offset | 
          
            |  | 134 | #buf = "A=%8.4f, B=%8.4f, C=%8.4f"%(val,val,val2*2.345) | 
          
            |  | 135 | buf = "%8.4f"%val | 
          
            |  | 136 | return buf | 
          
            |  | 137 |  | 
          
            |  | 138 | # end of class EchoHandler | 
          
            |  | 139 |  | 
          
            |  | 140 | def signal_handler(signal, frame): | 
          
            |  | 141 | sys.exit(0) | 
          
            |  | 142 |  | 
          
            |  | 143 | # __ main __ | 
          
            |  | 144 | if __name__ == '__main__': | 
          
            |  | 145 | signal.signal(signal.SIGINT, signal_handler) | 
          
            |  | 146 | socketserver.ForkingTCPServer.allow_reuse_address = True | 
          
            |  | 147 | srv = socketserver.ForkingTCPServer((HOST,PORT), EchoHandler) | 
          
            |  | 148 | print("StreamDevice Simulator started.") | 
          
            |  | 149 | srv.serve_forever() | 
          
            |  | 150 | }}} |