diff --git a/minigrid/device_interface.py b/minigrid/device_interface.py index 8358845..0173d24 100644 --- a/minigrid/device_interface.py +++ b/minigrid/device_interface.py @@ -27,8 +27,10 @@ def write_vendor_card(session, cache, key, minigrid_id, payment_id, vendor): b'\x08', # Offset b'\x00\x14', # Length int(time.time()).to_bytes(4, 'big'), # card produced time - bytes(4), # card read time TODO + bytes(4), # card read time, set as zeros uuid.UUID(payment_id).bytes, + b'\x00', # Application Flag, has the card been used? Initially no + bytes(12), )) sector_2_content = b''.join(( vendor.vendor_user_id.encode('ascii'), # 0000-9999 ASCII @@ -48,16 +50,15 @@ def write_vendor_card(session, cache, key, minigrid_id, payment_id, vendor): (sum(naive_payload[:15]) & 0xFF).to_bytes(1, 'big'), naive_payload[15:30], (sum(naive_payload[15:30]) & 0xFF).to_bytes(1, 'big'), - naive_payload[30:32], + naive_payload[30:45], + (sum(naive_payload[30:45]) & 0xFF).to_bytes(1, 'big'), + naive_payload[45:60], + (sum(naive_payload[45:60]) & 0xFF).to_bytes(1, 'big'), + naive_payload[60:75], + (sum(naive_payload[60:75]) & 0xFF).to_bytes(1, 'big'), + naive_payload[75:77], bytes(13), - (sum(naive_payload[30:32]) & 0xFF).to_bytes(1, 'big'), - naive_payload[32:47], - (sum(naive_payload[32:47]) & 0xFF).to_bytes(1, 'big'), - naive_payload[47:62], - (sum(naive_payload[47:62]) & 0xFF).to_bytes(1, 'big'), - naive_payload[62:64], - bytes(13), - (sum(naive_payload[62:64]) & 0xFF).to_bytes(1, 'big'), + (sum(naive_payload[75:77]) & 0xFF).to_bytes(1, 'big'), )) cache.set('device_info', _wrap_binary(actual_payload), 5) with models.transaction(session) as tx_session: @@ -78,13 +79,17 @@ def write_customer_card( b'\x08', # Offset b'\x00\x14', # Length int(time.time()).to_bytes(4, 'big'), # card produced time - bytes(4), # card read time TODO + bytes(4), # card read time, set as zeros uuid.UUID(payment_id).bytes, + b'\x00', # Application Flag, has the card been used? Initially no + bytes(12), )) sector_2_content = b''.join(( customer.customer_user_id.encode('ascii'), # 0000-9999 ASCII uuid.UUID(minigrid_id).bytes, - bytes(11), + int(customer.customer_current_limit).to_bytes(4, 'big'), # Current Limit mA + int(customer.customer_energy_limit).to_bytes(4, 'big'), # Energy Limit Wh + bytes(3), )) sector_2 = b''.join(( sector_2_content, @@ -99,16 +104,15 @@ def write_customer_card( (sum(naive_payload[:15]) & 0xFF).to_bytes(1, 'big'), naive_payload[15:30], (sum(naive_payload[15:30]) & 0xFF).to_bytes(1, 'big'), - naive_payload[30:32], - bytes(13), - (sum(naive_payload[30:32]) & 0xFF).to_bytes(1, 'big'), - naive_payload[32:47], - (sum(naive_payload[32:47]) & 0xFF).to_bytes(1, 'big'), - naive_payload[47:62], - (sum(naive_payload[47:62]) & 0xFF).to_bytes(1, 'big'), - naive_payload[62:64], + naive_payload[30:45], + (sum(naive_payload[30:45]) & 0xFF).to_bytes(1, 'big'), + naive_payload[45:60], + (sum(naive_payload[45:60]) & 0xFF).to_bytes(1, 'big'), + naive_payload[60:75], + (sum(naive_payload[60:75]) & 0xFF).to_bytes(1, 'big'), + naive_payload[75:77], bytes(13), - (sum(naive_payload[62:64]) & 0xFF).to_bytes(1, 'big'), + (sum(naive_payload[75:77]) & 0xFF).to_bytes(1, 'big'), )) cache.set('device_info', _wrap_binary(actual_payload), 5) with models.transaction(session) as tx_session: @@ -129,8 +133,10 @@ def write_maintenance_card_card( b'\x08', # Offset b'\x00\xd0', # Length int(time.time()).to_bytes(4, 'big'), # card produced time - bytes(4), # card read time TODO + bytes(4), # card read time, set as zeros uuid.UUID(payment_id).bytes, + b'\x00', # Application Flag, has the card been used? + bytes(12), )) mc_id = maintenance_card.maintenance_card_card_id.encode('ascii') sector_2_content = b''.join(( @@ -151,16 +157,15 @@ def write_maintenance_card_card( (sum(naive_payload[:15]) & 0xFF).to_bytes(1, 'big'), naive_payload[15:30], (sum(naive_payload[15:30]) & 0xFF).to_bytes(1, 'big'), - naive_payload[30:32], + naive_payload[30:45], + (sum(naive_payload[30:45]) & 0xFF).to_bytes(1, 'big'), + naive_payload[45:60], + (sum(naive_payload[45:60]) & 0xFF).to_bytes(1, 'big'), + naive_payload[60:75], + (sum(naive_payload[60:75]) & 0xFF).to_bytes(1, 'big'), + naive_payload[75:77], bytes(13), - (sum(naive_payload[30:32]) & 0xFF).to_bytes(1, 'big'), - naive_payload[32:47], - (sum(naive_payload[32:47]) & 0xFF).to_bytes(1, 'big'), - naive_payload[47:62], - (sum(naive_payload[47:62]) & 0xFF).to_bytes(1, 'big'), - naive_payload[62:64], - bytes(13), - (sum(naive_payload[62:64]) & 0xFF).to_bytes(1, 'big'), + (sum(naive_payload[75:77]) & 0xFF).to_bytes(1, 'big'), )) cache.set('device_info', _wrap_binary(actual_payload), 5) mmcci = maintenance_card.maintenance_card_card_id @@ -193,8 +198,10 @@ def write_credit_card( b'\x08', # Offset b'\x00\xf4', # Length b'\x00\x00\x00\x00', # old card produce time section - bytes(4), # card read time TODO + bytes(4), # card read time, set as zeros uuid.UUID(payment_id).bytes, + b'\x00', # Application Flag, has the card been used? + bytes(12), )) credit_card_id = uuid.uuid4() sector_2_content = b''.join(( @@ -231,23 +238,22 @@ def write_credit_card( (sum(naive_payload[:15]) & 0xFF).to_bytes(1, 'big'), naive_payload[15:30], (sum(naive_payload[15:30]) & 0xFF).to_bytes(1, 'big'), - naive_payload[30:32], - bytes(13), - (sum(naive_payload[30:32]) & 0xFF).to_bytes(1, 'big'), - naive_payload[32:47], - (sum(naive_payload[32:47]) & 0xFF).to_bytes(1, 'big'), - naive_payload[47:62], - (sum(naive_payload[47:62]) & 0xFF).to_bytes(1, 'big'), - naive_payload[62:64], + naive_payload[30:45], + (sum(naive_payload[30:45]) & 0xFF).to_bytes(1, 'big'), + naive_payload[45:60], + (sum(naive_payload[45:60]) & 0xFF).to_bytes(1, 'big'), + naive_payload[60:75], + (sum(naive_payload[60:75]) & 0xFF).to_bytes(1, 'big'), + naive_payload[75:77], bytes(13), - (sum(naive_payload[62:64]) & 0xFF).to_bytes(1, 'big'), - naive_payload[64:79], - (sum(naive_payload[64:79]) & 0xFF).to_bytes(1, 'big'), - naive_payload[79:94], - (sum(naive_payload[79:94]) & 0xFF).to_bytes(1, 'big'), - naive_payload[94:96], + (sum(naive_payload[75:77]) & 0xFF).to_bytes(1, 'big'), + naive_payload[77:92], + (sum(naive_payload[77:92]) & 0xFF).to_bytes(1, 'big'), + naive_payload[92:107], + (sum(naive_payload[92:107]) & 0xFF).to_bytes(1, 'big'), + naive_payload[107:109], bytes(13), - (sum(naive_payload[94:96]) & 0xFF).to_bytes(1, 'big'), + (sum(naive_payload[107:109]) & 0xFF).to_bytes(1, 'big'), )) cache.set('device_info', _wrap_binary(actual_payload), 5) data = { diff --git a/minigrid/handlers.py b/minigrid/handlers.py index 28cff16..59bbff1 100644 --- a/minigrid/handlers.py +++ b/minigrid/handlers.py @@ -448,7 +448,9 @@ def post(self, minigrid_id): with models.transaction(self.session) as session: grid.customers.append(models.Customer( customer_user_id=self.get_argument('customer_user_id'), - customer_name=self.get_argument('customer_name'))) + customer_name=self.get_argument('customer_name'), + customer_current_limit=self.get_argument('customer_current_limit'), + customer_energy_limit=self.get_argument('customer_energy_limit'))) except (IntegrityError, DataError) as error: if 'customer_name_key' in error.orig.pgerror: message = 'A customer with that name already exists' @@ -768,6 +770,9 @@ def _pack_into_dict(session, binary): else: secret_value = raw_secret_value.decode('ascii') result[_secret_value_type[card_type]] = secret_value + if card_type == 'B': + result['Current Limit (mA)'] = int.from_bytes(sector_2[20:24], 'big') + result['Energy Limit (Wh)'] = int.from_bytes(sector_2[24:28], 'big') if card_type in {'A', 'B', 'D'}: result['Minigrid ID'] = str(UUID(bytes=sector_2[4:20])) specific_data = _user_or_maintenance_card(binary) @@ -777,6 +782,13 @@ def _pack_into_dict(session, binary): specific_data = _credit_card(session, cipher, binary, cc_id) else: raise tornado.web.HTTPError(400, f'bad card type {card_type}') + if card_type == 'C': + application_flag = sector_1[32:33].hex() + logging.info(f'Application Flag: {application_flag}') + if application_flag == '00': + result['Credit Status'] = 'Unused' + elif application_flag == '01': + result['Credit Status'] = 'Previously Used' result.update(specific_data) return json_encode(result) diff --git a/minigrid/models.py b/minigrid/models.py index 1058401..1d710e6 100644 --- a/minigrid/models.py +++ b/minigrid/models.py @@ -315,6 +315,14 @@ class Customer(Base): customer_user_id = sa.Column( pg.TEXT, sa.CheckConstraint("customer_user_id ~ '\d{4}'"), nullable=False) + customer_current_limit = sa.Column( + pg.TEXT, + sa.CheckConstraint("customer_current_limit >= 0"), + nullable=False) + customer_energy_limit = sa.Column( + pg.TEXT, + sa.CheckConstraint("customer_energy_limit >= 0"), + nullable=False) __table_args__ = ( sa.UniqueConstraint('customer_minigrid_id', 'customer_user_id'), diff --git a/minigrid/templates/minigrid_customers.html b/minigrid/templates/minigrid_customers.html index f932c30..e9e4861 100644 --- a/minigrid/templates/minigrid_customers.html +++ b/minigrid/templates/minigrid_customers.html @@ -20,6 +20,8 @@

