Writing a book is hard enough – getting all the details right prior to print is nearly impossible. This section of my blog is dedicated to addressing various errata and providing clarification around content within Programming the Internet of Things, First Edition.It will be updated as I uncover others.

Table of Contents

  1. First Release – June 2021
    1. Errata
    2. Clarifications
    3. Updated Images
  2. FAQ

NOTE: For convenience, hyperlinks are embedded, using the phrase ‘Nearest Hyperlink’, pointing to the closest part of the online version of the book (O’Reilly Media – Programming the Internet of Things).

First Release – June 2021

Errata

  • Part I, Chapter 1, Page 10 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: Paragraph describing the Constrained Device Application (CDA)
      • Original: “… and actuators (which trigger actions, such as turning the thermostat on or off).”
      • Corrected: “… and actuators (which trigger actions, such as turning the HVAC on or off).”
      • Explanation: For the purposes of the example given, HVAC is more accurate as it represents the system to be activated / deactivated by a system such as the CDA, whilst a thermostat is a control device that automatically regulates temperature.
  • Part I, Chapter 1, Page 12 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: Chapter reference in first paragraph is incorrect.
      • Original: “We’ll dig into the functionality within the Cloud Tier beginning in Chapter 10.”
      • Corrected: “We’ll dig into the functionality within the Cloud Tier beginning in Chapter 11.”
      • Explanation: Content designated for cloud integration was moved to Chapter 11.
    • Errata: Last sentence in 3rd paragraph should reference optional exercises for Chapter 4.
      • Original: “The other two required IoT-specific hardware and will be discussed in more detail in Chapter 4.”
      • Corrected: “The other two require IoT-specific hardware and – while optional – are briefly covered as part of the optional exercises for Chapter 4.”
      • Explanation: Software is the focus for the book.
  • Part I, Chapter 1, Page 23 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: There are three steps to initially running your GDA. The second step (#2) states, ‘Build your project and create an executable package.’
      • Original: Step #2 provides instructions for running a build within your IDE (e.g., Eclipse) using Maven.
      • Corrected: You can skip step #2 within the IDE and go from step #1 to step #3.
      • Explanation: Running Maven without telling it to skip unit tests will cause the build to fail, as it will – by default – attempt to run all tests specified in the repository. However, most tests do not yet have corresponding implementations, so they’ll fail, existing the build with error conditions. For now, you can simply ignore this step. The original step content and output was from a previous build that did not have any unit tests implemented as of yet. Optionally, you can tell Maven to skip tests in your IDE configuration, or by updating your pom.xml accordingly.
  • Part I, Chapter 2, Page 70 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: GDA code segment after the bullet with the text ‘Create a public method named handleTelemetry() and add the following code…’ specifies a mis-named method / function name
      • Original: Code segment is provided as follows:
        • cpuUtilPct = this.cpuUtilTask.getTelemetry()
        • memUtilPct = this.memUtilTask.getTelemetry()
      • Corrected: Code segment should read as follows:
        • cpuUtilPct = this.cpuUtilTask.getTelemetryValue()
        • memUtilPct = this.memUtilTask.getTelemetryValue()
      • Explanation: Method / function name was renamed from ‘getTelemetry()‘ to ‘getTelemetryValue()‘.
  • Part I, Chapter 2, Page 61 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: The reference to the first parameter to self.scheduler.add_job() should not be quoted, and the reference to the third parameter seconds = pollRate should be seconds = self.pollRate.
      • Original: Code segment is provided as follows:
        • self.scheduler.add_job('self.handleTelemetry', 'interval', seconds = pollRate)
      • Corrected: Code segment should read as follows:
        • self.scheduler.add_job(self.handleTelemetry, 'interval', seconds = self.pollRate)
      • Explanation: The first argument should be a function reference, not a string value, and the third argument named pollRate is a class-scoped variable and should be referenced as self.pollRate.
  • Part II, Chapter 3, Page 96 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: Code segment is missing a test for duplicate command value.
      • Original: Code segment is provided as follows
        • if curCommand == self.lastKnownCommand:
      • Corrected: Code segment should read as follows
        • if curCommand == self.lastKnownCommand and curVal == self.lastKnownValue:
      • Explanation: For this simulator, it’s acceptable for duplicate actuator commands (e.g., ON) provided the command value is different.
  • Part II, Chapter 3, Pages 108 – 109 (Nearest Hyperlink)
    • Errata: Actuator task variable names are different in the book and online GitHub repository content, and should verify if the task itself is non-null prior to executing the logic.
      • Original: Sample code segment is provided as follows
        • if aType == ConfigConst.HUMIDIFIER_ACTUATOR_TYPE
          • responseData = self.humidifierEmulator.updateActuator(data)
      • Corrected: Code segment should read as follows
        • if aType == ConfigConst.HUMIDIFIER_ACTUATOR_TYPE and self.humidifierActuator:
          • responseData = self.humidifierActuator.updateActuator(data)
      • Explanation: Disambiguation required between printed book and online content. The pattern above should be applied to the logic for HUMIDIFIER_ACTUATOR_TYPE, HVAC_ACTUATOR_TYPE, and LED_DISPLAY_ACTUATOR_TYPE. See corrected sample code in PIOT-CDA-03-007
  • Part II, Chapter 4, Page 128 (Nearest Hyperlink)
    • Errata: The variable named SensorData should begin with a lower case ‘s’.
      • Original: Sample code segment is provided as follows:
        • Variable declaration in generateTelemetry() was ‘SensorData
      • Corrected: Code segment should read as follows:
        • Variable declaration in generateTelemetry() should be ‘sensorData
      • Explanation: Variable name capitalization is incorrect.
  • Part II, Chapter 5, Pages 143 – 146 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: The DataUtilTest in the ./part02/unit/data directory expects a different signature in DataUtil than that which is depicted in the online and printed version of the book.
      • Original: Method signatures for data to JSON conversion and back again depict the following (the pattern is the same for each of the three object conversions – ActuatorData, SensorData, SystemPerformanceData):
        • Object to JSON: def actuatorDataToJson(self, data):
        • JSON to Object: def jsonToActuatorData(self, jsonData):
      • Corrected: Method signatures for data to JSON conversion and back again should depict the following (the pattern is the same for each of the three object conversions – ActuatorData, SensorData, SystemPerformanceData):
        • Object to JSON: def actuatorDataToJson(self, data: ActuatorData = None, useDecForFloat: bool = False):
        • JSON to Object: def jsonToActuatorData(self, jsonData: str = None, useDecForFloat: bool = False):
      • Explanation: Unit tests and solutions were updated after the book went to print. The Kanban board is now updated, although the electronic and printed version of the book are not (yet). Keep in mind that the examples above only depict the method signatures for ActuatorData conversions. You’ll need to apply this same pattern to SensorData and SystemPerformanceData conversion methods.
  • Part II, Chapter 5, Pages 152 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: The SystemPerformanceManager class implementation described in the book doesn’t explicitly call out the requirements to add new class-scoped variables or configuration information retrieval in the constructor.
      • Original: No reference to, or instructions for, adding required class-scoped variables locationID (a String) and dataMsgListener (of type IDataMessageListener) is provided in the book or online version (these are included in the Kanban card, however).
      • Corrected: The corrected text should include a paragraph describing the above, and is corrected in the Kanban board card for PIOT-GDA-05-002.
      • Explanation: This clarification was simply missed when the book went to print.
  • Part III, Chapter 6, Page 189 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: Paragraph content has incorrect data:
      • Original: “This time, the MQTT packet length is 29 bytes, since the client ID “CDAMqttClientConnectorTest001” is 17 bytes”.
      • Corrected: “This time, the MQTT packet length is 41 bytes, since the client ID “CDAMqttClientConnectorTest001” is 29 bytes”
      • Explanation: The packet length is 41 bytes (not 29), and the client ID is 29 bytes (not 17). The example on the page was updated with a longer client ID; however, the prose was not updated to reflect the change.
  • Part III, Chapter 6, Page 197 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: A line of code is missing from the book example.
      • Original:
        • self.mqttClient = MqttClientConnector()
      • Corrected:
        • self.mqttClient = MqttClientConnector()
        • self.mqttClient.setDataMessageListener(self)
      • Explanation: The IDataMessageListener callback registration for self.mqttClient is missing.
  • Part III, Chapter 7, Pages 209 – 210 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata and Explanation: The sample code shown for publishing, subscribing and unsubscribing is incorrect. The Kanban board card for PIOT-GDA-07-003 provides the correct sample code for publishMessage(), subscribeToTopic(), and unsubscribeFromTopic().
  • Part III, Chapter 8, Page 227, Figure 8-3 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata and Explanation: (B3) “GET request to server”, while technically correct, should state “GET (OBSERVE) request to server” to disambiguate from a basic GET request. In CoAP, OBSERVE is essentially a GET request with a flag or value set to instruct the server the resource is to be observed.
  • Part III, Chapter 10, Page 287 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: The PiotConfig.props example at the bottom of the page for the Mqtt.GatewayService section indicates the certFile should use ‘ca.crt’. It should specify ‘server.crt’ instead.
      • Original: certFile = /someNonGitPath/cert/ca.crt
      • Corrected: certFile = /someNonGitPath/cert/server.crt
      • Explanation: The server cert should be used instead. The instructions for PIOT-CFG-10-001 and PIOT-INT-10-004 have been updated to provide further clarification. Please also note that the path ‘/someNonGitPath’ is notional only, and is designed to indicate a path that is NOT under Git (or other) source control.
  • Part IV, Chapter 11, Page 333, Figure 11-14 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata: In the test event sample JSON, line 7 includes a newline escape character (‘\n’)
      • Original: “locationID”: “Not s\net”,
      • Corrected: “locationID”: “Not set”,
      • Explanation: Copy / paste error.
  • Part IV, Chapter 12, Page 347, Figure 12-4 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata and Explanation: As with the other related diagrams (Figures 12-2, 12-3, and 12-5), a directional arrow should be depicted from the Internet cloud icon to the API gateway icon.
  • Appendix, Page 355, Figure A-5 (Nearest Hyperlink)
    • NOTE: Content update forthcoming.
    • Errata and Explanation: The class name ‘PressureSensorSimTask’ shown derived from ‘BaseActuatorSimTask’ in the lower-right of the image should be named ‘HvacActuatorEmulatorTask’ instead.

Clarifications

  • Part I, Chapter 1 (throughout) (Nearest Hyperlink)
    • Clarification: You’ll see references to ‘java-components’ and ‘piot-java-components’, as well as ‘python-components’ and ‘piot-python-components’ throughout this section. The former for each is the name of the GitHub repository (e.g., ‘java-components’), whereas the latter is the name of the Eclipse project (e.g., ‘piot-java-components’).
  • Part I, Chapter 1, Page 22 (Nearest Hyperlink)
    • Clarification: The last paragraph indicates “…there are already two files in the project…” stubbed out in code for you to use. In fact, nearly all files for each exercise have been stubbed out, with some utility classes written completely. The reason for creating the sample code and stubbed out classes / modules was to provide a clear structure of code that maps to the design concepts discussed throughout the book.
  • Part I, Chapter 1, Page 37, Figure 1-12 (Nearest Hyperlink)
    • Clarification: Although generally implied via the content that will be contained within ‘Actions’, the task template should include ‘Acceptance Criteria’ prior to the ‘Tests’ section, with references to each acceptance criterion within each documented test.
  • Part III, Chapter 10 (Nearest Hyperlink)
    • Clarification: When using MQTT for both the GDA and CDA, there may exist situations where you will encounter a deadlock condition if you’re attempting to process an incoming message via subscription while also attempting to publish an outgoing message on the same thread. This is relatively straight-forward to resolve as per the notes included here:
  • Appendix – Pages 351 – 369 (Nearest Hyperlink)
    • Clarification: To preserve space and ensure each diagram fits within the width margins on the page, some component names have been abbreviated
      • For instance, page 356 depicts ‘HumidityActuEmulatorTask’, which is the abbreviated class name for ‘HumidityActuatorEmulatorTask’.

Updated Images

  1. The screenshot depicted in Part IV, Chapter 11, Figure 11-5 may be difficult to read in print form. Here’s a full-color version of the same diagram (Nearest Hyperlink)

Programming the Internet of Things: Part IV, Chapter 11, Figure 11-5.

Figure 11-5 – Ubidots dashboard example screenshot (credit: Andy King, Programming the Internet of Things)

FAQ

  1. Why ‘yet another book on the IoT’?
    • Programming the Internet of Things is the book I wished existed when I started out teaching the subject and advising on IoT challenges several years ago. I was looking for a concise guide that covered the thinking, design, implementation, and testing of an IoT ecosystem – from device to cloud. It didn’t exist at the time, but now it does :). My book may not answer all your questions, but it will walk you through the design and implementation of the key software components of a simple IoT ecosystem.
  2. Can you provide a little history around the genesis of your book?
    • I joined the faculty of Northeastern University for Spring Semester 2018 where I was hired to teach the Connected Devices course. This was not only a fantastic opportunity to work with some amazing colleagues at a world-class research institute, but also one where I could create my own syllabus, content, and outcomes for the course. A key value proposition of the course was centered on ‘how’; more specifically, ‘how’ an IoT ecosystem works from a software design, development, and integration perspective. This concept not only helped me focus on the lecture and lab module material (what would eventually become a ~750 page slide deck with four supporting GitHub source repositories), but more importantly, it provided the inspiration for the most important assignment in the class: a Semester-long implementation project centered on building a basic IoT ecosystem – from scratch. The combination of these provided the basis for what would eventually become my book, Programming the Internet of Things.
  3. Does Programming the Internet of Things contain the same content as your Connected Devices course?
    • Only partially – the assignments are the same as the exercises from the book (including those that are optional), although the course itself also includes lectures, quizzes, mentoring by both TA’s and instructors, and, occasionally, guest speakers who are also involved in building IoT ecosystems.
  4. Why do your IDE examples use Eclipse? Do I have to use this IDE or can I choose my own?
    • It’s the primary IDE I’ve been using for many years, yet there’s no requirement to use a specific IDE. It’s your choice – use the IDE you’re most comfortable with (as indicated in Part I, Chapter 1).
  5. Why Python and Java? Why not just one language? Why not others?
    • Both languages are commonly used for IoT and other enterprise development initiatives, and provide a plethora of well-defined and maintained libraries to support communications and system integration. If there’s enough demand for the book and further requests for enhancements, I may consider re-implementing some of the exercises in other languages :).
  6. Why are all the exercises stubbed out in code within the Python and Java repositories?
    • I’ve been asked at various points during my teaching to include a coding framework for students to build upon, as well as sample code / solutions for some of the more mundane logic (e.g., configuration functionality, certificate loading, etc.) I came up with what I believe to be a reasonable compromise – hence, the stubbed out modules and classes and sample code that now exists within python-components and java-components.
  7. Why aren’t there any code comments for the stubbed out classes and methods / functions?
    • I included extensive code comments in the completed code, but purposely excluded them from the stubbed out code (the Python and Java you’ll write if implementing the exercises). This is by design – so you can learn to write your own code comments. To guide you along, read the commentary for each exercise in the book – it will probably help you with implementation and how to document the code.
  8. How do I get access to the exercise solutions?
    • The solutions to the core exercises are actually embedded within the book (Programming the Internet of Things), and in some cases, included as sample solution code embedded within the Programming the IoT Kanban Board exercise cards. The optional exercises – those within the Kanban Board and discussed as ‘additional exercises’ at the end of most chapters – are designed for you to work on independently from the book.
  9. Why not cover, for example, AWS Greengrass or Azure IoT Edge? Why build your own gateway device app?
    • I think the documentation for both products are generally self-explanatory, although a deeper dive into each (and others) may certainly worth considering in the future. Why build your own GDA? I believe it’s a great way to learn how complex a gateway device is – logically-speaking – and gain a deeper understanding of the basic concepts of edge tier to cloud tier integration.
  10. Why are there only two chapters dedicated to cloud integration?
    • The original book proposal was going to include one chapter for each major Cloud Service Provider, nearly doubling the size of the tome. I decided to scale back since there are already a number of excellent cloud computing books on the market, and because the Edge Tier concepts discussed in the book deserved more attention for this version.
  11. I was expecting more content on the business applications of the IoT. What gives?
  12. Why is there a cat cameo in your featured image at the top of the page?
    • One of our cats loves boxes. He was probably figuring out how to remove the books so he could claim the box as his own. Or maybe he really wanted to start Programming the Internet of Things… Cats think everything belongs to them, of course.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: