diff --git a/lec02/figs/Comparison-of-Majore-IOT-Protocols.png b/lec02/figs/Comparison-of-Majore-IOT-Protocols.png new file mode 100644 index 0000000000000000000000000000000000000000..1b98dca462fe70ce0aab87da00c08fe9f58b2dcd Binary files /dev/null and b/lec02/figs/Comparison-of-Majore-IOT-Protocols.png differ diff --git a/lec02/figs/iot-04.png b/lec02/figs/iot-04.png new file mode 100644 index 0000000000000000000000000000000000000000..8a52fe713da49be3636c2cc540efaeceba677522 Binary files /dev/null and b/lec02/figs/iot-04.png differ diff --git a/lec02/nsi-lec02.ipynb b/lec02/nsi-lec02.ipynb index 9aa3a132e5768511df3164b6889f945aba927c60..f74ca79eb428911574f234f4359f3c992d49d3a6 100644 --- a/lec02/nsi-lec02.ipynb +++ b/lec02/nsi-lec02.ipynb @@ -8,6 +8,41 @@ "# NSI - 2. pĹ™ednáška" ] }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n", + "p1 = 120\n" + ] + } + ], + "source": [ + "# jeste trochu Pythonu :-)\n", + "\n", + "for i in range(1, 10):\n", + " print(i)\n", + "\n", + "\n", + "def ahoj(p1 = 10):\n", + " print('p1 = ', p1)\n", + "\n", + "ahoj(120)" + ] + }, { "attachments": {}, "cell_type": "markdown", @@ -19,7 +54,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -34,9 +69,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'userId': 1, 'id': 1, 'title': 'delectus aut autem', 'completed': False}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# data zdroje\n", "response.json()" @@ -44,9 +90,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "200" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# status kĂłd\n", "response.status_code" @@ -54,9 +111,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'application/json; charset=utf-8'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# hlaviÄŤka odpovÄ›di\n", "response.headers[\"Content-Type\"]" @@ -251,9 +319,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "poslucharna/teplota 0 b'25'\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[10], line 22\u001b[0m\n\u001b[0;32m 18\u001b[0m \u001b[39m# client.subscribe(\"kids/yolo\", 0)\u001b[39;00m\n\u001b[0;32m 19\u001b[0m \u001b[39m# client.subscribe(\"adult/#\", 0)\u001b[39;00m\n\u001b[0;32m 20\u001b[0m client\u001b[39m.\u001b[39msubscribe(\u001b[39m\"\u001b[39m\u001b[39m#\u001b[39m\u001b[39m\"\u001b[39m, \u001b[39m0\u001b[39m)\n\u001b[1;32m---> 22\u001b[0m \u001b[39mwhile\u001b[39;00m client\u001b[39m.\u001b[39;49mloop() \u001b[39m==\u001b[39m \u001b[39m0\u001b[39m:\n\u001b[0;32m 23\u001b[0m \u001b[39mpass\u001b[39;00m\n", + "File \u001b[1;32mc:\\Python310\\lib\\site-packages\\paho\\mqtt\\client.py:1120\u001b[0m, in \u001b[0;36mClient.loop\u001b[1;34m(self, timeout, max_packets)\u001b[0m\n\u001b[0;32m 1117\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_reset_sockets(sockpair_only\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m)\n\u001b[0;32m 1118\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_sockpairR, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_sockpairW \u001b[39m=\u001b[39m _socketpair_compat()\n\u001b[1;32m-> 1120\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_loop(timeout)\n", + "File \u001b[1;32mc:\\Python310\\lib\\site-packages\\paho\\mqtt\\client.py:1150\u001b[0m, in \u001b[0;36mClient._loop\u001b[1;34m(self, timeout)\u001b[0m\n\u001b[0;32m 1147\u001b[0m rlist \u001b[39m=\u001b[39m [\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_sock, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_sockpairR]\n\u001b[0;32m 1149\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m-> 1150\u001b[0m socklist \u001b[39m=\u001b[39m select\u001b[39m.\u001b[39;49mselect(rlist, wlist, [], timeout)\n\u001b[0;32m 1151\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mTypeError\u001b[39;00m:\n\u001b[0;32m 1152\u001b[0m \u001b[39m# Socket isn't correct type, in likelihood connection is lost\u001b[39;00m\n\u001b[0;32m 1153\u001b[0m \u001b[39mreturn\u001b[39;00m MQTT_ERR_CONN_LOST\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], "source": [ "import paho.mqtt.client as paho\n", "\n", diff --git a/lec02/nsi-lec02.md b/lec02/nsi-lec02.md index 5b7aab72d841d8687434e1a04ef99cb6e87492e5..7f2b2b1b57940c7bcd6f71d6ae10e21ebd875b76 100644 --- a/lec02/nsi-lec02.md +++ b/lec02/nsi-lec02.md @@ -37,43 +37,126 @@ Katedra radioelektroniky --- -# Formáty vĂ˝mÄ›ny dat - JSON +# Formáty vĂ˝mÄ›ny dat + +--- + +# XML + +```xml +<?xml version="1.0" encoding="UTF-8" ?> +<book> + <title>Python Basics</title> + <page_count>635</page_count> + <pub_date>2021-03-16</pub_date> + <authors> + <author> + <name>David Amos</name> + </author> + <author><name>Joanna Jablonski</name></author> + <author><name>Dan Bader</name></author> + <author><name>Fletcher Heisler</name></author> + </authors> + <isbn13>978-1775093329</isbn13> + <genre>Education</genre> +</book> +``` + +--- -## JavaScript Object Notification +# JSON - JavaScript Object Notation -* kolekce párĹŻ název:hodnota -* 4 primitivnĂ datovĂ© typy (Ĺ™etÄ›zec, ÄŤĂslo, log. hodnota, NULL) -* 2 strukturovanĂ© datovĂ© typy (objekt, pole) +* ZaloĹľen na podmnoĹľinÄ› standardu programovacĂho jazyka JavaScript ECMA-262 3rd Edition. +* JSON je zpĹŻsob ukládánĂ a komunikace dat se specifickĂ˝mi pravidly (jako napĹ™. XML, YAML atd.) +* Soubory JSON majĂ pĹ™Ăponu .json +* PouĹľĂvá dvojice klĂÄŤ-hodnota +* NavrĹľen tak, aby byl ÄŤitelnĂ˝ pro lidi i stroje a nezávislĂ˝ na jazyce -```json -{"members":[ - { - "name": "John Lennon", - "birthdate": ["year": 1940, "month": 10, "day": 9] - }, - { - "name": "Paul McCartney", - "birthdate": ["year": 1942, "month": 6, "day": 18] - } -]} +http://json.org +https://json-schema.org/ +https://jsonformatter.curiousconcept.com/ +--- + +# JSON pĹ™Ăklad + +```json +{ + "members":[ + { + "name":"Ringo Star", + "alive":true, + "birth":1940 + }, + { + "name":"John Lennon", + "alive":false, + "birth":1940 + }, + { + "name":"Paul McCartney", + "alive":true, + "birth":1942 + }, + { + "name":"George Harrison", + "alive":false, + "birth":1943 + } + ] +} ``` --- -# # Formáty vĂ˝mÄ›ny dat - Binary JSON (BSON) +# JSON - datovĂ© typy + +* ĹetÄ›zec + * <span style="color:red; font=samily: courier;">"Hello world!"</span> + * sekvence znakĹŻ v kĂłdovánĂ Unicode + * znak je reprezentován jako jednoznakovĂ˝ Ĺ™etÄ›zec +* ÄŚĂslo + * <span style="color:blue; font=samily: courier;">10 1.5 1.3e20</span> + * ÄŤĂsla typu integer, float, vÄŤetnÄ› ÄŤĂsel v exponenciálnĂm tvaru +* LogickĂ˝ datovĂ˝ typ (boolean) + * <span style="color:green; font=samily: courier;">true false</span> +* Null + * hodnota mĹŻĹľe bĂ˝t <span style="color:green; font=samily: courier;">null</span> + +--- + +# JSON - datovĂ© typy + +* Pole + * [1, 2 3] ["Hello", "World"] + * poloĹľky oddÄ›lenĂ© čárkou + * poloĹľky nemusĂ bĂ˝t stejnĂ©ho datovĂ©ho typu + +* Objekt + * {"name": "John", "age": 43} + * páry klĂÄŤ-hodnota oddÄ›lenĂ© čárkou + +--- + +# BSON - Binary JSON  --- -# Protokoly relaÄŤnĂ/aplikaÄŤnĂ vrstvy +# Protokoly vyššĂch vrstev + +## AplikaÄŤnĂ, prezentaÄŤnĂ a relaÄŤnĂ + +--- + +# Role protokolĹŻ vyššĂch vrstev -1. PoskytovánĂ abstrakce "zprávy" (elementárnĂ jednotky dat)komunikace mezi koncovĂ˝mi body internetu vÄ›cĂ). +1. PoskytovánĂ abstrakce "zprávy" (elementárnĂ jednotky dat), komunikace mezi koncovĂ˝mi body. -2. PoskytovánĂ primitiv pro datovou komunikaci/vĂ˝mÄ›nu zpráv aplikacĂm vyššà vrstvy internetu vÄ›cĂ. +2. PoskytovánĂ primitiv pro datovou komunikaci/vĂ˝mÄ›nu zpráv aplikacĂm vyššà vrstvy. -3. Implementace specifickĂ˝ch sĂĹĄovĂ˝ch paradigmat (napĹ™. Publish-Subscribe nebo Request-Response). +3. Implementace specifickĂ˝ch sĂĹĄovĂ˝ch paradigmat. 4. PoskytovánĂ dodateÄŤnĂ˝ch mechanismĹŻ spolehlivosti nebo zabezpeÄŤenĂ. @@ -87,7 +170,8 @@ Katedra radioelektroniky * HTTP * CoAP 2. **Publish-Subscribe** - * MQTT, AMQP + * MQTT + * AMQP 3. **Push-Pull** 4. **Exclusive Pair** @@ -279,6 +363,12 @@ Katedra radioelektroniky --- +# COAP - Constrained Application Protocol + + + +--- + # COAP protokol * RozdÄ›len do dvou dĂlÄŤĂch vrstev @@ -299,7 +389,7 @@ Katedra radioelektroniky ## PĹ™Ăklad komunikace -  +  --- @@ -534,3 +624,9 @@ Mechanismus OBSERVE umoĹľĹuje implementovat mechanismus odbÄ›ru dat * Klient a server mohou po navázánĂ spojenĂ navzájem posĂlat zprávy .  + +--- + +# PorovnánĂ komunikaÄŤnĂch IoT protokolĹŻ + + \ No newline at end of file diff --git a/lec02/nsi-lec02.pdf b/lec02/nsi-lec02.pdf deleted file mode 100644 index 546bb033e3fa0f1321bba84a150bd4b21ce69064..0000000000000000000000000000000000000000 Binary files a/lec02/nsi-lec02.pdf and /dev/null differ diff --git a/lec02/rpc/client2.py b/lec02/rpc/client2.py new file mode 100644 index 0000000000000000000000000000000000000000..8eaab5b8f5449a88a5de5a6ebbe7107cf3ac72a5 --- /dev/null +++ b/lec02/rpc/client2.py @@ -0,0 +1,7 @@ +import xmlrpc.client +s = xmlrpc.client.ServerProxy('http://localhost:8000') +print(s.len("Tutorialspoint")) +print(s.rmndr(12,5)) +print(s.modl(7,3)) +# Print list of available methods +print(s.system.listMethods()) \ No newline at end of file diff --git a/lec02/rpc/server2.py b/lec02/rpc/server2.py new file mode 100644 index 0000000000000000000000000000000000000000..f15999770a023aa8f2a533e5e8e4ed29d82089a2 --- /dev/null +++ b/lec02/rpc/server2.py @@ -0,0 +1,18 @@ +from xmlrpc.server import SimpleXMLRPCServer +from xmlrpc.server import SimpleXMLRPCRequestHandler +class RequestHandler(SimpleXMLRPCRequestHandler): + rpc_paths = ('/RPC2',) +with SimpleXMLRPCServer(('localhost', 8000), + requestHandler=RequestHandler) as server: + server.register_introspection_functions() + # Register len() function; + server.register_function(len) + # Register a function under a different name + @server.register_function(name='rmndr') + def remainder_function(x, y): + return x // y + # Register a function under function.__name__. + @server.register_function + def modl(x, y): + return x % y + server.serve_forever() \ No newline at end of file diff --git a/lec03/nsi-lec03.ipynb b/lec03/nsi-lec03.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..885b8165a6985daff7f91996bea4431b8c382cd5 --- /dev/null +++ b/lec03/nsi-lec03.ipynb @@ -0,0 +1,85 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# NSI - 3. pĹ™ednáška\n", + "## TĹ™Ădy a objekty" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[<matplotlib.lines.Line2D at 0x131ef181510>]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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lClT9OKLLx5z4eyp5na7dccddxxzSgmDg/k+tZjvU4v5PrWY71NrsOfbYY7nXh8AAIBTiO/iAQAA1iFQAACAdQgUAABgHQIFAABYh0D5mF//+tcaPXq0MjMzNWvWLL399ttDPaTTwooVK3TeeecpLy9PJSUlmj9/vnbs2JG0TU9PjxYvXqyioiLl5uZqwYIFxzzIDyfnnnvukcPh0JIlSxLLmO/UOnjwoL71rW+pqKhIWVlZmjRpktatW5dYb4zR7bffrtLSUmVlZam6ulq7du0awhEPX7FYTMuXL1dlZaWysrJ05pln6ic/+UnSd7sw3yfv9ddf1+WXX66ysjI5HA49++yzSeuPZ25bW1u1cOFCeTwe5efn65prrlFHR8eJD8bAGGPMU089ZTIyMsxvf/tb895775lrr73W5Ofnm2AwONRDG/bmzZtnHn30UbNlyxazadMmc+mll5qKigrT0dGR2OY73/mOKS8vNzU1NWbdunXm/PPPN3PmzBnCUZ8e3n77bTN69Ghz7rnnmhtvvDGxnPlOndbWVjNq1Cjz7W9/29TV1Zk9e/aYl156yezevTuxzT333GO8Xq959tlnzebNm81Xv/pVU1lZabq7u4dw5MPTXXfdZYqKiswLL7xg9u7da55++mmTm5trfvWrXyW2Yb5P3p///Gfzox/9yPzxj380kswzzzyTtP545vbiiy82kydPNm+99ZZ54403zFlnnWW++c1vnvBYCJQjZs6caRYvXpz4cywWM2VlZWbFihVDOKrTU1NTk5FkVq9ebYwxpq2tzaSnp5unn346sc22bduMJFNbWztUwxz22tvbzdixY80rr7xivvSlLyUChflOrR/+8Ifmggsu+Ifr4/G48fv95mc/+1liWVtbm3G73eb3v//9qRjiaeWyyy4zV199ddKyK664wixcuNAYw3yn0tGBcjxzu3XrViPJrF27NrHNX/7yF+NwOMzBgwdP6P05xSMpGo1q/fr1qq6uTixzOp2qrq5WbW3tEI7s9BQKhSRJhYWFkqT169ert7c3af6rqqpUUVHB/H8Gixcv1mWXXZY0rxLznWrPPfecZsyYoW984xsqKSnR1KlT9cgjjyTW7927V4FAIGm+vV6vZs2axXyfhDlz5qimpkY7d+6UJG3evFlr1qzRJZdcIon5HkzHM7e1tbXKz8/XjBkzEttUV1fL6XSqrq7uhN5vWHyb8WBrbm5WLBY75im2Pp9P27dvH6JRnZ7i8biWLFmiuXPnauLEiZKkQCCgjIyMY74A0ufzKRAIDMEoh7+nnnpKGzZs0Nq1a49Zx3yn1p49e/TQQw9p6dKl+s///E+tXbtW3//+95WRkaFFixYl5nSg3y/M94m77bbbFA6HVVVVpbS0NMViMd11111auHChJDHfg+h45jYQCKikpCRpvcvlUmFh4QnPP4GCU2rx4sXasmWL1qxZM9RDOW3V19frxhtv1CuvvKLMzMyhHs5pLx6Pa8aMGbr77rslSVOnTtWWLVu0atUqLVq0aIhHd/r5wx/+oCeeeEJPPvmkJkyYoE2bNmnJkiUqKytjvk8znOKRVFxcrLS0tGPuYggGg/L7/UM0qtPP9ddfrxdeeEF/+9vfNHLkyMRyv9+vaDSqtra2pO2Z/5Ozfv16NTU1adq0aXK5XHK5XFq9erVWrlwpl8sln8/HfKdQaWmpxo8fn7Rs3LhxOnDggCQl5pTfL6nxgx/8QLfddpuuvPJKTZo0Sf/+7/+um266SStWrJDEfA+m45lbv9+vpqampPV9fX1qbW094fknUCRlZGRo+vTpqqmpSSyLx+OqqanR7Nmzh3BkpwdjjK6//no988wzevXVV1VZWZm0fvr06UpPT0+a/x07dujAgQPM/0m48MIL9e6772rTpk2J14wZM7Rw4cLE/2a+U2fu3LnH3Da/c+dOjRo1SpJUWVkpv9+fNN/hcFh1dXXM90no6uqS05n80ZWWlqZ4PC6J+R5MxzO3s2fPVltbm9avX5/Y5tVXX1U8HtesWbNO7A0/0yW+p5GnnnrKuN1u89hjj5mtW7ea6667zuTn55tAIDDUQxv2vvvd7xqv12tee+0109jYmHh1dXUltvnOd75jKioqzKuvvmrWrVtnZs+ebWbPnj2Eoz69fPwuHmOY71R6++23jcvlMnfddZfZtWuXeeKJJ0x2drb53e9+l9jmnnvuMfn5+eZPf/qTeeedd8zXvvY1bns9SYsWLTJnnHFG4jbjP/7xj6a4uNjceuutiW2Y75PX3t5uNm7caDZu3Ggkmfvvv99s3LjR7N+/3xhzfHN78cUXm6lTp5q6ujqzZs0aM3bsWG4z/qweeOABU1FRYTIyMszMmTPNW2+9NdRDOi1IGvD16KOPJrbp7u423/ve90xBQYHJzs42X//6101jY+PQDfo0c3SgMN+p9fzzz5uJEycat9ttqqqqzMMPP5y0Ph6Pm+XLlxufz2fcbre58MILzY4dO4ZotMNbOBw2N954o6moqDCZmZlmzJgx5kc/+pGJRCKJbZjvk/e3v/1twN/XixYtMsYc39y2tLSYb37zmyY3N9d4PB5z1VVXmfb29hMei8OYjz1+DwAAwAJcgwIAAKxDoAAAAOsQKAAAwDoECgAAsA6BAgAArEOgAAAA6xAoAADAOgQKAACwDoECAACsQ6AAAADrECgAAMA6BAoAALDO/weLO9BMUHetvQAAAABJRU5ErkJggg==", + "text/plain": [ + "<Figure size 640x480 with 1 Axes>" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import random\n", + "import matplotlib.pyplot as plt\n", + "\n", + "last = 100\n", + "data = []\n", + "\n", + "for i in range (1, 100):\n", + " rnd = random.random()-0.5\n", + " last += rnd\n", + " data.append(last)\n", + "\n", + "plt.plot(data)\n", + "# fig, ax = plt.subplots()\n", + "# ax.set_ylim([0, 110])\n", + "# ax.plot(data)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.3" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "369f2c481f4da34e4445cda3fffd2e751bd1c4d706f27375911949ba6bb62e1c" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}