Пример #1
0
 def update_tokens(self):
     """
     We need to record these updates to token states and provide a
     way to view this in the Gateway Interface.
     """
     session = DBSession()
     data = simplejson.loads(self.request.body)
     if not 'device_id' in data:
         return json_response('You must provide an device_id')
     device = session.query(Device)\
         .filter_by(device_id=data['device_id']).first()
     if device:
         for i in data['tokens']:
             token = session.query(Token)\
                 .filter_by(token=i['token_id']).first()
             if token:
                 circuit = session.query(Circuit)\
                     .filter_by(pin=i['account_id']).first()
                 if circuit:
                     job = AddCredit(token.value, circuit, token)
                     session.add(job)
                 token.state = 'used'
                 session.merge(token)
         session.flush()
         return json_response('ok')
     else:
         return json_response('You must provide a valid device_id')
Пример #2
0
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))
Пример #3
0
 def login(self):
     session = DBSession()
     came_from = self.request.params.get('came_from', '/')
     message = ''
     login = ''
     password = ''
     if 'form.submitted' in self.request.params:
         name = self.request.params['name']
         hash = hashlib.md5(self.request.params['password']).hexdigest()
         user = session.query(Users)\
             .filter_by(name=name)\
             .filter_by(password=unicode(hash)).first()
         if user:
             print(name, hash)
             headers = remember(self.request, user.name)
             return HTTPFound(
                 location="%s" % came_from,
                 headers=headers)
         message = 'Failed login'
     return {
         'message': message,
         'url': self.request.application_url + '/login',
         'came_from': came_from,
         'login': login,
         'password': password}
Пример #4
0
 def make_tokens(self):
     session = DBSession()
     batch = TokenBatch()
     session.add(batch)
     session.flush()
     data = simplejson.loads(self.request.body)
     if not 'device_id' in data:
         return Response('You must provide an device_id')
     else:
         device = session.query(Device)\
             .filter_by(device_id=data['device_id']).first()
         if device:
             if not 'tokens' in data:
                 return Response('You must provide an amount of tokens')
             for group in data['tokens']:
                 for i in range(0, group['count']):
                     token = Token(Token.get_random(),
                                   batch=batch,
                                   value=group['denomination'])
                     session.add(token)
                     session.flush()
             return json_response(
                 [{'token_id': int(token.token),
                   'denomination':
                   float(token.value)} for token in batch.getTokens()])
         else:
             return json_response('Not a valid device')
Пример #5
0
 def send(self):
     session = DBSession()
     twilio = session.query(TwilioInterface).first()
     msg = save_and_parse_message(twilio,
                                  self.request.params['From'],
                                  self.request.params['Body'],
                                  id=self.request.params['SmsMessageSid'])
     return Response(msg.uuid)
Пример #6
0
def groupfinder(userid, request):
    """
    Rough cut of user admin system.
    """
    session = DBSession()
    user = session.query(Users).filter_by(name=userid).first()
    if user:
        if user.group:
            return [user.group.name]
Пример #7
0
def findMeter(message):
    """
    Takes a message object and returns either a meter or none.
    Looks up the meter based on the message's number.
    """
    session = DBSession()
    meter = session.query(Meter).filter_by(phone=str(message.number)).first()
    if meter:
        return meter
Пример #8
0
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))
Пример #9
0
 def add_meter(self):
     session = DBSession()
     if self.request.method == 'GET':
         comms = session.query(CommunicationInterface).all()
         return {'comms': comms,
                 'breadcrumbs': self.breadcrumbs
                 }
     elif self.request.method == 'POST':
         comm = session.query(CommunicationInterface)\
             .get(int(self.request.params.get('communication-interface')))
         meter_name = self.request.params.get('meter-name')
         meter_phone = self.request.params.get('meter-phone')
         meter_location = self.request.params.get('meter-location')
         batter_capacity = self.request.params.get('battery-capacity')
         panel_capacity = self.request.params.get('panel-capacity')
         meter = Meter(name=meter_name,
                       phone=meter_phone,
                       location=meter_location,
                       geometry='POINT(1 1)',
                       battery=batter_capacity,
                       status=True,
                       panel_capacity=panel_capacity,
                       communication_interface_id=comm.id)
         # save the meter
         session.add(meter)
         session.flush()
         # start at mains as every meter needs a mains
         start_ip_address = 200
         for x in range(0, int(self.request.params.get('number-of-circuits'))):
             ip_address = '192.168.1.%s' % (start_ip_address + x)
             # create an account for each circuit
             account = Account(lang=self.request.params.get('default-language'))
             session.add(account)
             session.flush()
             # create the circuit
             circuit = Circuit(
                 meter=meter,
                 account=account,
                 ip_address=ip_address,
                 power_max=self.request.params.get('power-emax'),
                 energy_max=self.request.params.get('default-emax'))
             session.add(circuit)
             session.flush()
         return HTTPFound(location='/manage/show_meters')
Пример #10
0
 def job(self):
     session = DBSession()
     job = session.query(Job).get(self.request.matchdict["id"])
     if self.request.method == "DELETE":
         job.state = False
         job.end = datetime.now()
         session.merge(job)
         return Response(str(job))
     else:
         return Response(simplejson.dumps(job.toDict()))
Пример #11
0
class FunctionalTests(unittest.TestCase):
    """ Unit tests for the Gateway UI """
    def setUp(self):
        self.config = testing.setUp()
        import ConfigParser
        from gateway.models import DBSession
        from gateway.models import initialize_sql
        config = ConfigParser.ConfigParser()
        config.readfp(open('testing.ini'))
        db_string = config.get('app:gateway', 'db_string')
        initialize_sql(db_string)
        from gateway import main
        from webtest import TestApp
        app = main(None, **{'db_string': db_string,
                            'mako.directories': config.get('app:gateway', 'mako.directories')})
        self.testapp = TestApp(app)
        self.session = DBSession()

    def tearDown(self):
        testing.tearDown()

    def test_number_of_meter(self):
        from gateway.models import Meter
        meters = self.session.query(Meter).all()
        self.assertEquals(len(meters), 1)

    def test_index(self):
        res = self.testapp.get('/', status=200)
        self.assertEquals(res.status, '200 ok')

    def test_number_of_circuits(self):
        from gateway.models import Circuit
        circuits = self.session.query(Circuit).all()
        self.assertEquals(len(circuits), 11)

    def test_number_of_comm_interfaces(self):
        from gateway.models import CommunicationInterface
        interfaces = self.session.query(CommunicationInterface).all()
        self.assertEquals(len(interfaces), 1)

    def test_balance_english(self):
        from gateway.models import CommunicationInterface
        from gateway.models import Circuit
Пример #12
0
def findCircuit(message, meter):
    """Looks up circuit from meter and message.
    """
    session = DBSession()
    try:
        circuit = session.query(Circuit).\
            filter_by(ip_address=message["cid"]).\
            filter_by(meter=meter).first()
        if circuit:
            return circuit
    except Exception as e:
        print e, message
Пример #13
0
def get_token(message):
    """Tries to match message to token."""
    session = DBSession()
    tokenNumber = message.text.split(delimiter)[2]
    token = session.query(Token).filter_by(state="new").filter_by(token=tokenNumber).first()
    if token:
        return token
    else:
        interface = message.communication_interface
        interface.sendMessage(
            message.number, make_message_body("no-token.txt", lang=message.langauge), incoming=message.uuid
        )
        return False
Пример #14
0
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)
Пример #15
0
 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])
Пример #16
0
 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)})
Пример #17
0
 def metersAsGeoJson(self):
     session = DBSession()
     meters = session.query(Meter).filter(Meter.geometry != None)
     return Response(
         content_type='application/json',
         body=simplejson.dumps(
             {'type': 'FeatureCollection',
              'features':
                  [{'type': 'Feature',
                     'properties': {'name': x.name},
                     'geometry': {'type': 'Point',
                                  'coordinates': list(loads(
                                     x.geometry).coords)[0]}}
                for x in meters]
              }))
Пример #18
0
def get_circuit(message):
    """Queris the database to find circuit
    Returns the circuit or false
    """
    session = DBSession()
    pin = message.text.split(delimiter)[1].lower()
    circuit = session.query(Circuit).filter_by(pin=pin).first()
    if circuit:
        return circuit
    else:
        interface = message.communication_interface
        interface.sendMessage(
            message.number,
            make_message_body("no-circuit.txt", lang=interface.lang, pin=pin),
            incoming=message.uuid)
Пример #19
0
 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]})
Пример #20
0
 def show_meters_json(self):
     session = DBSession()
     return json_response(
         [
             {'name': m.name,
              'id': m.id,
              'number_of_circuits': len(m.get_circuits()),
              'uptime': find_meter_uptime(m),
              'pv': m.panel_capacity,
              'last_message': find_last_message_by_meter(m),
              'phone': m.phone,
              'battery': m.battery,
              'location': m.location
              } for m in session.query(Meter).all()
             ]
         )
