diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 18b2b295..755f4f90 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,6 +26,10 @@ repos: rev: v2.2.6 hooks: - id: codespell + exclude: > + (?x)^( + .*\.ambr + )$ - repo: https://github.com/charliermarsh/ruff-pre-commit rev: v0.13.2 hooks: diff --git a/roborock/devices/device.py b/roborock/devices/device.py index e58bac9d..d7908c74 100644 --- a/roborock/devices/device.py +++ b/roborock/devices/device.py @@ -33,7 +33,9 @@ MIN_BACKOFF_INTERVAL = datetime.timedelta(seconds=10) MAX_BACKOFF_INTERVAL = datetime.timedelta(minutes=30) BACKOFF_MULTIPLIER = 1.5 -START_ATTEMPT_TIMEOUT = datetime.timedelta(seconds=5) +# Give time for the NETWORK_INFO fetch and V1 hello attempt +# and potential fallback to L01. +START_ATTEMPT_TIMEOUT = datetime.timedelta(seconds=15) DeviceReadyCallback = Callable[["RoborockDevice"], None] diff --git a/tests/e2e/__init__.py b/tests/e2e/__init__.py index 38fd7fb6..d1bdda39 100644 --- a/tests/e2e/__init__.py +++ b/tests/e2e/__init__.py @@ -5,4 +5,5 @@ "tests.fixtures.local_async_fixtures", "tests.fixtures.pahomqtt_fixtures", "tests.fixtures.aiomqtt_fixtures", + "tests.fixtures.web_api_fixtures", ] diff --git a/tests/e2e/__snapshots__/test_device_manager.ambr b/tests/e2e/__snapshots__/test_device_manager.ambr new file mode 100644 index 00000000..ccea0922 --- /dev/null +++ b/tests/e2e/__snapshots__/test_device_manager.ambr @@ -0,0 +1,503 @@ +# serializer version: 1 +# name: test_l01_device + [mqtt >] + 00000000 10 29 00 04 4d 51 54 54 05 c2 00 3c 00 00 00 00 |.)..MQTT...<....| + 00000010 08 31 39 36 34 38 66 39 34 00 10 32 33 34 36 37 |.19648f94..23467| + 00000020 38 65 61 38 35 34 66 31 39 39 65 |8ea854f199e| + [mqtt <] + 00000000 20 09 02 00 06 22 00 0a 21 00 14 | ...."..!..| + [mqtt >] + 00000000 82 24 00 01 00 00 1e 72 72 2f 6d 2f 6f 2f 75 73 |.$.....rr/m/o/us| + 00000010 65 72 31 32 33 2f 31 39 36 34 38 66 39 34 2f 61 |er123/19648f94/a| + 00000020 62 63 31 32 33 00 |bc123.| + [mqtt <] + 00000000 90 04 00 01 00 00 |......| + [mqtt >] + 00000000 30 f8 01 00 1e 72 72 2f 6d 2f 69 2f 75 73 65 72 |0....rr/m/i/user| + 00000010 31 32 33 2f 31 39 36 34 38 66 39 34 2f 61 62 63 |123/19648f94/abc| + 00000020 31 32 33 00 31 2e 30 00 00 23 83 00 00 23 84 68 |123.1.0..#...#.h| + 00000030 a6 a2 27 00 65 00 c0 d5 b7 f1 34 a4 76 21 76 0a |..'.e.....4.v!v.| + 00000040 ed 60 71 51 04 ae bd 39 9b 41 c6 34 63 89 66 1f |.`qQ...9.A.4c.f.| + 00000050 c2 8b 96 83 ec 93 45 55 f0 cf ed 93 0f 45 ff a9 |......EU.....E..| + 00000060 a4 8b a5 5a c9 25 36 1a eb cf 1d 6d d9 b5 b6 37 |...Z.%6....m...7| + 00000070 8a a3 4d 9c 2f e4 41 f3 75 28 11 6c 2d 39 83 cb |..M./.A.u(.l-9..| + 00000080 b1 60 8b 92 d5 b7 a7 be e3 c0 aa 80 94 0c 99 12 |.`..............| + 00000090 a2 e1 97 7e 3e ea 29 27 0f 9e 9c 22 97 0b 9c 59 |...~>.)'..."...Y| + 000000a0 78 da 88 55 6b 52 58 b7 a3 2b 85 67 49 5e 90 85 |x..UkRX..+.gI^..| + 000000b0 d8 7a bb b3 c9 14 6c fb 42 1c 85 96 23 ff 30 02 |.z....l.B...#.0.| + 000000c0 78 20 1c 5b 96 e1 f2 ad f2 62 28 c2 8a 9f 97 79 |x .[.....b(....y| + 000000d0 f9 73 25 c4 66 98 e8 ea f3 37 20 f9 94 7e 2b d6 |.s%.f....7 ..~+.| + 000000e0 fb 9a ed 2c 37 e8 b2 b0 3d f3 93 6f 17 d7 89 31 |...,7...=..o...1| + 000000f0 bb e0 42 8b 18 fd 0d 62 2d 95 ca |..B....b-..| + [mqtt <] + 00000000 30 8c 02 00 1e 72 72 2f 6d 2f 6f 2f 75 73 65 72 |0....rr/m/o/user| + 00000010 31 32 33 2f 31 39 36 34 38 66 39 34 2f 61 62 63 |123/19648f94/abc| + 00000020 31 32 33 00 00 00 00 e7 31 2e 30 00 00 00 01 00 |123.....1.0.....| + 00000030 00 00 17 68 a6 a2 23 00 66 00 d0 84 66 bd 8c 5a |...h..#.f...f..Z| + 00000040 42 4a aa 2d 9e bf 93 7e 3e 92 5a 46 38 2b db 75 |BJ.-...~>.ZF8+.u| + 00000050 ab 6c 28 b5 3d 80 d9 b7 73 cf b9 9e cf 62 52 ca |.l(.=...s....bR.| + 00000060 4e b4 7e b9 89 e9 50 45 4d f3 e1 c8 a9 a4 65 f1 |N.~...PEM.....e.| + 00000070 6d ff 2d e4 c6 c8 4e 8b 85 08 5c 20 91 76 f7 af |m.-...N...\ .v..| + 00000080 cf 25 80 48 e6 95 97 b1 0f b0 6e 1e 62 26 a1 d1 |.%.H......n.b&..| + 00000090 38 c4 f1 39 2a b9 3b 05 0e 37 cb d5 5b cd 95 e7 |8..9*.;..7..[...| + 000000a0 4b f6 ff d7 03 dc 6b e3 ac d6 7e ec a7 75 64 08 |K.....k...~..ud.| + 000000b0 2d 2a 6d e1 af 94 ee a4 b3 4f ed 1e d8 aa 76 f0 |-*m......O....v.| + 000000c0 bd 02 37 7c 6b 5b fb 8d 62 b0 c1 85 79 49 df 67 |..7|k[..b...yI.g| + 000000d0 3c 1e 9a a3 b3 4d 1d 50 ac 9f 62 b9 99 4f 45 47 |<....M.P..b..OEG| + 000000e0 ba 41 30 53 19 63 92 84 c5 bc a4 33 2f 21 8c dd |.A0S.c.....3/!..| + 000000f0 6e f2 b1 ed 08 59 50 2a b1 a9 e2 f1 bb af 4b 6b |n....YP*......Kk| + 00000100 7c 87 7f 0c dd 9b 6d 26 a4 20 bb a7 e0 82 5c ||.....m&. ....\| + [local >] + 00000000 00 00 00 15 31 2e 30 00 00 00 01 00 00 23 85 68 |....1.0......#.h| + 00000010 a6 a2 28 00 00 2a 04 e3 89 |..(..*...| + [local <] + 00000000 00 |.| + [local >] + 00000000 00 00 00 15 4c 30 31 00 00 00 01 00 00 23 85 68 |....L01......#.h| + 00000010 a6 a2 29 00 00 22 92 f7 02 |..).."...| + [local <] + 00000000 00 00 00 29 4c 30 31 00 00 00 01 00 00 00 17 68 |...)L01........h| + 00000010 a6 a2 24 00 01 00 12 c1 07 5b 52 43 96 97 c5 29 |..$......[RC...)| + 00000020 59 36 cc 5c 9c 8b f2 ab 8a f0 30 d7 a9 |Y6.\......0..| + [local >] + 00000000 00 00 00 86 4c 30 31 00 00 23 87 00 00 23 88 68 |....L01..#...#.h| + 00000010 a6 a2 2a 00 04 00 6f 62 62 b7 96 c7 51 5f a7 4b |..*...obb...Q_.K| + 00000020 92 8f ce 25 cb 15 55 28 7a 93 03 83 ec 3c d9 9b |...%..U(z....<..| + 00000030 e2 c0 34 22 93 c0 c6 9a ff b2 9a df c3 01 b3 ad |..4"............| + 00000040 f3 a4 7f 05 f5 9c c5 89 38 55 42 09 ad 60 56 88 |........8UB..`V.| + 00000050 b7 cb 6f 62 f2 6d 04 a3 39 1f 69 70 64 41 29 d8 |..ob.m..9.ipdA).| + 00000060 20 a8 b4 64 d0 ae 37 79 b4 85 44 bb 66 87 14 39 | ..d..7y..D.f..9| + 00000070 33 20 60 02 0f 4e b1 bf 87 8a 84 5a 29 44 e1 d5 |3 `..N.....Z)D..| + 00000080 40 a6 02 6a 67 81 63 37 eb 07 |@..jg.c7..| + [local <] + 00000000 00 00 03 b5 4c 30 31 00 00 00 02 00 00 00 17 68 |....L01........h| + 00000010 a6 a2 25 00 66 03 9e f6 bf 79 0a 3e 32 de 58 fa |..%.f....y.>2.X.| + 00000020 f1 b0 dd a2 47 f6 30 37 c6 c1 24 70 3d bd 9c 15 |....G.07..$p=...| + 00000030 1f 2e 64 c7 95 7a e4 4f 5d 0a c6 d6 7a 9f b9 ad |..d..z.O]...z...| + 00000040 10 75 e3 b5 ff 4c e0 b5 dd 20 34 53 6f 40 4d ef |.u...L... 4So@M.| + 00000050 9c fd c7 83 49 99 80 0b 29 c9 b0 e7 57 4f 7d 24 |....I...)...WO}$| + 00000060 3b 09 42 fb 78 1f cc 39 2e ff 05 e3 0a 19 7f be |;.B.x..9........| + 00000070 6e cc ee d4 fe 3a dc 92 00 9e 07 09 ae 74 fc 95 |n....:.......t..| + 00000080 8b 4e 87 73 40 da bc 06 40 62 e7 49 86 e8 03 36 |.N.s@...@b.I...6| + 00000090 01 21 84 47 2b 1c 5f 64 26 8a 3c 65 0f 83 91 86 |.!.G+._d&..Mv..Z| + 000002d0 e0 cf 61 65 3b d4 30 04 f1 9f c0 14 33 b4 dc a0 |..ae;.0.....3...| + 000002e0 6e cc b7 eb 7d 52 e0 e2 c7 87 7e 31 52 64 92 3f |n...}R....~1Rd.?| + 000002f0 5d 55 d8 92 d0 d9 c0 11 92 36 40 f1 cc 67 14 84 |]U.......6@..g..| + 00000300 2a 00 08 91 21 b5 c9 12 c0 56 34 57 d2 e8 ef 51 |*...!....V4W...Q| + 00000310 81 10 eb c9 d9 84 a3 38 6d b5 b7 2c b6 52 a5 d6 |.......8m..,.R..| + 00000320 c5 33 94 a7 ed 27 00 c1 2e e2 88 0f 73 16 59 06 |.3...'......s.Y.| + 00000330 47 aa 45 6e e1 c7 31 69 b8 87 ae 1d 8f 01 ab 38 |G.En..1i.......8| + 00000340 69 ba a0 48 a0 47 3b a4 8f bf ac 51 64 6d e8 6a |i..H.G;....Qdm.j| + 00000350 ce a4 0a 2f af 36 04 97 60 f7 98 da df 84 7b d2 |.../.6..`.....{.| + 00000360 c6 c4 ac 9e 7d d7 86 b8 61 2b 1f b7 8e 19 67 69 |....}...a+....gi| + 00000370 cf 4e 65 b0 e9 50 b2 19 23 9e 8b de 4f 08 87 d2 |.Ne..P..#...O...| + 00000380 14 64 53 b8 f1 34 a9 ce 34 d3 c4 81 64 c0 9f 43 |.dS..4..4...d..C| + 00000390 c2 c4 bb 0b b0 ae ed e7 3f 28 cd 90 dd f6 7e dd |........?(....~.| + 000003a0 f7 2a 36 ad a6 a3 e2 1c 5e 52 41 a7 da 02 1e b4 |.*6.....^RA.....| + 000003b0 b5 c6 bf 22 a1 9f 76 65 45 |..."..veE| + [local >] + 00000000 00 00 00 7d 4c 30 31 00 00 23 8a 00 00 23 8b 68 |...}L01..#...#.h| + 00000010 a6 a2 2b 00 04 00 66 20 60 4b 53 1e 12 de 76 a8 |..+...f `KS...v.| + 00000020 54 c9 45 0a 1f 8d ec 16 42 2c 16 30 9b 69 03 a8 |T.E.....B,.0.i..| + 00000030 28 76 60 ff cf 40 84 05 29 92 68 05 71 df b5 5f |(v`..@..).h.q.._| + 00000040 56 f6 f1 d1 05 89 8f 23 6c 02 56 38 a2 e8 5a 08 |V......#l.V8..Z.| + 00000050 02 bd 2b db b7 c8 ff 25 52 ac 76 52 50 e7 a3 24 |..+....%R.vRP..$| + 00000060 4d ee 52 b4 00 f9 e2 49 c7 23 4b bd 11 6e cd 31 |M.R....I.#K..n.1| + 00000070 32 b3 57 f0 68 3d f4 87 10 21 5d 5a 0f e7 5a b4 |2.W.h=...!]Z..Z.| + 00000080 55 |U| + [local <] + 00000000 00 00 04 2a 4c 30 31 00 00 00 03 00 00 00 17 68 |...*L01........h| + 00000010 a6 a2 26 00 66 04 13 ce 36 7e 30 29 16 38 0c d3 |..&.f...6~0).8..| + 00000020 b0 34 ac 93 71 51 2c 20 ac a7 fb fa b7 1d 24 98 |.4..qQ, ......$.| + 00000030 4f 23 6e 89 0c 21 07 b4 8b a1 5a 86 ab c8 8e 94 |O#n..!....Z.....| + 00000040 9b 0f fc 8d 57 bc 01 a8 8e 95 27 e3 6a 08 5f b6 |....W.....'.j._.| + 00000050 cc 78 7c 39 c5 07 44 ae 70 2b bb e2 0a 0f 90 e9 |.x|9..D.p+......| + 00000060 a2 00 c5 9f 06 f2 b0 a5 85 e8 59 c5 36 bd 87 83 |..........Y.6...| + 00000070 78 e4 ed 0d 48 1c 60 bc 7f d9 aa c7 e5 25 cb 1b |x...H.`......%..| + 00000080 24 c7 c6 d8 96 c7 5d c8 f7 e5 a9 03 c9 6b 52 3e |$.....]......kR>| + 00000090 43 56 0a 82 9f bb f8 3d 92 38 9d 65 d0 26 53 cf |CV.....=.8.e.&S.| + 000000a0 62 48 ae ce 77 df 70 4a 0f e1 fc c7 36 da e7 64 |bH..w.pJ....6..d| + 000000b0 1f b0 aa 07 a1 1a 46 78 55 ad b7 52 99 33 16 a7 |......FxU..R.3..| + 000000c0 ed f4 a6 a3 45 58 bc a9 c0 4e db 0d 8c 7e 23 a2 |....EX...N...~#.| + 000000d0 d1 08 34 49 e5 ba 3e df c1 e3 b7 a4 38 78 47 e2 |..4I..>.....8xG.| + 000000e0 21 5f 16 30 86 c3 14 f8 f6 16 f9 aa d9 7f f5 87 |!_.0............| + 000000f0 70 a1 d2 3b a6 55 63 fe 78 7f c5 f5 bf 6d 51 80 |p..;.Uc.x....mQ.| + 00000100 d1 d9 e6 ce 5f 93 16 8b f7 b2 02 41 62 a9 90 95 |...._......Ab...| + 00000110 1f a9 82 3b 9e 22 ed 84 c5 31 12 bc 2d 7b 52 05 |...;."...1..-{R.| + 00000120 eb c3 b8 e9 66 5e 59 cf cb 4f b1 39 6b 8a 61 b8 |....f^Y..O.9k.a.| + 00000130 48 f4 a8 de 92 5e 68 c5 01 36 65 3c 5c 60 83 93 |H....^h..6e<\`..| + 00000140 25 f1 d4 96 fa a1 e9 3e 22 18 c2 b5 27 1e bb 92 |%......>"...'...| + 00000150 06 3c 6a ee 3e 03 fb a3 73 fe 22 5c ca f4 90 95 |....s."\....| + 00000160 be cf 91 dd 1e 3f fe ef 5b ac a6 5d 23 f2 9a 28 |.....?..[..]#..(| + 00000170 20 79 ec b7 0c 4b cc a3 3c a6 02 ce 3c eb b9 93 | y...K..<...<...| + 00000180 60 5b bb ab ab 1a 86 1f d2 3a 63 38 12 d2 2c 15 |`[.......:c8..,.| + 00000190 5e f0 12 23 c0 86 93 b7 70 fc 29 2b 75 41 e5 43 |^..#....p.)+uA.C| + 000001a0 ad 64 64 33 4d f3 a9 7b f9 4c 79 62 b0 3a 22 d5 |.dd3M..{.Lyb.:".| + 000001b0 0c 22 ee 55 60 11 0d 30 f5 ac ac a6 42 ec 12 85 |.".U`..0....B...| + 000001c0 d4 7f d1 ba 11 d3 da 40 03 d6 d6 1b d6 35 72 77 |.......@.....5rw| + 000001d0 49 05 be e6 c8 c7 84 4c 25 0b 4d b6 1f 59 2b 09 |I......L%.M..Y+.| + 000001e0 d5 4a 59 f1 7d 19 70 a9 39 29 25 fd 0e d1 ad 5d |.JY.}.p.9)%....]| + 000001f0 6a 91 c3 61 c7 ad c1 ed 4f 47 8c 54 d7 27 25 ee |j..a....OG.T.'%.| + 00000200 77 30 2d 36 73 60 3a d1 9b 5b 8a 8f 52 be f3 f7 |w0-6s`:..[..R...| + 00000210 68 a3 f5 16 a6 c3 df 2d c0 93 15 4a f9 00 3b 7d |h......-...J..;}| + 00000220 29 8c c4 ab 25 a5 ea d3 03 fc 67 06 b3 d3 23 55 |)...%.....g...#U| + 00000230 ef 8c 03 84 e2 af 3c b9 22 f4 cf 9e 44 9f df 4a |......<."...D..J| + 00000240 95 7e 22 8a 92 29 ce 86 6f 0a 70 6d 7b 47 2e 99 |.~"..)..o.pm{G..| + 00000250 6f d5 46 a8 61 13 2c 00 cb 06 80 fa 6d 73 20 88 |o.F.a.,.....ms .| + 00000260 e5 ec 00 89 4d 38 93 5c 11 28 5a 0e e7 3c 21 18 |....M8.\.(Z.....p......| + 00000340 12 85 2a 27 5a 92 54 fe ec 6f 51 ee 9a d6 ec 5a |..*'Z.T..oQ....Z| + 00000350 60 3e 12 5e 4b 78 c2 60 c5 3e 06 c1 24 43 4f 31 |`>.^Kx.`.>..$CO1| + 00000360 1a 37 61 06 d7 b3 f4 a9 bd 5b 1f 4e cf d7 c9 81 |.7a......[.N....| + 00000370 1b 5e f5 94 af 10 55 b2 01 e6 89 a7 1d 68 df b2 |.^....U......h..| + 00000380 8c a6 9a 2b 36 5c e2 9c 4b 69 0e 2e 03 b6 e3 18 |...+6\..Ki......| + 00000390 4c ca 5e 4e e6 44 1b 1f e9 e0 7d 73 2e 72 ce 39 |L.^N.D....}s.r.9| + 000003a0 e3 12 90 89 12 eb 93 34 1a 11 4f d1 98 33 c0 41 |.......4..O..3.A| + 000003b0 f0 6b 5d 64 90 4a cc 5c f6 2f 46 a0 55 20 d7 36 |.k]d.J.\./F.U .6| + 000003c0 0c 92 1a 85 68 aa 44 73 1d d0 7c c4 ba 31 33 a0 |....h.Ds..|..13.| + 000003d0 43 00 0e b3 43 68 98 7b 3d f9 4f 7c e8 c4 30 9e |C...Ch.{=.O|..0.| + 000003e0 0c b8 c1 89 56 88 a1 1c 5b ff dd 92 2c ef bf 0e |....V...[...,...| + 000003f0 23 48 d2 bd 48 84 99 14 a7 e8 19 cc 50 5e 0a 05 |#H..H.......P^..| + 00000400 90 1a e0 25 1a 4b 55 74 fe 59 36 47 e3 e5 79 fd |...%.KUt.Y6G..y.| + 00000410 a0 9b 5e 72 8d 3e 57 69 0b 7c 21 80 2f a4 d5 12 |..^r.>Wi.|!./...| + 00000420 99 be 49 6e f3 0b 57 e5 a8 1e 88 b6 7b 48 |..In..W.....{H| +# --- +# name: test_v1_device + [mqtt >] + 00000000 10 29 00 04 4d 51 54 54 05 c2 00 3c 00 00 00 00 |.)..MQTT...<....| + 00000010 08 31 39 36 34 38 66 39 34 00 10 32 33 34 36 37 |.19648f94..23467| + 00000020 38 65 61 38 35 34 66 31 39 39 65 |8ea854f199e| + [mqtt <] + 00000000 20 09 02 00 06 22 00 0a 21 00 14 | ...."..!..| + [mqtt >] + 00000000 82 24 00 01 00 00 1e 72 72 2f 6d 2f 6f 2f 75 73 |.$.....rr/m/o/us| + 00000010 65 72 31 32 33 2f 31 39 36 34 38 66 39 34 2f 61 |er123/19648f94/a| + 00000020 62 63 31 32 33 00 |bc123.| + [mqtt <] + 00000000 90 04 00 01 00 00 |......| + [mqtt >] + 00000000 30 f8 01 00 1e 72 72 2f 6d 2f 69 2f 75 73 65 72 |0....rr/m/i/user| + 00000010 31 32 33 2f 31 39 36 34 38 66 39 34 2f 61 62 63 |123/19648f94/abc| + 00000020 31 32 33 00 31 2e 30 00 00 23 83 00 00 23 84 68 |123.1.0..#...#.h| + 00000030 a6 a2 27 00 65 00 c0 d5 b7 f1 34 a4 76 21 76 0a |..'.e.....4.v!v.| + 00000040 ed 60 71 51 04 ae bd 39 9b 41 c6 34 63 89 66 1f |.`qQ...9.A.4c.f.| + 00000050 c2 8b 96 83 ec 93 45 55 f0 cf ed 93 0f 45 ff a9 |......EU.....E..| + 00000060 a4 8b a5 5a c9 25 36 1a eb cf 1d 6d d9 b5 b6 37 |...Z.%6....m...7| + 00000070 8a a3 4d 9c 2f e4 41 f3 75 28 11 6c 2d 39 83 cb |..M./.A.u(.l-9..| + 00000080 b1 60 8b 92 d5 b7 a7 be e3 c0 aa 80 94 0c 99 12 |.`..............| + 00000090 a2 e1 97 7e 3e ea 29 27 0f 9e 9c 22 97 0b 9c 59 |...~>.)'..."...Y| + 000000a0 78 da 88 55 6b 52 58 7e de 1c a3 c8 ec 0b 55 1d |x..UkRX~......U.| + 000000b0 86 46 cf 86 98 45 05 f3 06 76 db 4f 4e 2f 10 65 |.F...E...v.ON/.e| + 000000c0 ae 40 8d 86 4c 66 28 c8 4b 31 a5 ec 43 3d 40 21 |.@..Lf(.K1..C=@!| + 000000d0 90 07 ff fb 4f 5b f8 ea f3 37 20 f9 94 7e 2b d6 |....O[...7 ..~+.| + 000000e0 fb 9a ed 2c 37 e8 b2 b0 3d f3 93 6f 17 d7 89 31 |...,7...=..o...1| + 000000f0 bb e0 42 8b 18 fd 0d 46 bd 10 67 |..B....F..g| + [mqtt <] + 00000000 30 8c 02 00 1e 72 72 2f 6d 2f 6f 2f 75 73 65 72 |0....rr/m/o/user| + 00000010 31 32 33 2f 31 39 36 34 38 66 39 34 2f 61 62 63 |123/19648f94/abc| + 00000020 31 32 33 00 00 00 00 e7 31 2e 30 00 00 00 01 00 |123.....1.0.....| + 00000030 00 00 17 68 a6 a2 23 00 66 00 d0 84 66 bd 8c 5a |...h..#.f...f..Z| + 00000040 42 4a aa 2d 9e bf 93 7e 3e 92 5a 46 38 2b db 75 |BJ.-...~>.ZF8+.u| + 00000050 ab 6c 28 b5 3d 80 d9 b7 73 cf b9 9e cf 62 52 ca |.l(.=...s....bR.| + 00000060 4e b4 7e b9 89 e9 50 45 4d f3 e1 c8 a9 a4 65 f1 |N.~...PEM.....e.| + 00000070 6d ff 2d e4 c6 c8 4e 8b 85 08 5c 20 91 76 f7 af |m.-...N...\ .v..| + 00000080 cf 25 80 48 e6 95 97 b1 0f b0 6e 1e 62 26 a1 d1 |.%.H......n.b&..| + 00000090 38 c4 f1 39 2a b9 3b 05 0e 37 cb d5 5b cd 95 e7 |8..9*.;..7..[...| + 000000a0 4b f6 ff d7 03 dc 6b e3 ac d6 7e ec a7 75 64 08 |K.....k...~..ud.| + 000000b0 2d 2a 6d e1 af 94 ee a4 b3 4f ed 1e d8 aa 76 f0 |-*m......O....v.| + 000000c0 bd 02 37 7c 6b 5b fb 8d 62 b0 c1 85 79 49 df 67 |..7|k[..b...yI.g| + 000000d0 3c 1e 9a a3 b3 4d 1d 50 ac 9f 62 b9 99 4f 45 47 |<....M.P..b..OEG| + 000000e0 ba 41 30 53 19 63 92 84 c5 bc a4 33 2f 21 8c dd |.A0S.c.....3/!..| + 000000f0 6e f2 b1 ed 08 59 50 2a b1 a9 e2 f1 bb af 4b 6b |n....YP*......Kk| + 00000100 7c 87 7f 0c dd 9b 6d 26 a4 20 bb a7 e0 82 5c ||.....m&. ....\| + [local >] + 00000000 00 00 00 15 31 2e 30 00 00 00 01 00 00 23 85 68 |....1.0......#.h| + 00000010 a6 a2 28 00 00 2a 04 e3 89 |..(..*...| + [local <] + 00000000 00 00 00 27 31 2e 30 00 00 00 01 00 00 00 17 68 |...'1.0........h| + 00000010 a6 a2 24 00 01 00 10 e1 cc 62 66 4e c7 42 27 80 |..$......bfN.B'.| + 00000020 ee 12 a0 f8 9c 54 d3 d3 b6 78 34 |.....T...x4| + [local >] + 00000000 00 00 00 77 31 2e 30 00 00 23 87 00 00 23 88 68 |...w1.0..#...#.h| + 00000010 a6 a2 29 00 04 00 60 69 d4 c5 8b a1 6e 03 47 01 |..)...`i....n.G.| + 00000020 c4 cd bb 48 17 96 fb 9d b8 60 84 05 dc 99 96 e0 |...H.....`......| + 00000030 72 3e dc 6d 9d de a5 73 e6 c4 e8 7d 9a a5 ea d7 |r>.m...s...}....| + 00000040 73 7f 0d 58 31 a2 38 bc 85 2c 65 9e 93 e4 e8 ca |s..X1.8..,e.....| + 00000050 f0 c9 f9 fb 32 52 3c 1b 73 ea 1b ef 1a 71 17 de |....2R<.s....q..| + 00000060 74 77 ba 97 6e f7 27 9d c6 1b ac f4 64 6a 27 72 |tw..n.'.....dj'r| + 00000070 b6 ae 41 f6 17 60 99 fc 0d 53 ed |..A..`...S.| + [local <] + 00000000 00 00 03 a7 31 2e 30 00 00 00 02 00 00 00 17 68 |....1.0........h| + 00000010 a6 a2 25 00 66 03 90 a4 7d c1 13 61 78 1f aa ec |..%.f...}..ax...| + 00000020 22 05 51 cf c4 af fa ba eb 80 2f 0e 34 f6 d5 ae |".Q......./.4...| + 00000030 36 13 f2 0e 56 cd 69 4d 0f 4b 30 54 c0 67 1e f9 |6...V.iM.K0T.g..| + 00000040 b9 26 c0 0d 54 36 92 b1 47 20 25 ff 10 88 f3 8a |.&..T6..G %.....| + 00000050 e1 2b a7 cc 65 0b 27 35 5d 2f 7a 03 85 1a 92 8c |.+..e.'5]/z.....| + 00000060 51 2a 8b d8 4f 8d 8e 00 53 c3 d9 0c ea 17 79 9e |Q*..O...S.....y.| + 00000070 38 41 93 0e 19 6b cf 41 d3 16 b4 f9 8c db a5 65 |8A...k.A.......e| + 00000080 f2 9c dc ae 2d 69 85 f0 7f 7a dd 6c ba 46 1f c3 |....-i...z.l.F..| + 00000090 96 4f df be 32 fc 7a ed 6d 86 0b 7b 2d c7 03 00 |.O..2.z.m..{-...| + 000000a0 44 b1 ae 6a 32 3b e8 28 56 60 95 ec bd 59 b7 90 |D..j2;.(V`...Y..| + 000000b0 72 34 ca a6 ca 27 c7 0b 77 43 b5 76 3e fc f3 76 |r4...'..wC.v>..v| + 000000c0 c8 b3 2d fd 63 d8 89 6a 8b ad 11 27 64 d2 76 0f |..-.c..j...'d.v.| + 000000d0 96 d4 50 b4 99 cc 6a 81 bf 9a 8e 6b 99 27 92 c9 |..P...j....k.'..| + 000000e0 89 9e c3 e0 23 83 65 bd ec b9 fd ec 11 c5 76 a1 |....#.e.......v.| + 000000f0 bf ed 7c a5 a0 f8 ac 9b 71 c6 09 31 bd 5c 1f ef |..|.....q..1.\..| + 00000100 c5 b5 e3 f3 b3 92 66 d9 aa 76 67 62 c6 e0 db 36 |......f..vgb...6| + 00000110 a7 69 74 e6 ea fa eb a3 16 ba 04 6b 4f dc 7a 4d |.it........kO.zM| + 00000120 5d 3d 8c 9a 52 0b 88 f6 f7 db 62 a8 ce f1 73 8b |]=..R.....b...s.| + 00000130 2e 72 b4 92 53 29 0d 5b 65 5d 14 46 a0 55 4f 74 |.r..S).[e].F.UOt| + 00000140 13 a9 27 96 fb bb c9 09 58 71 05 03 9f c0 71 0a |..'.....Xq....q.| + 00000150 74 9a 9e 01 6f f9 04 ed 10 56 e9 3d 7c c1 88 11 |t...o....V.=|...| + 00000160 19 3e b3 80 58 8c 37 95 ea f7 9b 95 1b 51 36 38 |.>..X.7......Q68| + 00000170 c9 97 60 44 01 53 ba 24 c5 f7 15 45 ce 08 e0 51 |..`D.S.$...E...Q| + 00000180 6b 8b 2f de 79 e8 6d ef f2 c5 73 31 8e 12 f5 9b |k./.y.m...s1....| + 00000190 d7 b0 a6 c8 b5 78 09 7d a6 06 53 4a 45 aa 74 22 |.....x.}..SJE.t"| + 000001a0 95 f4 9e 99 d2 63 f4 3b 60 e6 8c 5f 73 68 89 f0 |.....c.;`.._sh..| + 000001b0 0f 12 82 a3 8a 63 4b eb a6 75 9e 6d 2f 1f 1a 2c |.....cK..u.m/..,| + 000001c0 90 67 03 60 3a fd bc c2 31 72 ce 2c f0 7b 30 2d |.g.`:...1r.,.{0-| + 000001d0 5b f0 f4 d2 b9 2f 7b f0 08 aa c7 8a 95 bb 68 7d |[..../{.......h}| + 000001e0 40 a8 9b 2c 5e c4 61 a5 cc 86 16 91 d6 cb c4 ab |@..,^.a.........| + 000001f0 a9 6e d2 26 ef 7d ad 99 0a 47 bc f5 3c 30 fe 88 |.n.&.}...G..<0..| + 00000200 b1 4b 39 27 40 92 96 77 55 eb 32 69 f1 fd 12 ab |.K9'@..wU.2i....| + 00000210 c6 39 c1 55 5e 1a df 9e 62 f2 df eb ac 2f 66 44 |.9.U^...b..../fD| + 00000220 46 05 7a 9e eb df d1 50 2e 4a 7b 9f 0d 19 c8 64 |F.z....P.J{....d| + 00000230 5b df 81 37 60 6f e9 b2 90 ef bc 76 27 43 c6 bb |[..7`o.....v'C..| + 00000240 63 6c 17 d3 d0 6d 37 0c 87 5c f8 ab e6 90 35 91 |cl...m7..\....5.| + 00000250 e5 d1 49 b1 c5 a7 0e eb 67 e0 ac fe 83 45 c4 6c |..I.....g....E.l| + 00000260 28 1d 7f d9 45 64 48 95 68 35 68 d3 80 06 3f 39 |(...EdH.h5h...?9| + 00000270 fd e4 6d 85 9d 29 8a f9 1b c4 4b 66 00 2e 36 d8 |..m..)....Kf..6.| + 00000280 41 fd ae 70 d5 3c 3e 83 fd a4 1c c0 1a 24 6e 91 |A..p.<>......$n.| + 00000290 b4 24 9f 98 6c f0 a4 c2 65 c4 e1 f3 34 bb b1 bd |.$..l...e...4...| + 000002a0 15 c1 b3 81 bc 9a 22 eb ad ab dd 22 ad b5 a2 59 |......"...."...Y| + 000002b0 88 6d a5 0e 28 d0 5e fe 46 62 f3 6d bf e8 6e 83 |.m..(.^.Fb.m..n.| + 000002c0 04 35 38 2d 7d c9 9b 63 c5 0d 5b 1f 99 07 f2 73 |.58-}..c..[....s| + 000002d0 63 8e 12 e9 3c f3 0c 5c c0 ca 40 ec d3 db 6d 84 |c...<..\..@...m.| + 000002e0 a1 0e 2f 42 6b e5 27 7f f6 b1 cf b9 f0 bf 67 ec |../Bk.'.......g.| + 000002f0 9a 14 b8 34 07 f5 10 60 7e 42 1c 3d b8 a0 07 be |...4...`~B.=....| + 00000300 0f c7 dd 5a 65 58 45 64 d3 10 1e 96 47 a7 ff e0 |...ZeXEd....G...| + 00000310 a7 56 f6 62 a1 c5 41 d6 b1 0f d8 24 56 80 c1 94 |.V.b..A....$V...| + 00000320 ac e6 34 4a 94 bf 07 6e bd e5 4c 07 81 f0 e9 73 |..4J...n..L....s| + 00000330 2f 56 c7 8b 54 31 f1 c0 b9 06 82 6e 3f 67 19 d1 |/V..T1.....n?g..| + 00000340 0f 79 9d 97 30 d3 22 6a 83 6b d7 48 34 7e 45 41 |.y..0."j.k.H4~EA| + 00000350 c7 e4 0e 26 98 56 c5 15 2d 35 f5 7e 67 d7 fb e5 |...&.V..-5.~g...| + 00000360 d8 76 c0 4d cb 0a 40 e3 0a 9e c7 9a 8c 6f 70 1d |.v.M..@......op.| + 00000370 10 b2 38 21 cc 98 5c 93 e7 ab b4 32 ec 15 ce f6 |..8!..\....2....| + 00000380 36 3a 09 27 62 bf bf 60 75 6d fb 36 b3 d8 c9 b5 |6:.'b..`um.6....| + 00000390 2b 5b d8 03 2e 79 4e c8 6c 66 48 97 ff 57 5f c8 |+[...yN.lfH..W_.| + 000003a0 c1 64 16 82 ba 30 5f 2f fd 96 ad |.d...0_/...| + [local >] + 00000000 00 00 00 77 31 2e 30 00 00 23 8a 00 00 23 8b 68 |...w1.0..#...#.h| + 00000010 a6 a2 2a 00 04 00 60 54 4f 82 9c 0f f0 e7 9c bb |..*...`TO.......| + 00000020 62 2e 87 79 75 6f 69 fa de 20 5a ef 66 01 1c 8d |b..yuoi.. Z.f...| + 00000030 2f 2b ca 36 e5 6f 3c 67 3a ee da 29 cf 87 66 1f |/+.6.o..<.| + 00000050 57 8c 73 44 ae b7 7d 2b 94 06 3f 12 6e 09 f0 9a |W.sD..}+..?.n...| + 00000060 c9 10 27 10 02 cd cd 69 61 64 28 ef 2c 78 44 db |..'....iad(.,xD.| + 00000070 8e 2f e2 d7 42 2c 0e fd 47 05 26 |./..B,..G.&| + [local <] + 00000000 00 00 04 27 31 2e 30 00 00 00 03 00 00 00 17 68 |...'1.0........h| + 00000010 a6 a2 26 00 66 04 10 23 78 4f 6e 2e 1a 98 9f 3d |..&.f..#xOn....=| + 00000020 a3 69 31 89 a2 c2 c7 b3 77 2a 69 ec 36 d0 1b 8d |.i1.....w*i.6...| + 00000030 f8 b0 e8 1c d8 6b 72 92 69 7b 6d 8c 1b a9 ba a1 |.....kr.i{m.....| + 00000040 d8 9d 0c b4 fb 99 ba f0 7a 30 de 17 90 11 df 4b |........z0.....K| + 00000050 87 8c 38 1d 3c 23 93 26 ab 0d fb 22 28 a1 e2 85 |..8.<#.&..."(...| + 00000060 dd 7d 36 63 7e 48 5c ff 32 57 e7 87 dd 45 5f eb |.}6c~H\.2W...E_.| + 00000070 9b 27 f5 82 cb 47 11 af 36 09 de 2e 4e c9 77 63 |.'...G..6...N.wc| + 00000080 16 3c 1a 43 9b ad 5c 70 f8 55 e7 ec ba 05 0c 65 |.<.C..\p.U.....e| + 00000090 60 c3 73 29 ca 2c 8b 7f eb ce bd 94 b8 69 37 7a |`.s).,.......i7z| + 000000a0 ee b7 18 5e cd f3 86 14 d3 e4 72 44 37 86 0c 59 |...^......rD7..Y| + 000000b0 67 89 d0 9b d5 0f 8a 56 b7 9f 59 33 95 6c c4 ef |g......V..Y3.l..| + 000000c0 47 c3 51 6b 92 6b b0 88 a9 58 f6 1e 2c d9 71 e4 |G.Qk.k...X..,.q.| + 000000d0 a3 f9 cb ea 27 61 e0 e6 8a 55 4a 8c 55 4e 37 0c |....'a...UJ.UN7.| + 000000e0 da 55 a2 76 b9 f7 bd 36 ef 82 c4 49 88 52 47 3d |.U.v...6...I.RG=| + 000000f0 b2 1f d8 23 b8 a8 b6 c1 9a a5 77 5c f2 39 30 fe |...#......w\.90.| + 00000100 16 ed 37 a6 79 54 77 e0 f9 b5 41 20 bf 63 fc bb |..7.yTw...A .c..| + 00000110 37 9e 4a a7 f5 f7 13 5e 56 a2 ac 7d 33 7d 20 86 |7.J....^V..}3} .| + 00000120 c8 4d 95 cd 9c f8 d8 10 68 60 60 6e fc 4b 08 67 |.M......h``n.K.g| + 00000130 74 e3 5a c9 ca 15 4f 86 92 c8 bc 34 3c c5 da a1 |t.Z...O....4<...| + 00000140 1b 75 18 f8 ec a1 98 70 22 81 fd ec e1 18 46 4a |.u.....p".....FJ| + 00000150 0c cf 9c 77 ec a1 b5 57 90 4c 79 8d b5 2a 56 fa |...w...W.Ly..*V.| + 00000160 a7 1b 07 05 d8 f3 0b 3b 34 6c ab 3d eb 3e 2e ec |.......;4l.=.>..| + 00000170 d9 8e 70 37 bc 47 86 b0 f3 22 e6 2e 72 10 b9 61 |..p7.G..."..r..a| + 00000180 ac 41 14 19 ca 3e 89 00 c7 a3 08 ba 04 ea 5c b1 |.A...>........\.| + 00000190 11 fd a2 98 7b 37 50 29 0c c9 25 a2 f1 0e 9f ac |....{7P)..%.....| + 000001a0 53 97 22 44 72 a2 b1 36 ed 9c 16 0f 0a f0 78 f3 |S."Dr..6......x.| + 000001b0 b1 61 1a d7 e8 30 ee 87 e4 1a 77 f0 11 ab 0d c5 |.a...0....w.....| + 000001c0 ef 0b 14 ef ee 15 5b 25 35 fd 53 32 db f8 0b 68 |......[%5.S2...h| + 000001d0 ae c7 c5 31 3f 6a 31 1c 63 65 03 49 a5 b4 48 e5 |...1?j1.ce.I..H.| + 000001e0 ac d5 66 a6 f8 20 fb 84 51 ee ee 6f a5 41 dc 1f |..f.. ..Q..o.A..| + 000001f0 27 3c 91 82 7c 87 8b c7 1d c6 2b c3 40 da 90 92 |'<..|.....+.@...| + 00000200 58 ea f9 ed 06 5e 25 e5 5a dd d8 35 bf 95 07 84 |X....^%.Z..5....| + 00000210 9e 9e f7 a7 de 08 de 2b 0f 68 75 de e5 7e 2d ef |.......+.hu..~-.| + 00000220 10 c4 51 96 bb e0 a8 93 39 a0 5e 86 2e 3f 01 8a |..Q.....9.^..?..| + 00000230 74 b8 3d b0 9c 2c 9b c2 2d e6 ce 64 ae cc f5 50 |t.=..,..-..d...P| + 00000240 a9 c5 c0 9c 49 fb 53 56 96 97 48 72 07 30 01 e0 |....I.SV..Hr.0..| + 00000250 a3 0b f7 2d 7d 12 e1 b6 e6 b3 f5 e7 da 21 b4 81 |...-}........!..| + 00000260 e0 0a d3 b4 4a 9d b7 96 9f 53 49 f3 62 1e 64 75 |....J....SI.b.du| + 00000270 f0 9f ef cb 4c b5 d4 2d 23 d2 9e 39 71 fc 17 8f |....L..-#..9q...| + 00000280 5a 9b c7 65 c1 4e c7 4f 6b c4 a8 e1 b8 51 d5 08 |Z..e.N.Ok....Q..| + 00000290 09 af 55 bf cf 7f a3 49 41 ea 0f 04 51 4b fd c5 |..U....IA...QK..| + 000002a0 94 ed 1e 10 64 12 9c 53 26 7b 62 f9 3c ff 25 17 |....d..S&{b.<.%.| + 000002b0 64 49 bf 78 85 9b e1 98 2a ed ca 5d 0f 47 57 3d |dI.x....*..].GW=| + 000002c0 04 83 78 12 fb 79 c7 5a 2c 70 9c 83 bf d2 a5 e5 |..x..y.Z,p......| + 000002d0 ee 9d 2e 46 17 42 23 35 18 29 4b d1 0d 7a 55 b0 |...F.B#5.)K..zU.| + 000002e0 76 da 38 5a 20 14 9f 19 e3 60 dd 8a b7 b7 72 4a |v.8Z ....`....rJ| + 000002f0 f8 e2 46 5f 4e 4e be db 86 03 26 72 53 d4 5d 25 |..F_NN....&rS.]%| + 00000300 fa ec b7 e2 7e 8b 0b ae c9 6d ee a6 0e 5b 80 90 |....~....m...[..| + 00000310 e1 c3 57 06 3f c3 5e 4f 6b c4 a8 e1 b8 51 d5 08 |..W.?.^Ok....Q..| + 00000320 09 af 55 bf cf 7f a3 15 43 d1 5a 4e 10 4e dd 5e |..U.....C.ZN.N.^| + 00000330 87 55 76 0e ce 9b 9f ea 56 87 73 b4 f5 5f 31 f8 |.Uv.....V.s.._1.| + 00000340 81 b2 c0 2d d1 84 22 3a fb f7 e5 2f 8c 74 03 fa |...-..":.../.t..| + 00000350 0b 97 e8 a8 92 21 23 cc 1a 7a 91 bc 33 ba ab dc |.....!#..z..3...| + 00000360 0d 09 22 af d3 a0 2a 8c 2c 48 53 72 a7 a2 0f 1f |.."...*.,HSr....| + 00000370 8c b5 ca a5 4b 62 3d c6 84 3f 9c 44 7c d9 f1 9c |....Kb=..?.D|...| + 00000380 8a fe d7 1b 83 ff f7 10 5b bd 1e 89 6a cd 91 c0 |........[...j...| + 00000390 3a 95 b6 d5 87 3b 8c 6e a9 4e e5 3f bd 90 9c 46 |:....;.n.N.?...F| + 000003a0 0a ef d3 02 e3 8d 5c 35 ba c9 24 4b 99 a2 fb 13 |......\5..$K....| + 000003b0 de bb 66 96 04 74 a1 76 73 50 41 54 70 5e 27 bb |..f..t.vsPATp^'.| + 000003c0 24 b6 ae ee 35 b4 a9 13 bb 04 60 13 e8 c8 f2 9f |$...5.....`.....| + 000003d0 f5 c7 36 27 81 b8 0b fb 7d 65 d1 7a 0f d9 3c 73 |..6'....}e.z..] + 00000000 e0 00 |..| + [mqtt <] + 00000000 20 09 02 00 06 22 00 0a 21 00 14 | ...."..!..| + [mqtt <] + 00000000 90 04 00 01 00 00 |......| + [local >] + 00000000 00 00 00 15 31 2e 30 00 00 00 01 00 00 23 8c 68 |....1.0......#.h| + 00000010 a6 a2 2c 00 00 b8 95 0e 86 |..,......| + [local <] + 00000000 00 00 00 27 31 2e 30 00 00 00 01 00 00 00 17 68 |...'1.0........h| + 00000010 a6 a2 2b 00 01 00 10 6d b9 48 37 ed 43 59 7a 90 |..+....m.H7.CYz.| + 00000020 ff 43 2f 0a 8f 81 44 e7 b6 b3 85 |.C/...D....| + [local >] + 00000000 00 00 00 77 31 2e 30 00 00 23 8e 00 00 23 8f 68 |...w1.0..#...#.h| + 00000010 a6 a2 2e 00 04 00 60 a9 a0 ac af 22 80 bb 11 b7 |......`...."....| + 00000020 e4 74 fa c3 0e bd c3 d5 a1 f9 a8 1d f1 4e 04 b9 |.t...........N..| + 00000030 05 50 39 bc b6 68 62 5b fc 54 1c ce ac c5 df ce |.P9..hb[.T......| + 00000040 93 8f 5c 61 d5 4c 66 8b c3 19 e0 cd b4 8f 63 be |..\a.Lf.......c.| + 00000050 2b c0 16 46 4e c8 e7 70 d3 a4 de 0f ac 57 5b e6 |+..FN..p.....W[.| + 00000060 79 84 2c ab 87 75 c7 7a d7 64 d6 51 3b 5a 04 85 |y.,..u.z.d.Q;Z..| + 00000070 38 a4 39 90 99 6f 4c 84 b5 1b ba |8.9..oL....| + [local <] + 00000000 00 00 04 27 31 2e 30 00 00 00 02 00 00 00 17 68 |...'1.0........h| + 00000010 a6 a2 2d 00 66 04 10 5e 5f 0b 3d ac 87 95 d7 72 |..-.f..^_.=....r| + 00000020 96 43 49 74 68 c3 35 e3 c7 bd 9d d2 41 b1 15 99 |.CIth.5.....A...| + 00000030 23 aa 66 a2 1a b7 54 da d3 d1 17 a7 d5 96 8c 29 |#.f...T........)| + 00000040 1e a0 17 b7 40 ed 89 49 70 0d f9 1e aa b0 68 73 |....@..Ip.....hs| + 00000050 6c 0e 82 1e 46 6b b7 7f 75 d6 7e b8 a9 4c d1 57 |l...Fk..u.~..L.W| + 00000060 42 95 10 c8 f1 d9 04 9e b9 2c b6 3f dd 1c e5 2f |B........,.?.../| + 00000070 08 1f 0f b7 e9 85 5a 34 4b 69 9b 6f 68 dd 45 74 |......Z4Ki.oh.Et| + 00000080 d4 bc c6 ad 11 07 98 9f fb aa 7b 67 96 2f 67 60 |..........{g./g`| + 00000090 e1 4b 2d 80 72 48 47 09 f0 c3 a2 65 a4 32 3b d2 |.K-.rHG....e.2;.| + 000000a0 02 ac 38 76 72 30 27 9d 75 d6 1a aa 05 e5 08 c5 |..8vr0'.u.......| + 000000b0 2e c4 3e ab 86 72 6b 61 ce d0 77 1e c4 6f 91 6f |..>..rka..w..o.o| + 000000c0 29 d3 19 89 45 21 6b 1e 7a 27 76 e1 1a 71 32 0f |)...E!k.z'v..q2.| + 000000d0 af bb 54 7d ea 30 19 e6 95 0b db 0b 88 0b eb 19 |..T}.0..........| + 000000e0 18 f1 03 80 3e 2d d3 dd 47 61 93 d1 5a b9 b1 13 |....>-..Ga..Z...| + 000000f0 c6 5c b1 f6 52 0a 94 6f 27 05 fe 67 80 3d 3a 51 |.\..R..o'..g.=:Q| + 00000100 d6 65 28 10 23 4f 42 9c d6 40 c3 3e c6 64 13 a8 |.e(.#OB..@.>.d..| + 00000110 c1 7d 13 17 d2 a0 a1 7b 6d 35 a5 62 73 75 f0 9b |.}.....{m5.bsu..| + 00000120 e9 32 96 62 14 0e 97 b3 73 b1 df 48 b4 4c 96 b1 |.2.b....s..H.L..| + 00000130 52 8d d5 5b 2f b2 21 f0 e6 81 9b e4 a3 68 11 6c |R..[/.!......h.l| + 00000140 bd d8 6c 4c ba a3 1a fd 12 4a c8 e1 39 ce 74 f5 |..lL.....J..9.t.| + 00000150 52 71 4d 28 f1 d4 8e a6 68 95 fb e2 b9 f6 62 10 |RqM(....h.....b.| + 00000160 a0 51 1b 44 13 53 71 1d 32 94 54 e8 d8 3a d9 d1 |.Q.D.Sq.2.T..:..| + 00000170 15 e3 f9 09 91 38 2a ba 4c e1 ca a8 6e 3f cf 38 |.....8*.L...n?.8| + 00000180 8a 8f 38 f7 da d1 b4 13 17 df 84 d4 74 0c 2a 65 |..8.........t.*e| + 00000190 64 96 ec 5e 9b fb 4d f5 eb ab e8 9a 91 ae 3b d1 |d..^..M.......;.| + 000001a0 ac 54 66 a1 18 65 92 f9 7c 67 a0 e2 d2 7e 79 3f |.Tf..e..|g...~y?| + 000001b0 5a 9d 31 8d f4 98 cd cf 1b c5 51 04 12 05 34 6c |Z.1.......Q...4l| + 000001c0 36 4e 9a 00 2b 10 9c 53 1f cf fe ff 28 d3 ab fe |6N..+..S....(...| + 000001d0 dc 7c 85 fb 23 06 00 58 2f 4d 36 fb 1b 04 76 a4 |.|..#..X/M6...v.| + 000001e0 7f 73 b8 58 b1 1a 22 2c e6 27 29 09 c7 48 72 f7 |.s.X..",.')..Hr.| + 000001f0 63 ce 7b ff 61 60 23 8a 92 06 a0 fa cc fd 6a d0 |c.{.a`#.......j.| + 00000200 13 e5 24 33 f7 2c c2 95 06 06 d8 c8 28 21 09 c9 |..$3.,......(!..| + 00000210 d8 d5 52 67 a6 81 68 80 00 f1 8b d9 dc bf 16 ea |..Rg..h.........| + 00000220 8f 76 2f bd 6e a8 89 77 94 d3 58 52 0e da aa 06 |.v/.n..w..XR....| + 00000230 2c 4d 35 89 23 45 8a 58 d0 b1 19 fb d4 05 da f0 |,M5.#E.X........| + 00000240 6f 2f 00 e5 11 85 4e 34 a8 55 13 39 a9 2a 46 75 |o/....N4.U.9.*Fu| + 00000250 52 e1 1f 66 e3 b8 2a 55 ab b0 ad ea 9b b6 4b 4d |R..f..*U......KM| + 00000260 9c 79 9b 09 d1 b6 61 48 89 37 b0 98 3c bf bb 4a |.y....aH.7..<..J| + 00000270 f1 22 e2 dd ad e6 3c 98 f6 d0 1f 14 c1 73 ed 7e |."....<......s.~| + 00000280 f8 9a fb 4e 64 e9 2f d9 f9 94 58 b1 f4 9d 67 13 |...Nd./...X...g.| + 00000290 6d 08 4b 6e 1b ca d6 76 02 3f b0 2c fc 0b 0b 32 |m.Kn...v.?.,...2| + 000002a0 ce 38 a1 05 86 d3 db ce dd 06 63 49 e8 c1 d1 41 |.8........cI...A| + 000002b0 00 e0 3b 0a ed 7b 7a b1 04 86 a8 bb 1b 18 52 63 |..;..{z.......Rc| + 000002c0 db 42 2a c3 41 d8 1c 3c 31 ef 6b 72 7e c2 54 a5 |.B*.A..<1.kr~.T.| + 000002d0 20 94 23 b9 8d d0 5e 94 ef 85 b0 73 47 5d 7c f0 | .#...^....sG]|.| + 000002e0 ef ac 82 55 13 04 ba ca 4f 1b af fb 5c 0c b9 e7 |...U....O...\...| + 000002f0 21 c7 97 75 d3 db 18 51 d1 92 5c 51 97 8a ba 3e |!..u...Q..\Q...>| + 00000300 79 80 5c c9 21 8f 6b 8f 04 9e 9a 47 ed ef fe 66 |y.\.!.k....G...f| + 00000310 fe d3 76 5b ff dc 31 d9 f9 94 58 b1 f4 9d 67 13 |..v[..1...X...g.| + 00000320 6d 08 4b 6e 1b ca d6 7f 0c de c5 f4 a5 0f 49 cf |m.Kn..........I.| + 00000330 f9 e5 74 88 96 8a 14 bd 8a 19 0a ce 93 be 30 b8 |..t...........0.| + 00000340 35 1a 1e bb f3 0b ed 34 28 7f 73 ca 76 4a 8d 03 |5......4(.s.vJ..| + 00000350 81 0a 2c 2c cc fe e8 c6 e2 dd 9d e0 be 45 63 57 |..,,.........EcW| + 00000360 ae 34 40 e1 c4 5c 2b ee 40 68 5e d0 35 83 94 ce |.4@..\+.@h^.5...| + 00000370 be 2a 27 08 a5 dc 00 d5 b6 af 48 b3 6b 57 99 80 |.*'.......H.kW..| + 00000380 ba e8 2d 7e b5 57 4e 91 5e 15 7a 13 af 9d ed 24 |..-~.WN.^.z....$| + 00000390 03 6a 35 fb 75 b0 56 36 90 70 ff 59 f9 3f dd 7e |.j5.u.V6.p.Y.?.~| + 000003a0 09 1b 05 a1 38 dc 1c 12 5b 9c 4d 82 b2 32 95 1f |....8...[.M..2..| + 000003b0 80 4f 29 53 51 9f b3 12 72 1a b4 b9 79 d5 7b 74 |.O)SQ...r...y.{t| + 000003c0 99 94 71 90 83 b5 51 1a 47 4e 99 ae 54 78 98 fe |..q...Q.GN..Tx..| + 000003d0 38 91 1e 5e 67 72 1b f1 b8 7d 66 83 55 21 94 7c |8..^gr...}f.U!.|| + 000003e0 d6 79 8b 61 65 0e 0d 46 c4 3b 6f e8 0e f2 ec 4b |.y.ae..F.;o....K| + 000003f0 b6 60 24 40 83 2b 94 06 de a8 88 76 d6 c4 7b 17 |.`$@.+.....v..{.| + 00000400 77 50 dd e5 02 1f 70 86 1b f5 f5 56 19 5e 54 00 |wP....p....V.^T.| + 00000410 cc 52 61 40 f9 d5 02 3c dd 7d 66 3a 06 89 a0 7a |.Ra@...<.}f:...z| + 00000420 98 80 37 eb 64 ea ee b2 82 5a 2a |..7.d....Z*| +# --- diff --git a/tests/e2e/test_device_manager.py b/tests/e2e/test_device_manager.py new file mode 100644 index 00000000..c6364819 --- /dev/null +++ b/tests/e2e/test_device_manager.py @@ -0,0 +1,347 @@ +"""End-to-end tests for MQTT session. + +These tests use a fake MQTT broker to verify the session implementation. We +mock out the lower level socket connections to simulate a broker which gets us +close to an "end to end" test without needing an actual MQTT broker server. + +These are higher level tests that the similar tests in tests/mqtt/test_roborock_session.py +which use mocks to verify specific behaviors. +""" + +import asyncio +import json +from collections.abc import AsyncGenerator, Awaitable, Callable +from typing import Any + +import pytest +import syrupy + +from roborock.data.containers import UserData +from roborock.devices.cache import Cache, InMemoryCache +from roborock.devices.device_manager import DeviceManager, UserParams, create_device_manager +from roborock.protocol import MessageParser +from roborock.protocols.v1_protocol import LocalProtocolVersion +from roborock.roborock_message import RoborockMessage, RoborockMessageProtocol +from roborock.web_api import RoborockApiClient +from tests import mock_data, mqtt_packet +from tests.fixtures.logging import CapturedRequestLog +from tests.mock_data import LOCAL_KEY + +TEST_USERNAME = "user@example.com" +TEST_CODE = 1234 + +# The topic used for the user + device. This is determined from the fake Home +# data API response. +TEST_TOPIC = "rr/m/o/user123/19648f94/abc123" +TEST_RANDOM = 23 +TEST_HOST = mock_data.TEST_LOCAL_API_HOST +NETWORK_INFO = { + "ip": TEST_HOST, + "ssid": "test_wifi", + "mac": "aa:bb:cc:dd:ee:ff", + "bssid": "aa:bb:cc:dd:ee:ff", + "rssi": -50, +} + + +@pytest.fixture(autouse=True) +def auto_mock_mqtt_client(mock_aiomqtt_client: None) -> None: + """Automatically use the mock mqtt client fixture.""" + + +@pytest.fixture(autouse=True) +def auto_fast_backoff(fast_backoff_fixture: None) -> None: + """Automatically use the fast backoff fixture.""" + + +@pytest.fixture(autouse=True) +def mqtt_server_fixture(mock_paho_mqtt_create_connection: None, mock_paho_mqtt_select: None) -> None: + """Fixture to mock the MQTT connection. + + This is here to pull in the mock socket fixtures into all tests used here. + """ + + +@pytest.fixture(autouse=True) +def auto_mock_local_client(mock_async_create_local_connection: None) -> None: + """Automatically use the mock local client fixture.""" + + +@pytest.fixture(name="device_manager_factory") +async def device_manager_factory_fixture() -> AsyncGenerator[Callable[[UserParams], Awaitable[DeviceManager]], None]: + """Fixture to create a device manager and handle auto shutdown on test failure.""" + + cleanup_tasks: list[Callable[[], Awaitable[None]]] = [] + cache: Cache = InMemoryCache() + + async def factory(user_params: UserParams) -> DeviceManager: + """Create a device manager and auto cleanup.""" + device_manager = await create_device_manager(user_params, cache=cache) + cleanup_tasks.append(device_manager.close) + return device_manager + + yield factory + + await asyncio.gather(*[task() for task in cleanup_tasks]) + + +class ResponseBuilder: + """Utility class to build raw response messages. + + This helps keep track of sequence numbers and timestamps mostly to remove + them from the main test body. These are mostly ignored by the client in the + response. + """ + + def __init__(self) -> None: + """Initialize the response builder.""" + self.seq_counter = 0 + self.timestamp_counter = 1766520441 + self.connect_nonce: int | None = None + self.ack_nonce: int | None = None + self.protocol = RoborockMessageProtocol.RPC_RESPONSE + self.version = LocalProtocolVersion.V1 + + def build( + self, + payload: bytes, + protocol: RoborockMessageProtocol | None = None, + ) -> bytes: + """Build an encoded response message.""" + self.seq_counter += 1 + return MessageParser.build( + RoborockMessage( + protocol=protocol if protocol is not None else self.protocol, + random=TEST_RANDOM, + seq=self.seq_counter, + payload=payload, + version=self.version.value.encode(), + ), + local_key=LOCAL_KEY, + connect_nonce=self.connect_nonce, + ack_nonce=self.ack_nonce, + ) + + def build_rpc( + self, + data: dict[str, Any], + protocol: RoborockMessageProtocol | None = None, + ) -> bytes: + """Build an encoded RPC response message.""" + self.timestamp_counter += 1 + return self.build( + payload=json.dumps( + { + "t": self.timestamp_counter, + "dps": { + "102": json.dumps(data), + }, + } + ).encode(), + protocol=protocol, + ) + + +async def test_v1_device( + mock_rest: Any, + push_mqtt_response: Callable[[bytes], None], + local_response_queue: asyncio.Queue[bytes], + local_received_requests: asyncio.Queue[bytes], + log: CapturedRequestLog, + snapshot: syrupy.SnapshotAssertion, + device_manager_factory: Callable[[UserParams], Awaitable[DeviceManager]], +) -> None: + """Test the device manager end to end flow with a v1 device.""" + + # Simulate the login flow to get user params + web_api = RoborockApiClient(username=TEST_USERNAME) + await web_api.request_code() + user_data = await web_api.code_login(TEST_CODE) + + # Prepare MQTT requests + response_builder = ResponseBuilder() + mqtt_responses: list[bytes] = [ + # MQTT connection response + mqtt_packet.gen_connack(rc=0, flags=2), + # ACK the request to subscribe to the topic + mqtt_packet.gen_suback(mid=1), + # ACK the GET_NETWORK_INFO call. id is deterministic based on deterministic_message_fixtures + mqtt_packet.gen_publish( + TEST_TOPIC, mid=2, payload=response_builder.build_rpc(data={"id": 9090, "result": NETWORK_INFO}) + ), + ] + for response in mqtt_responses: + push_mqtt_response(response) + + # Prepare local device responses. The ids are deterministic based on deterministic_message_fixtures + response_builder.seq_counter = 0 + local_responses: list[bytes] = [ + # Queue HELLO response + response_builder.build(protocol=RoborockMessageProtocol.HELLO_RESPONSE, payload=b"ok"), + # Feature discovery part 1 & 2 + response_builder.build_rpc(data={"id": 9094, "result": [mock_data.APP_GET_INIT_STATUS]}), + response_builder.build_rpc(data={"id": 9097, "result": [mock_data.STATUS]}), + ] + for payload in local_responses: + local_response_queue.put_nowait(payload) + + # Create the device manager + user_params = UserParams( + username=TEST_USERNAME, + user_data=user_data, + base_url=await web_api.base_url, + ) + device_manager = await device_manager_factory(user_params) + + # The mocked Home Data API returns a single v1 device + devices = await device_manager.get_devices() + assert len(devices) == 1 + device = devices[0] + assert device.duid == "abc123" + assert device.name == "Roborock S7 MaxV" + assert device.is_connected + assert device.is_local_connected + + # Verify GET_STATUS response based on mock_data.STATUS + assert device.v1_properties + assert device.v1_properties.status + assert device.v1_properties.status.state_name == "charging" + assert device.v1_properties.status.battery == 100 + assert device.v1_properties.status.clean_time == 1176 + + # Verify arbitrary device features + assert device.v1_properties.device_features.is_show_clean_finish_reason_supported + assert device.v1_properties.device_features.is_customized_clean_supported + assert not device.v1_properties.device_features.is_matter_supported + + # Close the device manager. We will test re-connecting and reusing the network + # information and device discovery information from the cache. + await device_manager.close() + + mqtt_responses = [ + # MQTT connection response + mqtt_packet.gen_connack(rc=0, flags=2), + # ACK the request to subscribe to the topic + mqtt_packet.gen_suback(mid=1), + # No network info call this time since it should be cached + ] + for response in mqtt_responses: + push_mqtt_response(response) + + # Prepare local device responses. + response_builder.seq_counter = 0 + local_response_queue.put_nowait( + response_builder.build(protocol=RoborockMessageProtocol.HELLO_RESPONSE, payload=b"ok") + ) + + device_manager = await device_manager_factory(user_params) + + # The mocked Home Data API returns a single v1 device + devices = await device_manager.get_devices() + assert len(devices) == 1 + device = devices[0] + assert device.duid == "abc123" + assert device.name == "Roborock S7 MaxV" + assert device.is_connected + assert device.is_local_connected + + # Verify arbitrary device features from cache + assert device.v1_properties + assert device.v1_properties.device_features + assert device.v1_properties.device_features.is_show_clean_finish_reason_supported + assert device.v1_properties.device_features.is_customized_clean_supported + assert not device.v1_properties.device_features.is_matter_supported + + # In the previous test, the dock information is fetched and has the side effect of + # populating the status trait. This test gets dock information from the cache so + # we have to manually refresh status the first time (like other traits). + assert device.v1_properties + assert device.v1_properties.status + assert device.v1_properties.status.state_name is None + + # Exercise a GET_STATUS call. id is deterministic based on deterministic_message_fixtures + local_response_queue.put_nowait(response_builder.build_rpc(data={"id": 9101, "result": [mock_data.STATUS]})) + + # Verify GET_STATUS response + await device.v1_properties.status.refresh() + assert device.v1_properties.status.state_name == "charging" + + assert snapshot == log + + +async def test_l01_device( + mock_rest: Any, + push_mqtt_response: Callable[[bytes], None], + local_response_queue: asyncio.Queue[bytes], + local_received_requests: asyncio.Queue[bytes], + log: CapturedRequestLog, + snapshot: syrupy.SnapshotAssertion, + device_manager_factory: Callable[[UserParams], Awaitable[DeviceManager]], +) -> None: + """Test the device manager end to end flow with a l01 device.""" + # Prepare MQTT requests + mqtt_response_builder = ResponseBuilder() + mqtt_responses: list[bytes] = [ + # MQTT connection response + mqtt_packet.gen_connack(rc=0, flags=2), + # ACK the request to subscribe to the topic + mqtt_packet.gen_suback(mid=1), + # ACK the GET_NETWORK_INFO call. id is deterministic based on deterministic_message_fixtures + mqtt_packet.gen_publish( + TEST_TOPIC, mid=2, payload=mqtt_response_builder.build_rpc(data={"id": 9090, "result": NETWORK_INFO}) + ), + ] + for response in mqtt_responses: + push_mqtt_response(response) + + # Prepare local device responses. The ids are deterministic based on deterministic_message_fixtures + local_response_builder = ResponseBuilder() + local_response_builder.version = LocalProtocolVersion.L01 + local_response_builder.connect_nonce = 9093 + local_responses: list[bytes] = [ + # Initial V01 Hello request will fail and cause a retry with L01 + b"\x00", + # Queue HELLO response with L01 + local_response_builder.build(protocol=RoborockMessageProtocol.HELLO_RESPONSE, payload=b"ok"), + ] + # Feature discovery requests are sent with an ack nonce based on the random sent in HELLO_RESPONSE + local_response_builder.ack_nonce = TEST_RANDOM + local_responses.extend( + [ + local_response_builder.build_rpc(data={"id": 9094, "result": [mock_data.APP_GET_INIT_STATUS]}), + local_response_builder.build_rpc(data={"id": 9097, "result": [mock_data.STATUS]}), + ] + ) + for payload in local_responses: + local_response_queue.put_nowait(payload) + + # Create the device manager + user_params = UserParams( + username=TEST_USERNAME, + user_data=UserData.from_dict(mock_data.USER_DATA), + base_url=mock_data.BASE_URL, + ) + device_manager = await device_manager_factory(user_params) + + # The mocked Home Data API returns a single v1 device + devices = await device_manager.get_devices() + assert len(devices) == 1 + device = devices[0] + assert device.duid == "abc123" + assert device.name == "Roborock S7 MaxV" + assert device.is_connected + assert device.is_local_connected + + # Verify GET_STATUS response based on mock_data.STATUS + assert device.v1_properties + assert device.v1_properties.status + assert device.v1_properties.status.state_name == "charging" + assert device.v1_properties.status.battery == 100 + assert device.v1_properties.status.clean_time == 1176 + + # Verify arbitrary device features + assert device.v1_properties.device_features.is_show_clean_finish_reason_supported + assert device.v1_properties.device_features.is_customized_clean_supported + assert not device.v1_properties.device_features.is_matter_supported + + assert snapshot == log diff --git a/tests/fixtures/web_api_fixtures.py b/tests/fixtures/web_api_fixtures.py index 0b071387..3d5726d3 100644 --- a/tests/fixtures/web_api_fixtures.py +++ b/tests/fixtures/web_api_fixtures.py @@ -62,6 +62,11 @@ def mock_rest_fixture(skip_rate_limit: Any) -> aioresponses: status=200, payload={"api": None, "code": 200, "result": HOME_DATA_RAW, "status": "ok", "success": True}, ) + mocked.get( + re.compile(r"https://api-.*\.roborock\.com/v3/user/homes*"), + status=200, + payload={"api": None, "code": 200, "result": HOME_DATA_RAW, "status": "ok", "success": True}, + ) mocked.post( re.compile(r"https://api-.*\.roborock\.com/nc/prepare"), status=200,