{"id":1601,"date":"2020-10-15T18:51:16","date_gmt":"2020-10-15T22:51:16","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/?p=1601"},"modified":"2020-10-17T00:41:29","modified_gmt":"2020-10-17T04:41:29","slug":"worry-free-curtains-and-an-alarm-clock-supplement-thats-natural","status":"publish","type":"post","link":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/?p=1601","title":{"rendered":"Worry free curtains and an alarm clock supplement that&#8217;s natural!"},"content":{"rendered":"<p><strong>Problem:<\/strong><\/p>\n<p>Do you like having natural light in the room during the day, but often forget to close the curtains at night and so get woken up earlier than you wanted in the morning? Do you ever just want to wake up with natural light in the room, but not get woken up too early by it? After not getting enough sleep, do you find yourself having trouble getting up to your alarm or being blinded when you turn on the light or open the curtains because your eyes aren&#8217;t used to it? If you&#8217;re like me and have answered yes to these questions, this worry free curtain and alarm clock supplement could be the solution!<\/p>\n<p><strong>Proposed Solution:<\/strong><\/p>\n<p>Enter the time times you want to wake up each day of the week, the current date and time, upload the program, and that&#8217;s it your curtains will open according to the time you want to wake up and when you went to bed (set by pressing button) and close when it&#8217;s evening and dark. If you didn&#8217;t get nearly enough sleep, a fan will also blow in your face when your alarm goes off to help ensure you wake up. The fan could be an overhead one, but one on a nightstand or a taller one on the floor next to the bed would be best. I used the left and right threaded rods coupled together that I had from a previous project to be able to control the open and closing of the curtains movement. The logic I used for when the curtains should open compared to when you want to wake up and when you went to sleep were set by my preferences wherein the less sleep I got, the earlier the curtains would open based on time frames of amount of sleep. For me if I&#8217;ve gotten less sleep, I wake up to slight changes less than if I got enough sleep. Also, the fan is set to blow at a low speed for a minute when you&#8217;ve had under 5 hours sleep and high speed for 30 seconds if you&#8217;ve had between 5 and 6 hours. This is because higher speed will be more annoying and so needs to be on less; the lower speed is for the least sleep case because you are more likely to get sick on less sleep. I used a stepper motor to control the opening and closing of the curtains as that is what I had available and I can easily control the distance moved forward and reverse precisely. I would&#8217;ve used a faster motor if available and ideally a DC motor and an encoder instead as I&#8217;d be able to control the amounts forward and reverse easily and it&#8217;s more efficient in this scenario. Additionally, if I had a pressure sensor, the time you went to bed would be detected by the time you went on the bed and didn&#8217;t get up again before the alarm. This way you wouldn&#8217;t have to remember to click a button. To add to this, I would add a speaker so that this could be used for an alarm sound itself too. Finally, as someone mentioned during the crit, an app would be really useful for inputting the parameters and quickly making any changes. With the materials I was able to use and the time given, I&#8217;m happy with this prototype and in the future may make this for myself on an actual scale.<\/p>\n<p>For reference, this is what the curtains in my room look like:<\/p>\n<p><strong><img loading=\"lazy\" class=\"size-medium wp-image-1627 aligncenter\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/myCurtains-300x210.jpg\" alt=\"\" width=\"300\" height=\"210\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/myCurtains-300x210.jpg 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/myCurtains-1024x717.jpg 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/myCurtains-768x538.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/myCurtains-1200x840.jpg 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/myCurtains.jpg 1204w\" sizes=\"(max-width: 300px) 85vw, 300px\" \/><\/strong><\/p>\n<p>Ideal fans:<\/p>\n<figure id=\"attachment_1632\" aria-describedby=\"caption-attachment-1632\" style=\"width: 281px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-1632 size-medium\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/small-fan-for-nightstand-281x300.jpg\" alt=\"\" width=\"281\" height=\"300\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/small-fan-for-nightstand-281x300.jpg 281w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/small-fan-for-nightstand.jpg 537w\" sizes=\"(max-width: 281px) 85vw, 281px\" \/><figcaption id=\"caption-attachment-1632\" class=\"wp-caption-text\">small fan for nightstand<\/figcaption><\/figure>\n<figure id=\"attachment_1633\" aria-describedby=\"caption-attachment-1633\" style=\"width: 189px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-1633 size-medium\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/floor-stand-fan-189x300.jpg\" alt=\"\" width=\"189\" height=\"300\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/floor-stand-fan-189x300.jpg 189w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/floor-stand-fan.jpg 366w\" sizes=\"(max-width: 189px) 85vw, 189px\" \/><figcaption id=\"caption-attachment-1633\" class=\"wp-caption-text\">floor stand fan to be put near\u00a0 head of bed<\/figcaption><\/figure>\n<p><strong>Proof of Concept:<\/strong><\/p>\n<div style=\"width: 640px;\" class=\"wp-video\"><!--[if lt IE 9]><script>document.createElement('video');<\/script><![endif]-->\n<video class=\"wp-video-shortcode\" id=\"video-1601-1\" width=\"640\" height=\"368\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/closingAfter6dark.mp4?_=1\" \/><a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/closingAfter6dark.mp4\">https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/closingAfter6dark.mp4<\/a><\/video><\/div>\n<p style=\"text-align: center\"><em>Closing the curtains after 6:00PM and dark<\/em><\/p>\n<div style=\"width: 368px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-1601-2\" width=\"368\" height=\"656\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/setSleepTimeopenfan.mp4?_=2\" \/><a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/setSleepTimeopenfan.mp4\">https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/setSleepTimeopenfan.mp4<\/a><\/video><\/div>\n<p><em>Setting the time went to bed, opening curtains, and blowing the fan.<\/em><\/p>\n<p>You might notice that in this video, the printing format changed from day, month, year to month, day, year. This was an intentional change after the first video because it&#8217;s the format we are accustomed to.<\/p>\n<figure id=\"attachment_1634\" aria-describedby=\"caption-attachment-1634\" style=\"width: 840px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"wp-image-1634 size-large\" src=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/kinetic-crit-circuit-1024x567.jpg\" alt=\"\" width=\"840\" height=\"465\" srcset=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/kinetic-crit-circuit-1024x567.jpg 1024w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/kinetic-crit-circuit-300x166.jpg 300w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/kinetic-crit-circuit-768x425.jpg 768w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/kinetic-crit-circuit-1200x664.jpg 1200w, https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/wp-content\/uploads\/2020\/10\/kinetic-crit-circuit.jpg 1424w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-1634\" class=\"wp-caption-text\">Circuit<\/figcaption><\/figure>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#include &lt;AccelStepper.h&gt;\r\n\r\n\/\/ stepper Motor pin definitions:\r\n#define motorPin1  9      \/\/ IN1 on the ULN2003 driver\r\n#define motorPin2  10      \/\/ IN2 on the ULN2003 driver\r\n#define motorPin3  11     \/\/ IN3 on the ULN2003 driver\r\n#define motorPin4  12     \/\/ IN4 on the ULN2003 driver\r\n\r\n\/\/ Define the AccelStepper interface type; 4 wire motor in half step mode:\r\n#define MotorInterfaceType 8\r\n\r\n\/\/ Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper library with 28BYJ-48 stepper motor:\r\nAccelStepper stepper = AccelStepper(MotorInterfaceType, motorPin1, motorPin3, motorPin2, motorPin4);\r\n\/\/above from  https:\/\/www.makerguides.com to learn how to use this specific stepper motor and driver\r\n\r\n#include &lt;Wire.h&gt;\r\n#include &lt;RTC.h&gt;\r\nconst int photoPin = A5;\r\nstatic DS3231 RTC;\r\n\r\n\/\/input times for each day with hr then min; 24 hr time but as it'll be morning, it shouldn't make too much of a difference\r\nint wakeUpTimes[7][2] ={{12, 12}, \/\/sun\r\n                        {9, 0}, \/\/mon\r\n                        {9, 35}, \/\/tues\r\n                        {8, 55}, \/\/wed\r\n                        {9, 30}, \/\/thurs\r\n                        {10, 10}, \/\/fri\r\n                        {11, 11}};\/\/sat\r\n\r\nconst int fanMotorPin = 3;\r\nint low = 50;\r\nint high = 150;\r\nint fanSpeed;\r\nint turnOnFan;\r\nint fanDuration;\r\n\r\nint timeSlept[3];\r\nint openCurtainsXbeforeWakeUpTime;\r\nint sleep = 0;\r\nconst int buttonPin = 2;\r\n\r\nint timeWentToBed[3];\r\n\r\nvoid calcTimeSlept() {\r\n  \/\/seconds\r\n  int secs = 60 - timeWentToBed[0];\r\n  if (secs == 60) {\r\n    timeSlept[2] = 0;\r\n  }\r\n  else {\r\n    timeSlept[2] = secs;\r\n  }\r\n\r\n  \/\/mins\r\n  if (wakeUpTimes[RTC.getWeek() - 1][1] &gt;= timeWentToBed[1]) {\r\n    if (timeSlept[2] == 0) {\r\n      timeSlept[1] = wakeUpTimes[RTC.getWeek() - 1][1] - timeWentToBed[1];\r\n    }\r\n    else {\r\n      timeSlept[1] = wakeUpTimes[RTC.getWeek() - 1][1] - timeWentToBed[1] - 1;\r\n    }\r\n  }\r\n  else {\r\n    if (timeSlept[2] == 0) {\r\n      timeSlept[1] = wakeUpTimes[RTC.getWeek() - 1][1] + 60 - timeWentToBed[1];\r\n    }\r\n    else {\r\n      timeSlept[1] = wakeUpTimes[RTC.getWeek() - 1][1] + 60 - timeWentToBed[1] - 1;\r\n    }\r\n  }\r\n\r\n  \/\/hrs\r\n  if (timeWentToBed[0] &lt; 12) {\r\n    if (wakeUpTimes[RTC.getWeek() - 1][1] &gt;= timeWentToBed[1]) {\r\n      timeSlept[0] = wakeUpTimes[RTC.getWeek() - 1][0] - timeWentToBed[0];\r\n    }\r\n    else {\r\n      timeSlept[0] = wakeUpTimes[RTC.getWeek() - 1][0] - timeWentToBed[0] - 1;\r\n    }\r\n  }\r\n  else { \/\/if went to bed before midnight, need to add hours bc subtraction not right otherwise\r\n    int hrsBeforeMidnight = 24 - timeWentToBed[0];\r\n    if (wakeUpTimes[RTC.getWeek() - 1][1] &gt;= timeWentToBed[1]) {\r\n      timeSlept[0] = wakeUpTimes[RTC.getWeek() - 1][0] + hrsBeforeMidnight;\r\n    }\r\n    else {\r\n      timeSlept[0] = wakeUpTimes[RTC.getWeek() - 1][0] + hrsBeforeMidnight - 1;\r\n    }\r\n  }\r\n}\r\n\r\nvoid goinToSleep() {\r\n  if (digitalRead(buttonPin) == HIGH) {\r\n    sleep = 1;\r\n  }\r\n}\r\n\r\nvoid openCurtains() {\r\n  while (stepper.currentPosition() != 4096 * 7) { \/\/choosing this bc it was enough rev to at least show some opening\r\n    stepper.setSpeed(1000);\r\n    stepper.runSpeed();\r\n  }\r\n}\r\nvoid closeCurtains() {\r\n  while (stepper.currentPosition() != 0) {\r\n    stepper.setSpeed(-1000);\r\n    stepper.runSpeed();\r\n  }\r\n}\r\n\r\nvoid setup() {\r\n  \/\/ put your setup code here, to run once:\r\n  stepper.setMaxSpeed(1000);\r\n  Serial.begin(9600);\r\n  RTC.begin();\r\n\r\n  RTC.setDay(16);\r\n  RTC.setMonth(10);\r\n  RTC.setYear(2020);\r\n\r\n  RTC.setWeek(6);\r\n\r\n\/\/to show setting time went to bed from button for Fri\r\n  RTC.setHours(10);\r\n  RTC.setMinutes(8);\r\n  RTC.setSeconds(0);\r\n  \r\n\/\/to show fan turning on when not enough sleep for Mon\r\n\/\/  RTC.setHours(8);\r\n\/\/  RTC.setMinutes(59);\r\n\/\/  RTC.setSeconds(30);\r\n\r\n\/\/\/\/to show closing:\r\n\/\/  stepper.setCurrentPosition(4096 * 7);\r\n  \r\n  \/\/to show curtains closing past 5 and dark\r\n\/\/  RTC.setHours(17);\r\n\/\/  RTC.setMinutes(59);\r\n\/\/  RTC.setSeconds(45);\r\n  \r\n\/\/to show opening:\r\n    stepper.setCurrentPosition(0);\r\n  \/\/to show curtain opening:\r\n\/\/  RTC.setHours(8);\r\n\/\/  RTC.setMinutes(49);\r\n\/\/  RTC.setSeconds(58);\r\n\r\n  RTC.setHourMode(CLOCK_H24);\r\n\r\n  pinMode(fanMotorPin, OUTPUT);\r\n\r\n  attachInterrupt (digitalPinToInterrupt (buttonPin), goinToSleep, HIGH);\r\n\r\n  \/*set time went to bed to hr before wakeup as default after woken up\r\n        will change if\/when press button before going to sleep\r\n        this way if you forget still get this, and assuming if didn't press,\r\n        you went to bed really late\r\n  *\/\r\n  \/\/commenting out for demo of button to set time went to bed\r\n  timeWentToBed[0] = wakeUpTimes[RTC.getWeek() - 1][0] - 1;\r\n  timeWentToBed[1] = wakeUpTimes[RTC.getWeek() - 1][1];\r\n  timeWentToBed[2] = 0;\r\n}\r\n\r\nvoid loop() {\r\n  int  photoVal = analogRead(photoPin);\r\n  \/\/Serial.println(photoVal);\r\n  if (RTC.getHours() &gt;= 18) {\/\/6:00PM\r\n    if (photoVal &lt; 600) {\r\n      \/\/if it's past 6PM and dark(here just chose 600, but would be lower in real thing), close curtains\r\n      closeCurtains();\r\n    }\r\n  }\r\n  if (sleep == 1) {\r\n    Serial.println(\"clicked\");\r\n    timeWentToBed[0] = RTC.getHours();\r\n    timeWentToBed[1] = RTC.getMinutes();\r\n    timeWentToBed[2] = RTC.getSeconds();\r\n    calcTimeSlept();\r\n    sleep = 0;\r\n  }\r\n  if (timeSlept[0] &gt;= 8) {\r\n    openCurtainsXbeforeWakeUpTime = 5; \/\/mins\r\n  }\r\n  else if (6 &lt;= timeSlept[0] &amp;&amp; timeSlept[0] &lt; 8) {\r\n    openCurtainsXbeforeWakeUpTime = 30; \/\/mins\r\n  }\r\n  else if (5 &lt;= timeSlept[0] &amp;&amp; timeSlept[0] &lt; 6) {\r\n    openCurtainsXbeforeWakeUpTime = 45; \/\/mins\r\n    turnOnFan = 1;\r\n    fanSpeed = high;\r\n    fanDuration = 30;\r\n  }\r\n  else {\/\/under 5 hrs\r\n    \/\/for demo\r\n    \/\/openCurtainsXbeforeWakeUpTime = 1; \/\/mins\r\n    openCurtainsXbeforeWakeUpTime = 55; \/\/mins\r\n    turnOnFan = 1;\r\n    fanSpeed = low;\r\n    fanDuration = 60;\r\n  }\r\n  if (wakeUpTimes[RTC.getWeek() - 1][1] &gt;= openCurtainsXbeforeWakeUpTime) {\r\n    if (RTC.getHours() == wakeUpTimes[RTC.getWeek() - 1][0]) {\r\n\/\/Serial.println(openCurtainsXbeforeWakeUpTime);\r\n        \/\/Serial.println((wakeUpTimes[RTC.getWeek() - 1][1] - openCurtainsXbeforeWakeUpTime));\r\n      if (RTC.getMinutes() == (wakeUpTimes[RTC.getWeek() - 1][1] - openCurtainsXbeforeWakeUpTime)) {\r\n        openCurtains();\r\n        timeWentToBed[0] = wakeUpTimes[RTC.getWeek() - 1][0] - 1;\r\n        timeWentToBed[1] = wakeUpTimes[RTC.getWeek() - 1][1];\r\n        timeWentToBed[2] = 0;\r\n      }\r\n    }\r\n  }\r\n  else {\/\/minutes of wakeUpTime&lt;time to subtract to wake up\r\n    if (RTC.getHours() == (wakeUpTimes[RTC.getWeek() - 1][0] - 1)) { \/\/took hr off here\r\n      \/\/right side of eq subtracted amount of time left after changing hr\r\n      if (RTC.getMinutes() == (60 - openCurtainsXbeforeWakeUpTime + wakeUpTimes[RTC.getWeek() - 1][1])) {\r\n        openCurtains();\r\n        timeWentToBed[0] = wakeUpTimes[RTC.getWeek() - 1][0] - 1;\r\n        timeWentToBed[1] = wakeUpTimes[RTC.getWeek() - 1][1];\r\n        timeWentToBed[2] = 0;\r\n      }\r\n    }\r\n  }\r\n  \r\n  if (RTC.getHours() == wakeUpTimes[RTC.getWeek() - 1][0]) {\r\n    if (RTC.getMinutes() == wakeUpTimes[RTC.getWeek() - 1][1]) {\r\n      \/\/Serial.println(RTC.getSeconds());\r\n      if (turnOnFan) {\r\n        if (RTC.getSeconds() &lt;= fanDuration) {\r\n          \/\/Serial.println(RTC.getSeconds());\r\n          analogWrite(fanMotorPin, fanSpeed);\r\n        }\r\n        else {\r\n                    analogWrite(fanMotorPin, 0);\r\n          turnOnFan = 0;        \r\n          }\r\n      }\r\n\r\n    }\r\n  }\r\n  static int startPrint=millis();\r\n  if ((millis()-startPrint)&gt;=1000){\/\/putting this here so don't use delay while also showing the times\r\n   switch (RTC.getWeek())\r\n    {\r\n      case 1:\r\n        Serial.print(\"SUN\");\r\n        break;\r\n      case 2:\r\n        Serial.print(\"MON\");\r\n        break;\r\n      case 3:\r\n        Serial.print(\"TUE\");\r\n        break;\r\n      case 4:\r\n        Serial.print(\"WED\");\r\n        break;\r\n      case 5:\r\n        Serial.print(\"THU\");\r\n        break;\r\n      case 6:\r\n        Serial.print(\"FRI\");\r\n        break;\r\n      case 7:\r\n        Serial.print(\"SAT\");\r\n        break;\r\n    }\r\n    Serial.print(\" \");\r\n    Serial.print(RTC.getMonth());\r\n    Serial.print(\"-\");\r\n    Serial.print(RTC.getDay());\r\n    Serial.print(\"-\");\r\n    Serial.print(RTC.getYear());\r\n  \r\n    Serial.print(\" \");\r\n  \r\n    Serial.print(RTC.getHours());\r\n    Serial.print(\":\");\r\n    Serial.print(RTC.getMinutes());\r\n    Serial.print(\":\");\r\n    Serial.println(RTC.getSeconds());\r\n\r\n    startPrint=millis();\r\n  }\r\n  \/\/  delay(1000);\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Problem: Do you like having natural light in the room during the day, but often forget to close the curtains at night and so get woken up earlier than you wanted in the morning? Do you ever just want to wake up with natural light in the room, but not get woken up too early &hellip; <a href=\"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/?p=1601\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Worry free curtains and an alarm clock supplement that&#8217;s natural!&#8221;<\/span><\/a><\/p>\n","protected":false},"author":21,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16],"tags":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/posts\/1601"}],"collection":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1601"}],"version-history":[{"count":6,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/posts\/1601\/revisions"}],"predecessor-version":[{"id":1608,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=\/wp\/v2\/posts\/1601\/revisions\/1608"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1601"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1601"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/48-339\/f2020\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}