Minigrid Name: {{ minigrid.minigrid_name }}

  • Name: {{ customer.customer_name }}

    User ID: {{ customer.customer_user_id }}

    +

    Current Limit (mA): {{ customer.customer_current_limit }}

    +

    Energy Limit (Wh): {{ customer.customer_energy_limit }}

    {% module xsrf_form_html() %} @@ -49,6 +51,8 @@

    Minigrid Name: {{ minigrid.minigrid_name }}

    {% module xsrf_form_html() %}

    +
    +

    diff --git a/prod/docker-compose.yml b/prod/docker-compose.yml index 21f657c..a3c0096 100644 --- a/prod/docker-compose.yml +++ b/prod/docker-compose.yml @@ -1,7 +1,7 @@ version: '2' services: minigrid: - image: selcolumbia/minigrid-server:0.2.3 + image: selcolumbia/minigrid-server:0.2.4 command: ./prod/run.sh --db_host=db --redis_url=redis://redis:6379/0 --minigrid-website-url=https://www.example.com depends_on: - redis diff --git a/prod/install.sh b/prod/install.sh index 85a4333..f415ae0 100755 --- a/prod/install.sh +++ b/prod/install.sh @@ -1,5 +1,5 @@ #!/usr/bin/env sh -# Minigrid Server installer for version 0.2.3 +# Minigrid Server installer for version 0.2.4 set -e # Do you have docker installed? @@ -108,8 +108,8 @@ $SUDO openssl dhparam -out /etc/letsencrypt/live/$LETSENCRYPT_DIR/dhparam.pem 20 printf "========================================\n" printf " Generating configuration \n" printf "========================================\n" -$CURL -L https://raw.githubusercontent.com/SEL-Columbia/minigrid-server/0.2.3/prod/docker-compose.yml > docker-compose.yml -$CURL -L https://raw.githubusercontent.com/SEL-Columbia/minigrid-server/0.2.3/prod/nginx.conf > nginx.conf +$CURL -L https://raw.githubusercontent.com/SEL-Columbia/minigrid-server/0.2.4/prod/docker-compose.yml > docker-compose.yml +$CURL -L https://raw.githubusercontent.com/SEL-Columbia/minigrid-server/0.2.4/prod/nginx.conf > nginx.conf sed -i s/www.example.com/$LETSENCRYPT_DIR/g docker-compose.yml sed -i s/www.example.com/$LETSENCRYPT_DIR/g nginx.conf @@ -148,7 +148,7 @@ printf "========================================\n" # the container can't run the docker command properly. # So /tmp/renewed serves as a sentinel CRON_CMD="mkdir -p /tmp/letsencrypt && "\ -"docker run -it --rm --name certbot"\ +"docker run -i --rm --name certbot"\ " -v /etc/letsencrypt:/etc/letsencrypt:Z"\ " -v /var/lib/letsencrypt:/var/lib/letsencrypt:Z"\ " -v /tmp:/tmp:Z"\