class MessageHandler(object): """ Handler that allows the system to manage messages """ def __init__(self, request): self.session = DBSession() self.request = request self.message = self.session.\ query(Message).filter_by( uuid=self.request.matchdict["id"]).first() @action(renderer='sms/index_msg.mako', permission='admin') def index(self): global breadcrumbs breadcrumbs.extend({}) return { 'breadcrumbs': breadcrumbs, 'message': self.message} @action(request_method="POST") def remove(self): self.message.sent = True self.session.merge(self.message) return Response("ok") @action(permission='admin') def delete(self): self.session.delete(self.message) self.session.flush() return HTTPFound(location='/')
class InterfaceHandler(object): """ A handler for managing the interfaces. """ def __init__(self, request): self.breadcrumbs = breadcrumbs self.request = request self.session = DBSession() self.interface = self.session.query( CommunicationInterface).get(self.request.matchdict.get('id')) @action(renderer='interface/index.mako', permission='admin') def index(self): breadcrumbs = self.breadcrumbs[:] breadcrumbs.append({'text': 'Interface overview'}) return {'interface': self.interface, 'breadcrumbs': breadcrumbs, 'fields': get_fields(self.interface), 'logged_in': authenticated_userid(self.request)} def save_and_parse_message(self, origin, text, id=None): """ Function to save incoming message based on relay type. Takes the message class, the numner, the body of the message and a session. Optional argument is the messages id. Parses the message and return the message object. """ if id is None: id = str(uuid.uuid4()) message = IncomingMessage(origin, text, id, self.interface) self.session.add(message) self.session.flush() dispatcher.matchMessage(message) return message @action() def send(self): msg = self.save_and_parse_message(self.request.params['number'], self.request.params['message']) return Response(msg.uuid) @action() def remove(self): self.session.delete(self.interface) self.session.flush() return HTTPFound(location="%s/" % self.request.application_url)
class SMSHandler(object): """ Handler for most SMS operations """ def __init__(self, request): self.request = request self.breadcrumbs = breadcrumbs[:] self.session = DBSession() @action(renderer="sms/index.mako", permission="view") def index(self): breadcrumbs = self.breadcrumbs[:] breadcrumbs.append({"text": "SMS Message"}) limit = self.request.params.get('limit', 1000) count = self.session.query(Message).count() messages = self.session.\ query(Message).order_by(desc(Message.id)).limit(limit) return { "limit": limit, "count": count, "messages": messages, "table_headers": make_table_header(OutgoingMessage), "breadcrumbs": breadcrumbs} @action(renderer='sms/meter_messages.mako', permission='view') def meter_messages(self): from sqlalchemy import create_engine db_string = self.request.registry.settings.get('db_string') engine = create_engine(db_string, echo=False) conn = engine.connect() results = conn.execute( """ SELECT meter.name, meter.id, incoming_message.text, message.date FROM meter, message, incoming_message WHERE meter.phone = message.number AND message.id = incoming_message.id ORDER BY message.date DESC LIMIT 1000; """) return {'results': results} @action(permission="view") def remove_all(self): [self.session.delete(msg) for msg in self.session.query(Message).all()] return HTTPFound( location="%s/sms/index" % self.request.application_url) @action() def ping(self): return Response('ok') @action() def received(self): msgs = [msg.toDict() for msg in self.session.query(Message).\ filter_by(sent=False).filter(or_(Message.type == "job_message", Message.type == "outgoing_message")).all() if msg.number != ''] return Response( content_type="application/json", body=simplejson.dumps(msgs))
class InterfaceHandler(object): """ A handler for managing the interfaces. """ def __init__(self, request): self.breadcrumbs = breadcrumbs self.request = request self.session = DBSession() self.interface = self.session.query( CommunicationInterface).get(self.request.matchdict.get('id')) @action(renderer='interface/index.mako', permission='admin') def index(self): breadcrumbs = self.breadcrumbs[:] breadcrumbs.append({'text': 'Interface overview'}) messages = self.session.query(IncomingMessage)\ .filter_by(communication_interface=self.interface)\ .order_by(desc(IncomingMessage.id))\ .limit(200) return {'interface': self.interface, 'breadcrumbs': breadcrumbs, 'messages': messages, 'fields': get_fields(self.interface)} @action() def send(self): msg = save_and_parse_message( self.interface, self.request.params['number'], self.request.params['message']) return Response(msg.uuid) @action(permission='admin') def remove(self): self.session.delete(self.interface) self.session.flush() return HTTPFound(location="%s/" % self.request.application_url)
class SMSHandler(object): """ Handler for most SMS operations """ def __init__(self, request): self.request = request self.breadcrumbs = breadcrumbs[:] self.session = DBSession() @action(renderer="sms/index.mako", permission="admin") def index(self): breadcrumbs = self.breadcrumbs[:] breadcrumbs.append({"text": "SMS Message"}) limit = self.request.params.get('limit', 1000) count = self.session.query(Message).count() messages = self.session.\ query(Message).order_by(desc(Message.id)).limit(limit) return { "logged_in": authenticated_userid(self.request), "limit": limit, "count": count, "messages": messages, "table_headers": make_table_header(OutgoingMessage), "breadcrumbs": breadcrumbs } @action(permission="admin") def remove_all(self): [self.session.delete(msg) for msg in self.session.query(Message).all()] return HTTPFound( location="%s/sms/index" % self.request.application_url) @action() def ping(self): return Response('ok') @action() def received(self): msgs = [msg.toDict() for msg in self.session.query(Message).\ filter_by(sent=False).filter(or_(Message.type == "job_message", Message.type == "outgoing_message")).all() if msg.number != ''] return Response( content_type="application/json", body=simplejson.dumps(msgs))
class CircuitHandler(object): """ Circuit handler. Has all of the most important urls for managing circuits """ def __init__(self, request): self.session = DBSession() self.request = request self.circuit = self.session.\ query(Circuit).get(self.request.matchdict["id"]) self.meter = self.circuit.meter self.breadcrumbs = breadcrumbs[:] @action(renderer='circuit/index.mako', permission='view') def index(self): """ """ breadcrumbs = self.breadcrumbs[:] breadcrumbs.extend([ {'text': 'Meters', 'url': '/manage/show_meters'}, {'text': 'Meter Overview', 'url': self.meter.getUrl()}, {'text': 'Circuit Overview'}]) return { 'logged_in': authenticated_userid(self.request), 'breadcrumbs': breadcrumbs, 'circuit': self.circuit} @action(permission='admin') def turn_off(self): self.circuit.turnOff() return HTTPFound(location=self.circuit.getUrl()) @action(permission='admin') def turn_on(self): self.circuit.turnOn() return HTTPFound(location=self.circuit.getUrl()) @action(permission='admin') def ping(self): self.circuit.ping() return HTTPFound(location=self.circuit.getUrl()) @action(permission='admin') def remove_jobs(self): [self.session.delete(job) for job in self.circuit.get_jobs()] return HTTPFound( location="%s%s" % (self.request.application_url, self.circuit.getUrl())) @action() def jobs(self): return Response([x.toJSON() for x in self.circuit.get_jobs()]) @action() def show_primary_logs(self): session = DBSession() logs = session.query(PrimaryLog)\ .filter_by(circuit=self.circuit)\ .order_by(desc(PrimaryLog.created))\ .limit(200) return json_response([{'id': l.id, 'status': l.status, 'use_time': l.use_time, 'gateway_date': l.created.strftime('%Y-%m-%d %H:%M:%S'), 'meter_date': l.date.strftime('%Y-%m-%d %H:%M:%S'), 'time_difference': find_time_different(l), 'watthours': "{0:.1f}".format(l.watthours), 'credit': int(l.credit)} for l in logs]) @action() def show_graphing_logs(self): session = DBSession() value = self.request.params.get('value', 'watthours') start = datetime.strptime(self.request.params.get('start', '05/01/2011'), '%m/%d/%Y') end = datetime.strptime(self.request.params.get('end', '06/01/2011'), '%m/%d/%Y') logs = session.query(PrimaryLog)\ .filter(PrimaryLog.circuit == self.circuit)\ .filter(PrimaryLog.date > start)\ .filter(PrimaryLog.date <= end)\ .order_by(PrimaryLog.created) if value == 'use_time': values = map(lambda x: (getattr(x, value) / 3600), logs) else: values = map(lambda x: getattr(x, value), logs) return json_response( {'dates': map(lambda x: time.mktime(x.date.timetuple()), logs), 'values': values } ) @action(permission='view') def get_payment_logs(self): """ A view to render a circuit's payment history as a json object. """ session = DBSession() payments = session.query(AddCredit)\ .filter_by(circuit=self.circuit).order_by(desc(AddCredit.start)) return json_response( {'payments': [{'id': p.id, 'status': p.state, 'token': str(p.token), 'start': str(p.start), 'credit': p.credit, 'end': str(p.end), 'state': p.state} for p in payments]}) @action(permission='admin') def add_credit(self): interface = self.circuit.meter.communication_interface job = AddCredit(circuit=self.circuit, credit=self.request.params.get("amount")) self.session.add(job) self.session.flush() interface.sendJob(job) return HTTPFound(location=self.circuit.getUrl()) @action(permission="admin") def remove(self): self.session.delete(self.circuit) return HTTPFound(location=self.meter.getUrl())
class MeterHandler(object): """ Meter handler, allows for user to edit and manage meters """ def __init__(self, request): self.request = request self.session = DBSession() self.meter = self.session.query(Meter).\ get(self.request.matchdict['id']) self.breadcrumbs = breadcrumbs[:] def show_billing_history(self): return Response('hi') def getDataListForCircuit(self, circuit_id, dateStart=datetime(2011, 5, 12), dateEnd=datetime(2011, 5, 13), quantity='watthours', verbose=0): session = DBSession() # get query based on circuit and date logs = session.query(PrimaryLog)\ .filter(PrimaryLog.circuit_id == circuit_id)\ .filter(PrimaryLog.date > dateStart)\ .filter(PrimaryLog.date <= dateEnd)\ .order_by(PrimaryLog.date) # turn query into a sorted list of unique dates and watthour readings data = [(l.date, getattr(l, quantity)) for l in logs] # remove duplicate entries and sort by date data = list(set(data)) data.sort() dates = [d[0] for d in data] watthours = [d[1] for d in data] return dates, watthours @action(renderer='meter/alerts.mako', permission='view') def alerts(self): session = DBSession() alerts = session.query(Alert).filter_by(meter=self.meter) return {'alerts': alerts} @action() def show_pculogs(self): session = DBSession() value = self.request.params.get('pcu-value', 'battery_volts') start = datetime.strptime( self.request.params.get('start', '05/01/2011'), '%m/%d/%Y') end = datetime.strptime( self.request.params.get('end', '07/20/2011'), '%m/%d/%Y') pculogs = session.query(PCULog)\ .filter(PCULog.meter == self.meter)\ .filter(PCULog.timestamp >= start)\ .filter(PCULog.timestamp <= end) return json_response( {'dates': map(lambda x: time.mktime(x.timestamp.timetuple()), pculogs), 'values': map(lambda x: getattr(x, value), pculogs)}) @action(renderer="meter/index.mako", permission="view") def index(self): """ Main view for meter overview. Also includes circuit gird and some graphs """ session = DBSession() breadcrumbs = self.breadcrumbs[:] breadcrumbs.append({'text': 'Meters', 'url': '/manage/show_meters'}) breadcrumbs.append({"text": "Meter Overview"}) return { 'meter': self.meter, 'last_message': find_last_message_by_meter(self.meter), 'changesets': session\ .query(MeterChangeSet).filter_by(meter=self.meter), 'meter_config_keys': session.query(MeterConfigKey).all(), 'breadcrumbs': breadcrumbs} @action() def update_config(self): return Response('ok') @action(renderer='meter/messsage_graph.mako', permission='view') def message_graph(self): """ Message table. """ output = cStringIO.StringIO() d = collections.defaultdict(list) logs = self.meter.getLogs() cids = sorted([c.id for c in self.meter.get_circuits()]) for log in logs: d[log.date.strftime('%Y.%m.%d.%H.%M')].append(log) for key in sorted(d.iterkeys(), reverse=True): log_cids = [log.circuit.id for log in d[key]] output.write(str(key) + " | ") output.write(" ".join([str(x).ljust(3) if x in log_cids else ' - ' for x in cids])) output.write("\n") return Response(output.getvalue(), content_type="text/plain") @action(permission='admin') def show_account_numbers(self): """ Returns the account numbers as a csv file. """ output = cStringIO.StringIO() output.write('Pin, IpAddress \n') for c in self.meter.get_circuits(): output.write('%s, %s\n' % (c.pin, c.ip_address)) resp = Response(output.getvalue()) resp.content_type = 'application/x-csv' resp.headers.add('Content-Disposition', 'attachment;filename=%s:accounts.csv' % \ str(self.meter.name)) return resp # this serialization should be a class method. @action(permission='view') def circuits(self): now = datetime.now() last_month = now - timedelta(days=30) return json_response( [{'id':x.id, 'ipaddress': x.ip_address, 'language': x.account.lang, 'watthours': x.getWatthours(), 'last_msg': x.getLastLogTime(), 'credit_consumed': int(x.calculateCreditConsumed(last_month, now)), 'status': x.status, 'number_of_recharges': x.get_number_of_recharges(), 'account': x.pin, 'credit': int(x.credit) } for x in self.meter.get_circuits()] ) @action() def geometry(self): point = loads(self.meter.geometry) return Response( content_type='application/json', body=simplejson.dumps( {'type': 'FeatureCollection', 'features': [{ 'type':'Feature', 'geometry': {'type': 'Point', 'coordinates': list(point.coords)[0]}, 'properties': {} }]})) @action(renderer='meter/grid_graph.mako') def grid_graph(self): return {'meter': self.meter} @action(request_method='POST', permission="admin") def add_circuit(self): """A view that allows users to add an circuit to an """ params = self.request.params pin = params.get("pin") if len(pin) == 0: pin = Circuit.get_pin() account = Account( lang=params.get("lang"), phone=params.get("phone")) circuit = Circuit(meter=self.meter, account=account, ip_address=params.get("ip_address"), energy_max=int(params.get("energy_max")), power_max=int(params.get("power_max"))) self.session.add(account) self.session.add(circuit) self.session.flush() return Response(simplejson.dumps(circuit.id)) @action(permission="admin") def remove(self): """Allows users to remove an meter. """ [self.session.delete(c) for c in self.session.query(Circuit).filter_by(meter=self.meter)] self.session.delete(self.meter) return HTTPFound(location="/manage/show_meters") @action(permission="admin") def ping(self): job = Mping(self.meter) self.session.add(job) self.session.flush() interface = self.meter.communication_interface interface.sendJob(job) return HTTPFound(location=self.meter.getUrl())
class CircuitHandler(object): """ Circuit handler. Has all of the most important urls for managing circuits """ def __init__(self, request): self.session = DBSession() self.request = request self.circuit = self.session.\ query(Circuit).get(self.request.matchdict["id"]) self.meter = self.circuit.meter self.breadcrumbs = breadcrumbs[:] @action(renderer="circuit/index.mako", permission="admin") def index(self): breadcrumbs = self.breadcrumbs[:] breadcrumbs.extend([ {"text": "Meter Overview", "url": self.meter.getUrl()}, {"text": "Circuit Overview"}]) return { "logged_in": authenticated_userid(self.request), "breadcrumbs": breadcrumbs, "jobs": self.circuit.get_jobs(), "fields": get_fields(self.circuit), "circuit": self.circuit } @action(renderer="circuit/edit.mako", permission="admin") def edit(self): breadcrumbs = self.breadcrumbs breadcrumbs.extend([ {"text": "Meter Overview", "url": self.meter.getUrl()}, {"text": "Circuit Overview", "url": self.circuit.url()}, {"text": "Circuit Edit"}]) return { "logged_in": authenticated_userid(self.request), "breadcrumbs": breadcrumbs, "fields": get_fields(self.circuit), "circuit": self.circuit } @action(permission="admin") def update(self): circuit = model_from_request( self.request, self.circuit) self.session.merge(circuit) return HTTPFound( location="%s%s" % (self.request.application_url, self.circuit.getUrl())) @action(permission="admin") def turn_off(self): self.circuit.turnOff() return HTTPFound(location=self.circuit.getUrl()) @action(permission="admin") def turn_on(self): self.circuit.turnOn() return HTTPFound(location=self.circuit.getUrl()) @action(permission="admin") def ping(self): self.circuit.ping() return HTTPFound(location=self.circuit.getUrl()) @action(permission="admin") def remove_jobs(self): [self.session.delete(job) for job in self.circuit.get_jobs()] return HTTPFound( location="%s%s" % (self.request.application_url, self.circuit.getUrl())) @action(renderer="circuit/build_graph.mako", permission="admin") def build_graph(self): return { "logged_in": authenticated_userid(self.request), "circuit": self.circuit } @action(renderer="circuit/show_graph.mako", permission="admin") def show_graph(self): query = self.session.query(PrimaryLog) params = self.request.params # parse the date from the request origin = parser.parse(params["from"]) to = parser.parse(params["to"]) yaxis = params["yaxis"] logs = [x for x in query.all() if x.created > origin] logs = [x for x in logs if x.created < to] return { "logged_in": authenticated_userid(self.request), "data": [{"time": str(x.created.ctime()), "value": x.get_property(yaxis)} for x in logs ], "y_units": simplejson.dumps(params["yaxis"]), "origin": simplejson.dumps(params["from"]), "to": simplejson.dumps(params["to"])} @action() def jobs(self): return Response([x.toJSON() for x in self.circuit.get_jobs()]) @action(permission="admin") def add_credit(self): interface = self.circuit.meter.communication_interface job = AddCredit(circuit=self.circuit, credit=self.request.params.get("amount")) self.session.add(job) self.session.flush() interface.sendJob(job) return HTTPFound(location=self.circuit.getUrl()) @action(permission="admin") def remove(self): self.session.delete(self.circuit) return HTTPFound(location=self.meter.getUrl())
class MeterHandler(object): """ Meter handler, allows for user to edit and manage meters """ def __init__(self, request): self.request = request self.session = DBSession() self.meter = self.session.query(Meter).\ filter_by(slug=self.request.matchdict['slug']).one() self.breadcrumbs = breadcrumbs[:] @action(renderer="meter/index.mako", permission="admin") def index(self): breadcrumbs = self.breadcrumbs[:] breadcrumbs.append({"text": "Meter Overview"}) circuit_data = make_table_data(self.meter.get_circuits()) return { "logged_in": authenticated_userid(self.request), "meter": self.meter, "circuit_header": make_table_header(Circuit), "circuit_data": circuit_data, "fields": get_fields(self.meter), "breadcrumbs": breadcrumbs } @action(request_method='POST', permission="admin") def add_circuit(self): params = self.request.params pin = params.get("pin") if len(pin) == 0: pin = Circuit.get_pin() account = Account( lang=params.get("lang"), phone=params.get("phone")) circuit = Circuit(meter=self.meter, account=account, pin=pin, ip_address=params.get("ip_address"), energy_max=int(params.get("energy_max")), power_max=int(params.get("power_max"))) self.session.add(account) self.session.add(circuit) self.session.flush() return HTTPFound(location="%s%s" % ( self.request.application_url, self.meter.getUrl())) @action(renderer="meter/edit.mako", permission="admin") def edit(self): return { "fields": get_fields(self.meter), "meter": self.meter } @action(renderer="meter/build_graph.mako", permission="admin") def build_graph(self): return { "logged_in": authenticated_userid(self.request), "meter": self.meter } @action(renderer="meter/show_graph.mako", permission="admin") def show_graph(self): #needs to be implemented return {} @action(permission="admin") def logs(self): days = int(self.request.params.get('days', 10)) date = datetime.now() logs = find_meter_logs(meter=self.meter, date=date, session=self.session, days=days) return Response( simplejson.dumps(logs), content_type='application/json') @action(permission="admin") def update(self): meter = model_from_request(self.request, self.meter) self.session.merge(meter) return HTTPFound( location="%s%s" % (self.request.application_url, self.meter.getUrl())) @action(permission="admin") def remove(self): self.session.delete(self.meter) [self.session.delete(x) for x in self.session.query(Circuit).filter_by(meter=self.meter)] return HTTPFound(location="/") @action(permission="admin") def ping(self): job = Mping(self.meter) self.session.add(job) self.session.flush() msgClass = self.meter.getMessageType(job=True) self.session.add(msgClass(job, self.meter.phone, incoming="")) return HTTPFound(location=self.meter.getUrl())