def get_state(self): msg = { "type": "geigerjson", "node_uuid": cfg.get('node','uuid'), "timestamp": int(datetime.datetime.now().strftime("%s")), "geostamp": { "lat": cfg.getfloat('node','lat'), "lon": cfg.getfloat('node','lon'), "alt": cfg.getfloat('node','alt') }, "parameters": { "tube_id": cfg.get('geigercounter','tube_id'), "dead_time": cfg.getfloat('geigercounter','tube_dead_time'), "tube_factor": cfg.getfloat('geigercounter','tube_rate_factor'), "opmode": cfg.get('node', 'opmode'), "window": cfg.get('geigercounter', 'window') }, "data": { "source": cfg.get('geigercounter', 'source') if gpio_available else "sim", "cps": self.cps, "cps_dtc": self.cps_dtc, "cpm": self.cpm, "cpm_dtc": self.cpm_dtc, "totalcount": self.totalcount, "totalcount_dtc": self.totalcount_dtc, "edr": self.edr }, "annotation": "" } return msg
def run(self): while True: ratefactor = cfg.getfloat('geigercounter','tube_rate_factor') simrate = cfg.getfloat('geigercounter','sim_dose_rate') rate = simrate/ratefactor time.sleep(random.random()/rate*120) self.geiger.tick()
def get_log_entries_sparse(self,start,end,amount): result = [] delta_total = end - start delta_step = delta_total / amount step = 0 while True: t = start + delta_step * step if t > end: break if step >= 1: t_prev = start + delta_step * (step - 1) annotation_keys = list(self.db_annotation.RangeIter(key_from=str(t_prev),key_to=str(t),include_value=False)) if annotation_keys: for key in annotation_keys: result.append(json.loads(self.db.Get(key))) db_iter = self.db.RangeIter(key_from=str(t),fill_cache=True) try: (timestamp,entry_json) = db_iter.next() except StopIteration: break; entry = json.loads(entry_json) if int(timestamp)-t>MAX_ENTRY_DIST: entry=dummy_entry(t,entry['data']['totalcount'],entry['data']['totalcount_dtc']) if not result: result.append(entry) elif result[-1] != entry: result.append(entry) step += 1 return average_log_entries(result,cfg.getfloat('geigercounter','tube_rate_factor'))
def run(self): if gpio_available: GPIO.setmode(GPIO.BCM) gpio_port = cfg.getint('geigercounter','gpio_port') GPIO.setup(gpio_port,GPIO.IN) GPIO.add_event_detect(gpio_port,GPIO.FALLING) GPIO.add_event_callback(gpio_port,self.tick) # I2C config for HV output i2c_addr = 0x19 bus = smbus.SMBus(1) # I2C1 port bus.write_byte(i2c_addr, 0x71) else: TickSimulator(self).start() cpm_fifo = deque([],60) cpm_dtc_fifo = deque([],60) while True: time.sleep(1) # Statistical correction of tube dead-time if gpio_available: deadtime = cfg.getfloat('geigercounter','tube_dead_time') count_dtc = int(self.count/(1-(self.count*deadtime))) else: count_dtc = self.count cpm_fifo.appendleft(self.count) cpm_dtc_fifo.appendleft(count_dtc) self.cpm = int(sum(cpm_fifo)*60.0/len(cpm_fifo)) self.cpm_dtc = int(sum(cpm_dtc_fifo)*60.0/len(cpm_dtc_fifo)) self.cps = self.count self.cps_dtc = count_dtc ratefactor = cfg.getfloat('geigercounter','tube_rate_factor') self.edr = round(self.cpm_dtc * ratefactor,2) self.totalcount_dtc += (count_dtc - self.count) self.count = 0 log.debug(self.get_state())
def run(self): if gpio_available: GPIO.setmode(GPIO.BCM) gpio_port = cfg.getint('geigercounter','gpio_port') GPIO.setup(gpio_port,GPIO.IN) GPIO.add_event_detect(gpio_port,GPIO.FALLING) GPIO.add_event_callback(gpio_port,self.tick) else: TickSimulator(self).start() cpm_fifo = deque([],60) cpm_dtc_fifo = deque([],60) while True: time.sleep(1) # Statistical correction of tube dead-time if gpio_available: deadtime = cfg.getfloat('geigercounter','tube_dead_time') count_dtc = int(self.count/(1-(self.count*deadtime))) else: count_dtc = self.count cpm_fifo.appendleft(self.count) cpm_dtc_fifo.appendleft(count_dtc) self.cpm = int(sum(cpm_fifo)*60.0/len(cpm_fifo)) self.cpm_dtc = int(sum(cpm_dtc_fifo)*60.0/len(cpm_dtc_fifo)) self.cps = self.count self.cps_dtc = count_dtc ratefactor = cfg.getfloat('geigercounter','tube_rate_factor') self.edr = round(self.cpm_dtc * ratefactor,2) self.totalcount_dtc += (count_dtc - self.count) self.count = 0 log.debug(self.get_state())
def get_log_entries_sparse(self, start, end, amount): result = [] delta_total = end - start delta_step = delta_total / amount step = 0 while True: t = start + delta_step * step if t > end: break if step >= 1: t_prev = start + delta_step * (step - 1) annotation_keys = list( self.db_annotation.RangeIter(key_from=str(t_prev), key_to=str(t), include_value=False)) if annotation_keys: for key in annotation_keys: result.append(json.loads(self.db.Get(key))) db_iter = self.db.RangeIter(key_from=str(t), fill_cache=True) try: (timestamp, entry_json) = db_iter.next() except StopIteration: break entry = json.loads(entry_json) if int(timestamp) - t > MAX_ENTRY_DIST: entry = dummy_entry(t, entry['data']['totalcount'], entry['data']['totalcount_dtc']) if not result: result.append(entry) elif result[-1] != entry: result.append(entry) step += 1 return average_log_entries( result, cfg.getfloat('geigercounter', 'tube_rate_factor'))
from entropygenerator import EntropyGenerator log = logging.getLogger(__name__) try: import RPi.GPIO as GPIO import smbus gpio_available = True except ImportError: log.info("+---------------------------------------------------------------------------+") log.info("| Could not import RPi.GPIO or smbus python modules. |") log.info("| I'm assuming you are in development/show mode on another host system |") log.info("| If this is a Raspberry PI and you want real counts, you'll need to |") log.info("| install RPi.GPIO and smbus. |") log.info("+---------------------------------------------------------------------------+") log.info("Engaging TickSimulator with an avg. radiation level of %(edr)s uSv/h instead" % {"edr": cfg.getfloat('geigercounter','sim_dose_rate')}) gpio_available = False class TickSimulator (threading.Thread): def __init__(self, geiger): threading.Thread.__init__(self) self.daemon = True self.geiger = geiger log.info("Starting tick simulator") def run(self): while True: ratefactor = cfg.getfloat('geigercounter','tube_rate_factor') simrate = cfg.getfloat('geigercounter','sim_dose_rate') rate = simrate/ratefactor time.sleep(random.random()/rate*120)
) log.info( "| I'm assuming you are in development/show mode on another host system |" ) log.info( "| If this is a Raspberry PI and you want real counts, you'll need to |" ) log.info( "| install RPi.GPIO and smbus. |" ) log.info( "+---------------------------------------------------------------------------+" ) log.info( "Engaging TickSimulator with an avg. radiation level of %(edr)s uSv/h instead" % {"edr": cfg.getfloat('geigercounter', 'sim_dose_rate')}) gpio_available = False class TickSimulator(threading.Thread): def __init__(self, geiger): threading.Thread.__init__(self) self.daemon = True self.geiger = geiger log.info("Starting tick simulator") def run(self): while True: ratefactor = cfg.getfloat('geigercounter', 'tube_rate_factor') simrate = cfg.getfloat('geigercounter', 'sim_dose_rate') rate = simrate / ratefactor
def receive_commands(self, handler): #FIXME: some commands need clearer names #FIXME: more robust error/edgecase handling while True: try: message = self.ws.receive() if message is None: raise WebSocketError log.info("Received : %s" % message) msg = json.loads(message) cmd = msg.get("cmd") if not cmd: log.error("Received something, but not a command: %s" % msg) #Ticks if cmd == "send_ticks": if msg.get("state") == "on": self.send_ticks = True elif msg.get("state") == "off": self.send_ticks = False else: log.error("Invalid set_ticks command: %s" % msg) #Log elif cmd == "read": age_seconds = int(msg.get("age", 60 * 60)) if msg.get("hd"): handler.send_log(self, age=age_seconds, amount=None) else: handler.send_log(self, age=age_seconds, amount=1000) elif cmd == "history": age_from = msg.get("from") age_to = msg.get("to") #log.info("From %s to %s"%(str(age_from),str(age_to))) handler.send_log(self, start=age_from, end=age_to, amount=1000, static=True) elif cmd == "annotation": ts = msg.get("timestamp") text = msg.get("text") handler.geigerlog.set_annotation(ts, text) handler.send_log(start=age_from, end=age_to, amount=1000, static=True) #Config elif cmd == "get": try: entropy_pool = os.path.getsize( cfg.get('entropy', 'filename')) except (IOError, OSError): entropy_pool = 0 conf = { "type": "geigerconf", "uuid": cfg.get('node', 'uuid'), "name": cfg.get('node', 'name'), "opmode": cfg.get('node', 'opmode'), "lat": cfg.getfloat('node', 'lat'), "lon": cfg.getfloat('node', 'lon'), "alt": cfg.getfloat('node', 'alt'), "sim_dose_rate": cfg.getfloat('geigercounter', 'sim_dose_rate'), "window": cfg.get('geigercounter', 'window'), "source": cfg.get('geigercounter', 'source') if geigercounter.gpio_available else "sim", "entropy": cfg.getboolean('entropy', 'enable'), "entropy_pool": entropy_pool } self.send(conf) elif cmd == "save": for field in ["lat", "lon", "alt", "opmode"]: val = msg["conf"].get(field) if not val is None: cfg.set('node', field, str(val)) for field in ["window", "source", "sim_dose_rate"]: val = msg["conf"].get(field) if not val is None: cfg.set('geigercounter', field, str(val)) entropy_enable = msg["conf"].get("entropy") if not entropy_enable is None: cfg.set('entropy', 'enable', str(entropy_enable)) cfg.write_dynamic() cfg.read_dynamic() elif cmd == "resetEntropy": log.info("Resetting entropy file") os.remove( os.path.join(script_dir, cfg.get('entropy', 'filename'))) elif cmd == "resetDynamicCfg": log.info("Resetting client config") cfg.clear_dynamic() except WebSocketError: break log.info("websocket closed %s (client %s)" % (self.ws.path, self.session_id))
def receive_commands(self,handler): #FIXME: some commands need clearer names #FIXME: more robust error/edgecase handling while True: try: message = self.ws.receive() if message is None: raise WebSocketError log.info("Received : %s" % message) msg = json.loads(message) cmd = msg.get("cmd") if not cmd: log.error("Received something, but not a command: %s"%msg) #Ticks if cmd == "send_ticks": if msg.get("state") == "on": self.send_ticks = True elif msg.get("state") == "off": self.send_ticks = False else: log.error("Invalid set_ticks command: %s"%msg) #Log elif cmd == "read": age_seconds = int(msg.get("age",60*60)); if msg.get("hd"): handler.send_log(self,age=age_seconds,amount=None) else: handler.send_log(self,age=age_seconds,amount=1000) elif cmd == "history": age_from = msg.get("from") age_to = msg.get("to") #log.info("From %s to %s"%(str(age_from),str(age_to))) handler.send_log(self,start=age_from,end=age_to,amount=1000,static=True) elif cmd == "annotation": ts = msg.get("timestamp") text = msg.get("text") handler.geigerlog.set_annotation(ts,text) handler.send_log(start=age_from,end=age_to,amount=1000,static=True) #Config elif cmd == "get": try: entropy_pool = os.path.getsize(cfg.get('entropy','filename')) except (IOError, OSError): entropy_pool = 0 conf = { "type": "geigerconf", "uuid": cfg.get('node','uuid'), "name": cfg.get('node','name'), "opmode": cfg.get('node','opmode'), "lat": cfg.getfloat('node','lat'), "lon": cfg.getfloat('node','lon'), "alt": cfg.getfloat('node','alt'), "sim_dose_rate": cfg.getfloat('geigercounter','sim_dose_rate'), "window": cfg.get('geigercounter','window'), "source": cfg.get('geigercounter','source') if geigercounter.gpio_available else "sim", "entropy": cfg.getboolean('entropy','enable'), "entropy_pool": entropy_pool } self.send(conf) elif cmd == "save": for field in ["lat","lon","alt","opmode"]: val = msg["conf"].get(field) if not val is None: cfg.set('node',field,str(val)) for field in ["window","source","sim_dose_rate"]: val = msg["conf"].get(field) if not val is None: cfg.set('geigercounter',field,str(val)) entropy_enable = msg["conf"].get("entropy") if not entropy_enable is None: cfg.set('entropy','enable',str(entropy_enable)) cfg.write_dynamic() cfg.read_dynamic() elif cmd == "resetEntropy": log.info("Resetting entropy file") os.remove(os.path.join(script_dir,cfg.get('entropy','filename'))) elif cmd == "resetDynamicCfg": log.info("Resetting client config") cfg.clear_dynamic() except WebSocketError: break log.info("websocket closed %s (client %s)"%(self.ws.path,self.session_id))
from collections import deque from configurator import cfg from entropygenerator import EntropyGenerator log = logging.getLogger(__name__) try: import RPi.GPIO as GPIO gpio_available = True except ImportError: log.info("+---------------------------------------------------------------------------+") log.info("| Could not import RPi.GPIO python module. |") log.info("| I'm assuming you are in development/show mode on another host system |") log.info("| If this is a Raspberry PI/PiGI and you want real counts, install RPi.GPIO |") log.info("+---------------------------------------------------------------------------+") log.info("Engaging TickSimulator with an avg. radiation level of %(edr)s uSv/h instead" % {"edr": cfg.getfloat('geigercounter','sim_dose_rate')}) gpio_available = False class TickSimulator (threading.Thread): def __init__(self, geiger): threading.Thread.__init__(self) self.daemon = True self.geiger = geiger log.info("Starting tick simulator") def run(self): while True: ratefactor = cfg.getfloat('geigercounter','tube_rate_factor') simrate = cfg.getfloat('geigercounter','sim_dose_rate') rate = simrate/ratefactor time.sleep(random.random()/rate*120)