Requirements

@startuml

' Nodes definition 

node "<size:12>Feature</size>\n**NDEF message**\n**type**\n<size:10>CODEC_FEAT_1</size>" as CODEC_FEAT_1 [[../docs/specification/features.html#CODEC_FEAT_1]] #DF744A 
node "<size:12>Feature</size>\n**NDEF message**\n**length**\n<size:10>CODEC_FEAT_2</size>" as CODEC_FEAT_2 [[../docs/specification/features.html#CODEC_FEAT_2]] #DF744A 
node "<size:12>Feature</size>\n**Payload length**\n<size:10>CODEC_FEAT_3</size>" as CODEC_FEAT_3 [[../docs/specification/features.html#CODEC_FEAT_3]] #DF744A 
node "<size:12>Feature</size>\n**Type length**\n<size:10>CODEC_FEAT_4</size>" as CODEC_FEAT_4 [[../docs/specification/features.html#CODEC_FEAT_4]] #DF744A 
node "<size:12>Feature</size>\n**Record type**\n<size:10>CODEC_FEAT_5</size>" as CODEC_FEAT_5 [[../docs/specification/features.html#CODEC_FEAT_5]] #DF744A 
node "<size:12>Feature</size>\n**Sample interval**\n**b64**\n<size:10>CODEC_FEAT_10</size>" as CODEC_FEAT_10 [[../docs/specification/features.html#CODEC_FEAT_10]] #DF744A 
node "<size:12>Feature</size>\n**Serial**\n<size:10>CODEC_FEAT_38</size>" as CODEC_FEAT_38 [[../docs/specification/features.html#CODEC_FEAT_38]] #DF744A 
node "<size:12>Feature</size>\n**CodecVersion**\n<size:10>CODEC_FEAT_41</size>" as CODEC_FEAT_41 [[../docs/specification/features.html#CODEC_FEAT_41]] #DF744A 
node "<size:12>Feature</size>\n**FormatCode**\n<size:10>CODEC_FEAT_42</size>" as CODEC_FEAT_42 [[../docs/specification/features.html#CODEC_FEAT_42]] #DF744A 
node "<size:12>Feature</size>\n**Error raised if**\n**versions**\n**mismatch**\n<size:10>CODEC_FEAT_43</size>" as CODEC_FEAT_43 [[../docs/specification/features.html#CODEC_FEAT_43]] #DF744A 
node "<size:12>Feature</size>\n**Protocol**\n<size:10>CODEC_FEAT_44</size>" as CODEC_FEAT_44 [[../docs/specification/features.html#CODEC_FEAT_44]] #DF744A 
node "<size:12>Feature</size>\n**LoopCount**\n<size:10>CODEC_FEAT_28</size>" as CODEC_FEAT_28 [[../docs/specification/features.html#CODEC_FEAT_28]] #DF744A 
node "<size:12>Feature</size>\n**ResetsAllTime**\n<size:10>CODEC_FEAT_29</size>" as CODEC_FEAT_29 [[../docs/specification/features.html#CODEC_FEAT_29]] #DF744A 
node "<size:12>Feature</size>\n**BatV**\n<size:10>CODEC_FEAT_30</size>" as CODEC_FEAT_30 [[../docs/specification/features.html#CODEC_FEAT_30]] #DF744A 
node "<size:12>Feature</size>\n**Error raised if**\n**hash check**\n**fails**\n<size:10>CODEC_FEAT_40</size>" as CODEC_FEAT_40 [[../docs/specification/features.html#CODEC_FEAT_40]] #DF744A 
node "<size:12>Feature</size>\n**Adjustable**\n**buffer length.**\n<size:10>CODEC_FEAT_23</size>" as CODEC_FEAT_23 [[../docs/specification/features.html#CODEC_FEAT_23]] #DF744A 
node "<size:12>Feature</size>\n**Hash**\n<size:10>CODEC_FEAT_24</size>" as CODEC_FEAT_24 [[../docs/specification/features.html#CODEC_FEAT_24]] #DF744A 
node "<size:12>Feature</size>\n**NPairs**\n<size:10>CODEC_FEAT_25</size>" as CODEC_FEAT_25 [[../docs/specification/features.html#CODEC_FEAT_25]] #DF744A 
node "<size:12>Feature</size>\n**Elapsed b64**\n<size:10>CODEC_FEAT_26</size>" as CODEC_FEAT_26 [[../docs/specification/features.html#CODEC_FEAT_26]] #DF744A 
node "<size:12>Feature</size>\n**No absolute**\n**timestamp**\n<size:10>CODEC_FEAT_27</size>" as CODEC_FEAT_27 [[../docs/specification/features.html#CODEC_FEAT_27]] #DF744A 
node "<size:12>Feature</size>\n**Samples**\n**timestamped by**\n**decoder**\n<size:10>CODEC_FEAT_6</size>" as CODEC_FEAT_6 [[../docs/specification/features.html#CODEC_FEAT_6]] #DF744A 
node "<size:12>Feature</size>\n**Base URL**\n<size:10>CODEC_FEAT_7</size>" as CODEC_FEAT_7 [[../docs/specification/features.html#CODEC_FEAT_7]] #DF744A 
node "<size:12>Feature</size>\n**Encoder writes**\n**to EEPROM**\n**blocks.**\n<size:10>CODEC_FEAT_13</size>" as CODEC_FEAT_13 [[../docs/specification/features.html#CODEC_FEAT_13]] #DF744A 
node "<size:12>Feature</size>\n**Only static**\n**memory**\n**allocation is**\n**used.**\n<size:10>CODEC_FEAT_8</size>" as CODEC_FEAT_8 [[../docs/specification/features.html#CODEC_FEAT_8]] #DF744A 
node "<size:12>Feature</size>\n**Encoder is**\n**written in C.**\n<size:10>CODEC_FEAT_9</size>" as CODEC_FEAT_9 [[../docs/specification/features.html#CODEC_FEAT_9]] #DF744A 
node "<size:12>Feature</size>\n**No RTOS is**\n**required**\n<size:10>CODEC_FEAT_14</size>" as CODEC_FEAT_14 [[../docs/specification/features.html#CODEC_FEAT_14]] #DF744A 
node "<size:12>Feature</size>\n**Status updates**\n**once per loop**\n<size:10>CODEC_FEAT_39</size>" as CODEC_FEAT_39 [[../docs/specification/features.html#CODEC_FEAT_39]] #DF744A 
node "<size:12>Feature</size>\n**Full message**\n**written on**\n**startup.**\n<size:10>CODEC_FEAT_12</size>" as CODEC_FEAT_12 [[../docs/specification/features.html#CODEC_FEAT_12]] #DF744A 
node "<size:12>Feature</size>\n**Append sample.**\n<size:10>CODEC_FEAT_15</size>" as CODEC_FEAT_15 [[../docs/specification/features.html#CODEC_FEAT_15]] #DF744A 
node "<size:12>Feature</size>\n**The encoder**\n**writes two**\n**circular buffer**\n**blocks at a**\n**time.**\n<size:10>CODEC_FEAT_16</size>" as CODEC_FEAT_16 [[../docs/specification/features.html#CODEC_FEAT_16]] #DF744A 
node "<size:12>Requirement</size>\n**Codec comprises**\n**an encoder and**\n**decoder.**\n<size:10>CODEC_REQ_3</size>" as CODEC_REQ_3 [[../docs/specification/requirements.html#CODEC_REQ_3]] #BFD8D2 
node "<size:12>Requirement</size>\n**Encoder writes**\n**a message**\n<size:10>CODEC_REQ_1</size>" as CODEC_REQ_1 [[../docs/specification/requirements.html#CODEC_REQ_1]] #BFD8D2 
node "<size:12>Requirement</size>\n**Encoder shall**\n**run on a low**\n**cost, low power**\n**microcontroller**\n<size:10>CODEC_REQ_12</size>" as CODEC_REQ_12 [[../docs/specification/requirements.html#CODEC_REQ_12]] #BFD8D2 
node "<size:12>Requirement</size>\n**No**\n**configuration**\n**from the user**\n<size:10>CODEC_REQ_7</size>" as CODEC_REQ_7 [[../docs/specification/requirements.html#CODEC_REQ_7]] #BFD8D2 
node "<size:12>Requirement</size>\n**Message is**\n**written to**\n**EEPROM**\n<size:10>CODEC_REQ_8</size>" as CODEC_REQ_8 [[../docs/specification/requirements.html#CODEC_REQ_8]] #BFD8D2 
node "<size:12>Requirement</size>\n**Decoder**\n**reproduces**\n**encoder data**\n<size:10>CODEC_REQ_2</size>" as CODEC_REQ_2 [[../docs/specification/requirements.html#CODEC_REQ_2]] #BFD8D2 
node "<size:12>Specification</size>\n**Message format**\n<size:10>CODEC_SPEC_1</size>" as CODEC_SPEC_1 [[../docs/specification/specs.html#CODEC_SPEC_1]] #FEDCD2 
node "<size:12>Specification</size>\n**NDEF URL record**\n<size:10>CODEC_SPEC_3</size>" as CODEC_SPEC_3 [[../docs/specification/specs.html#CODEC_SPEC_3]] #FEDCD2 
node "<size:12>Specification</size>\n**Circular Buffer**\n<size:10>CODEC_SPEC_12</size>" as CODEC_SPEC_12 [[../docs/specification/specs.html#CODEC_SPEC_12]] #FEDCD2 
node "<size:12>Specification</size>\n**Endstop**\n<size:10>CODEC_SPEC_13</size>" as CODEC_SPEC_13 [[../docs/specification/specs.html#CODEC_SPEC_13]] #FEDCD2 
node "<size:12>Specification</size>\n**VFmt b64**\n<size:10>CODEC_SPEC_18</size>" as CODEC_SPEC_18 [[../docs/specification/specs.html#CODEC_SPEC_18]] #FEDCD2 
node "<size:12>Specification</size>\n**HashN b64**\n<size:10>CODEC_SPEC_14</size>" as CODEC_SPEC_14 [[../docs/specification/specs.html#CODEC_SPEC_14]] #FEDCD2 
node "<size:12>Specification</size>\n**Status b64**\n<size:10>CODEC_SPEC_15</size>" as CODEC_SPEC_15 [[../docs/specification/specs.html#CODEC_SPEC_15]] #FEDCD2 
node "<size:12>Specification</size>\n**ResetCause**\n<size:10>CODEC_SPEC_16</size>" as CODEC_SPEC_16 [[../docs/specification/specs.html#CODEC_SPEC_16]] #FEDCD2 
node "<size:12>Specification</size>\n**TNF + flags**\n<size:10>CODEC_SPEC_5</size>" as CODEC_SPEC_5 [[../docs/specification/specs.html#CODEC_SPEC_5]] #FEDCD2 
node "<size:12>Specification</size>\n**Low memory**\n**utilisation**\n<size:10>CODEC_SPEC_4</size>" as CODEC_SPEC_4 [[../docs/specification/specs.html#CODEC_SPEC_4]] #FEDCD2 
node "<size:12>Specification</size>\n**Reduce EEPROM**\n**wear**\n<size:10>CODEC_SPEC_2</size>" as CODEC_SPEC_2 [[../docs/specification/specs.html#CODEC_SPEC_2]] #FEDCD2 
node "<size:12>Specification</size>\n**Low power**\n**consumption**\n<size:10>CODEC_SPEC_8</size>" as CODEC_SPEC_8 [[../docs/specification/specs.html#CODEC_SPEC_8]] #FEDCD2 
node "<size:12>Specification</size>\n**Zero user**\n**configuration**\n<size:10>CODEC_SPEC_6</size>" as CODEC_SPEC_6 [[../docs/specification/specs.html#CODEC_SPEC_6]] #FEDCD2 
node "<size:12>Specification</size>\n**URL parameters**\n**decoded**\n<size:10>CODEC_SPEC_19</size>" as CODEC_SPEC_19 [[../docs/specification/specs.html#CODEC_SPEC_19]] #FEDCD2 
node "<size:12>Specification</size>\n**Circular buffer**\n**decoded**\n<size:10>CODEC_SPEC_10</size>" as CODEC_SPEC_10 [[../docs/specification/specs.html#CODEC_SPEC_10]] #FEDCD2 

' Connection definition 

CODEC_FEAT_1 --> CODEC_SPEC_1
CODEC_FEAT_2 --> CODEC_SPEC_1
CODEC_FEAT_3 --> CODEC_SPEC_3
CODEC_FEAT_4 --> CODEC_SPEC_3
CODEC_FEAT_5 --> CODEC_SPEC_3
CODEC_FEAT_10 --> CODEC_SPEC_3
CODEC_FEAT_38 --> CODEC_SPEC_3
CODEC_FEAT_41 --> CODEC_SPEC_18
CODEC_FEAT_41 --> CODEC_FEAT_43
CODEC_FEAT_42 --> CODEC_SPEC_18
CODEC_FEAT_43 --> CODEC_SPEC_19
CODEC_FEAT_44 --> CODEC_SPEC_3
CODEC_FEAT_28 --> CODEC_SPEC_15
CODEC_FEAT_29 --> CODEC_SPEC_15
CODEC_FEAT_30 --> CODEC_SPEC_15
CODEC_FEAT_40 --> CODEC_SPEC_10
CODEC_FEAT_23 --> CODEC_SPEC_12
CODEC_FEAT_24 --> CODEC_SPEC_14
CODEC_FEAT_25 --> CODEC_SPEC_14
CODEC_FEAT_26 --> CODEC_SPEC_13
CODEC_FEAT_27 --> CODEC_SPEC_6
CODEC_FEAT_27 --> CODEC_SPEC_10
CODEC_FEAT_6 --> CODEC_SPEC_10
CODEC_FEAT_7 --> CODEC_SPEC_3
CODEC_FEAT_13 --> CODEC_SPEC_4
CODEC_FEAT_8 --> CODEC_SPEC_4
CODEC_FEAT_9 --> CODEC_SPEC_4
CODEC_FEAT_14 --> CODEC_SPEC_8
CODEC_FEAT_14 --> CODEC_SPEC_4
CODEC_FEAT_39 --> CODEC_SPEC_15
CODEC_FEAT_12 --> CODEC_SPEC_1
CODEC_FEAT_15 --> CODEC_SPEC_12
CODEC_FEAT_16 --> CODEC_SPEC_4
CODEC_FEAT_16 --> CODEC_SPEC_2
CODEC_FEAT_16 --> CODEC_SPEC_8
CODEC_REQ_1 --> CODEC_REQ_3
CODEC_REQ_8 --> CODEC_REQ_1
CODEC_REQ_2 --> CODEC_REQ_3
CODEC_SPEC_1 --> CODEC_REQ_1
CODEC_SPEC_3 --> CODEC_SPEC_1
CODEC_SPEC_12 --> CODEC_SPEC_3
CODEC_SPEC_12 --> CODEC_SPEC_2
CODEC_SPEC_13 --> CODEC_SPEC_12
CODEC_SPEC_18 --> CODEC_SPEC_3
CODEC_SPEC_14 --> CODEC_SPEC_13
CODEC_SPEC_15 --> CODEC_SPEC_3
CODEC_SPEC_16 --> CODEC_SPEC_15
CODEC_SPEC_5 --> CODEC_SPEC_3
CODEC_SPEC_4 --> CODEC_REQ_12
CODEC_SPEC_2 --> CODEC_REQ_8
CODEC_SPEC_8 --> CODEC_REQ_12
CODEC_SPEC_6 --> CODEC_REQ_7
CODEC_SPEC_19 --> CODEC_REQ_2
CODEC_SPEC_10 --> CODEC_SPEC_19

@enduml

My first needflow

Requirement: Codec comprises an encoder and decoder. CODEC_REQ_3 ../../_images/arrow-right-circle.svg
status: open
links incoming: CODEC_REQ_1, CODEC_REQ_2

The codec comprises has two parts:

  1. An encoder that produces an URL from raw data.

  2. A decoder that recovers raw data from the URL.

Encoder

Requirement: Encoder writes a message CODEC_REQ_1 ../../_images/arrow-right-circle.svg
status: open
links outgoing: CODEC_REQ_3
links incoming: CODEC_REQ_8, CODEC_SPEC_1

The encoder takes environmental sensor data and writes it into a message that is opened and read automatically by most mobile phones.

Requirement: Encoder shall run on a low cost, low power microcontroller CODEC_REQ_12 ../../_images/arrow-right-circle.svg
status: open
links incoming: CODEC_SPEC_4, CODEC_SPEC_8

The encoder will run on an inexpensive microcontroller. This will be powered by a coin cell battery and should run for years.

Requirement: No configuration from the user CODEC_REQ_7 ../../_images/arrow-right-circle.svg
status: complete
links incoming: CODEC_SPEC_6

The encoder must not require any set up or configuration from the user.

Requirement: Message is written to EEPROM CODEC_REQ_8 ../../_images/arrow-right-circle.svg
status: complete
links outgoing: CODEC_REQ_1
links incoming: CODEC_SPEC_2

The encoder must not write to the same EEPROM block too frequently. Each has a write endurance of roughly 100,000 cycles.

Status information changes infrequently compared to environmental sensor data.

Decoder

Requirement: Decoder reproduces encoder data CODEC_REQ_2 ../../_images/arrow-right-circle.svg
status: open
links outgoing: CODEC_REQ_3
links incoming: CODEC_SPEC_19

The decoder must reproduce data fed into the encoder.