Source code for wscodec.encoder.pyencoder.eeprom

#  cuplcodec encodes environmental sensor data into a URL and the reverse.
#
#  https://github.com/cuplsensor/cuplcodec
#
#  Original Author: Malcolm Mackay
#  Email: malcolm@plotsensor.com
#  Website: https://cupl.co.uk
#
#  Copyright (C) 2021. Plotsensor Ltd.
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
#

import ndef
import urllib.parse as urlparse
from ctypes import c_char_p


[docs]class Eeprom(): """ A mock of the NT3H2111 EEPROM, based on a bytearray. There are methods to read and write from this in 16-byte blocks. Helper methods parse the entire EEPROM contents as an NDEF message. This mimics what a phone will do when it reads the NT3H2111 using NFC. The EEPROM will normally contain the output of the cupl Encoder: an NDEF message containing one NDEF record. This itself will contain a URL. One of the parameters in the query string is 'q', which contains the circular buffer of temperature and relative humidity samples. """ def __init__(self, sizeblocks: int): """ Instatiate a mock EEPROM. :param sizeblocks: Size of the EEPROM in 16-byte blocks. """ self.eepromba = bytearray(sizeblocks*16) self.sizeblocks = sizeblocks
[docs] def write_block(self, block: int, blkdata: c_char_p): """ Write one block from a pointer. :param block: Address of the block to write :param blkdata: Pointer to an array of 16 bytes that will be written to the block. :return: None """ blkstartbyte = block*16 for i in range(0,16): self.eepromba[blkstartbyte + i] = int.from_bytes(blkdata[i], byteorder="little")
[docs] def read_block(self, block: int, blkdata: c_char_p): """ Read one block into a pointer. :param block: Address if the block to read. :param blkdata: Pointer to an array of 16 bytes that the block will be read into. :return: None """ blkstartbyte = block*16 for i in range(0,16): blkdata[i] = bytes(self.eepromba[blkstartbyte+i:blkstartbyte+i+1]) return 0
[docs] def display_block(self, block: int) -> bytearray: """ Display one EEPROM block. :param block: Address of the block to display. :return: Block data as a list of 16 bytes. """ blkstartbyte = block*16 blkendbyte = blkstartbyte + 16 return self.eepromba[blkstartbyte:blkendbyte]
def __repr__(self) -> str: """ Display all EEPROM blocks. :return: The contents of all EEPROM blocks as a string. """ retstr = "EEPROM with " + str(self.sizeblocks) + " blocks\n" for block in range(0, self.sizeblocks): retstr += "EEPROM block " + str(block) + "\n" blkstartbyte = block*16 blkendbyte = blkstartbyte + 16 retstr += str(self.eepromba[blkstartbyte:blkendbyte]) + "\n" return retstr
[docs] def get_message(self) -> bytearray: """ Extract the NDEF message bytes from EEPROM. :return: NDEF message bytearray """ ndefmsgstartbyte = 16 + 4 return self.eepromba[ndefmsgstartbyte:]
[docs] def decode_ndef(self) -> ndef.Record: """ Decode the NDEF message. :return: First NDEF record in the message """ sizedemis = self.sizeblocks * 2 ndefmessage = self.get_message() # Copy NDEF message into a bytearray ndefdemis = bytearray() for i in range(0,sizedemis): startbyte = i*8 endbyte = startbyte + 8 demi = ndefmessage[startbyte:endbyte] ndefdemis += demi # Decode the bytearray. ndefrecords = ndef.message_decoder(ndefdemis) # Use next to generate the first record from the ndefrecords generator return next(ndefrecords)
[docs] def get_url(self) -> str: """ Obtain URL from the NDEF record stored in EEPROM. :return: URL string """ ndefmessage = self.decode_ndef() return ndefmessage.iri
[docs] def get_url_parsed(self) -> urlparse.ParseResult: """ Parse URL in the EEPROM NDEF record. :return: Parsed URL """ url = self.get_url() return urlparse.urlparse(url)
[docs] def get_url_parsedqs(self) -> dict: """ Parse parameters in the `query string <https://en.wikipedia.org/wiki/Query_string>`_ :return: A dictionary of URL parameters. """ parsedurl = self.get_url_parsed() urlquery = parsedurl.query return urlparse.parse_qs(urlquery)
[docs] def get_qparam(self) -> str: """ :return: The value of URL parameter 'q' as a string. """ parsedqs = self.get_url_parsedqs() q = parsedqs['q'] return q[0]
[docs] def get_qdemis(self) -> list: """ :return: The value of URL parameter 'q' as a list of 8-byte demis. """ qstr = self.get_qparam() n = 8 qdemis = [qstr[i:i+n] for i in range(0, len(qstr), n)] return qdemis