Пример #21
0
def find_meter_uptime(meter):
    """
    cs = # of circuits
    actual = number messages it did receive
    possible = Number of messages it should have receive in the last week
    -> 48 * cs * 7
    (* (/ actual possible) 100)
    """
    now = datetime.now()
    last_week = now - timedelta(days=7)
    session = DBSession()
    log_count = session.query(PrimaryLog)\
        .filter_by(circuit=meter.getMainCircuit())\
        .filter(PrimaryLog.date < now)\
        .filter(PrimaryLog.date > last_week).count()
    return int((log_count / (24 * 7.0)) * 100)
Пример #22
0
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)
Пример #23
0
 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}
Пример #24
0
def make_columns(cls):
    """
    Function to look up and convert a SQL types to a colander type
    Requires a Class the inherents from Base
    """
    session = DBSession()
    data = cls.__mapper__.columns._data
    columns = {}
    for key in data.keys():
        column = data[key]
        if len(column.foreign_keys) == 0:
            columns[key] = matching.get(
                str(column.type),
                String)
        elif len(column.foreign_keys) == 1:
            foregin = column.foreign_keys[0]
            table = foregin.column.table
            choices = session.query(table).all()
            columns[key] = [table, choices]
    return columns
Пример #25
0
    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 }
          )
Пример #26
0
 def add(self):
     errors = None
     session = DBSession()
     groups = session.query(Groups).all()
     breadcrumbs = self.breadcrumbs[:]
     breadcrumbs.append({'text': 'Add a new user'})
     if self.request.method == 'GET':
         return {'breadcrumbs': breadcrumbs,
                 'groups': groups,
                 'errors': errors}
     elif self.request.method == 'POST':
         name = self.request.params['name']
         email = self.request.params['email']
         password = self.request.params['password']
         group = self.request.params['group']
         user = Users(name=name, email=email,
                      group_id=group,
                      password=password)
         session.add(user)
         session.flush()
         return HTTPFound(location='/')
Пример #27
0
    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
Пример #28
0
class AlertHandler(object):
    """
    This handler allows admin to send test messages.
    Will be expaned to include more types of alerts.
    """
    def __init__(self, request):
        self.request = request
        self.session = DBSession()
        self.breadcrumbs = breadcrumbs[:]

    @action()
    def all(self):
        session = DBSession()
        return json_response([a.toJSON() for a in session.query(Alert).order_by(Alert.id.desc()).all()])

    @action(renderer='alerts/make.mako', permission='admin')
    def make(self):
        breadcrumbs = self.breadcrumbs[:]
        breadcrumbs.append({'text': 'Send Alerts'})
        return {
            'breadcrumbs': breadcrumbs,
            'interfaces': self.session.query(CommunicationInterface).all()}

    @action(permission='admin')
    def send_test(self):
        """
        Method to send a test message via a comm interface
        """
        interface = self.session\
                    .query(CommunicationInterface)\
                    .get(self.request.params['interface'])
        number = self.request.params['number']
        text = self.request.params['text']
        msg = interface.sendMessage(number, text)
        return HTTPFound(location="%s/message/index/%s" %
                         (self.request.application_url, msg.uuid))
Пример #29
0
class Dashboard(object):
    """
    Home page for the gateway
    """
    def __init__(self, request):
        self.request = request
        self.breadcrumbs = breadcrumbs[:]
        self.session = DBSession()

    @action(renderer='index.mako', permission='view')
    def index(self):

        logs = Grid(SystemLog,
                    self.session.query(SystemLog)\
                    .order_by(desc(SystemLog.created)).limit(10))
        logs.configure(readonly=True)
        return {
            'logs': logs,
            'breadcrumbs': self.breadcrumbs}

    @action(renderer="dashboard.mako", permission='view')
    def dashboard(self):
        return {
            "logged_in": authenticated_userid(self.request)}
Пример #30
0
import transaction
from shapely.geometry import Point
from gateway.models import DBSession
from gateway.models import Meter
from gateway.models import SystemLog
from gateway.models import initialize_sql

import csv

db_string = "postgresql://*****:*****@localhost:5432/gateway"
initialize_sql(db_string)
session = DBSession()


if __name__ == '__main__': 
    query = session.query(Meter)
    try:
        locations = csv.reader(open("locations.csv"))
        
        for line in locations: 
            with transaction:
                point = Point(float(line[2]), float(line[1]))
                print point.wkt
                meter = query.filter_by(name= line[0]).first()
                meter.geometry = point.wkt
                session.flush()

    except Exception as error:
        print error