commit c2aa1e15c78cd5451a92419c0387b0dcbe64394b Author: Alex Janka Date: Thu Feb 15 15:15:01 2024 +1100 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2712914 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/test-data diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..f89f74a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,686 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" + +[[package]] +name = "homekit-controller" +version = "0.1.0" +dependencies = [ + "log", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "homekit-exporter" +version = "0.1.0" +dependencies = [ + "clap", + "env_logger", + "homekit-controller", + "log", + "tokio", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..56d3182 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,4 @@ +[workspace] +members = ["homekit-controller", "homekit-exporter"] +default-members = ["homekit-exporter"] +resolver = "2" diff --git a/homekit-controller/Cargo.toml b/homekit-controller/Cargo.toml new file mode 100644 index 0000000..9da6103 --- /dev/null +++ b/homekit-controller/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "homekit-controller" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +thiserror = "1.0" +log = "0.4" diff --git a/homekit-controller/src/characteristics.rs b/homekit-controller/src/characteristics.rs new file mode 100644 index 0000000..580589b --- /dev/null +++ b/homekit-controller/src/characteristics.rs @@ -0,0 +1,1286 @@ +use serde::{Deserialize, Deserializer, Serialize}; + +// data from https://github.com/oznu/homebridge-gsh/blob/master/src/hap-types.ts + +pub(crate) fn deserialize_characteristic_type<'de, D>( + deserializer: D, +) -> Result +where + D: Deserializer<'de>, +{ + CharacteristicTypeInner::deserialize(deserializer).map(|v| v.into()) +} + +#[derive(Serialize, Deserialize, Debug, Clone)] + +pub enum CharacteristicType { + AccessControlLevel, + AccessoryFlags, + ProductData, + Active, + AdministratorOnlyAccess, + AirParticulateDensity, + AirParticulateSize, + AirQuality, + AudioFeedback, + BatteryLevel, + Brightness, + CarbonDioxideDetected, + CarbonDioxideLevel, + CarbonDioxidePeakLevel, + CarbonMonoxideDetected, + CarbonMonoxideLevel, + CarbonMonoxidePeakLevel, + ChargingState, + ColorTemperature, + ContactSensorState, + CoolingThresholdTemperature, + CurrentAirPurifierState, + CurrentAmbientLightLevel, + CurrentDoorState, + CurrentFanState, + CurrentHeaterCoolerState, + CurrentHeatingCoolingState, + CurrentHorizontalTiltAngle, + CurrentHumidifierDehumidifierState, + CurrentPosition, + CurrentRelativeHumidity, + CurrentSlatState, + CurrentTemperature, + CurrentTiltAngle, + CurrentVerticalTiltAngle, + DigitalZoom, + FilterChangeIndication, + FilterLifeLevel, + FirmwareRevision, + HardwareRevision, + HeatingThresholdTemperature, + HoldPosition, + Hue, + Identify, + ImageMirroring, + ImageRotation, + InUse, + IsConfigured, + LeakDetected, + LockControlPoint, + LockCurrentState, + LockLastKnownAction, + LockManagementAutoSecurityTimeout, + LockPhysicalControls, + LockTargetState, + Logs, + Manufacturer, + Model, + MotionDetected, + Mute, + Name, + NightVision, + NitrogenDioxideDensity, + ObstructionDetected, + OccupancyDetected, + On, + OpticalZoom, + OutletInUse, + OzoneDensity, + PairSetup, + PairVerify, + PairingFeatures, + PairingPairings, + PasswordSetting, + PM10Density, + PM2_5Density, + PositionState, + ProgramMode, + ProgrammableSwitchEvent, + RelativeHumidityDehumidifierThreshold, + RelativeHumidityHumidifierThreshold, + RemainingDuration, + ResetFilterIndication, + RotationDirection, + RotationSpeed, + Saturation, + SecuritySystemAlarmType, + SecuritySystemCurrentState, + SecuritySystemTargetState, + SelectedRTPStreamConfiguration, + SerialNumber, + ServiceLabelIndex, + ServiceLabelNamespace, + SetDuration, + SetupEndpoints, + SlatType, + SmokeDetected, + StatusActive, + StatusFault, + StatusJammed, + StatusLowBattery, + StatusTampered, + StreamingStatus, + SulphurDioxideDensity, + SupportedAudioStreamConfiguration, + SupportedRTPConfiguration, + SupportedVideoStreamConfiguration, + SwingMode, + TargetAirPurifierState, + TargetAirQuality, + TargetDoorState, + TargetFanState, + TargetHeaterCoolerState, + TargetHeatingCoolingState, + TargetHorizontalTiltAngle, + TargetHumidifierDehumidifierState, + TargetPosition, + TargetRelativeHumidity, + TargetSlatState, + TargetTemperature, + TargetTiltAngle, + TargetVerticalTiltAngle, + TemperatureDisplayUnits, + ValveType, + Version, + VOCDensity, + Volume, + WaterLevel, + RecordingAudioActive, + SupportedCameraRecordingConfiguration, + SupportedVideoRecordingConfiguration, + SupportedAudioRecordingConfiguration, + SelectedCameraRecordingConfiguration, + CameraOperatingModeIndicator, + EventSnapshotsActive, + DiagonalFieldOfView, + HomeKitCameraActive, + ManuallyDisabled, + ThirdPartyCameraActive, + PeriodicSnapshotsActive, + NetworkClientProfileControl, + NetworkClientStatusControl, + RouterStatus, + SupportedRouterConfiguration, + WANConfigurationList, + WANStatusList, + ManagedNetworkEnable, + NetworkAccessViolationControl, + WiFiSatelliteStatus, + WakeConfiguration, + SupportedTransferTransportConfiguration, + SetupTransferTransport, + ActivityInterval, + CCAEnergyDetectThreshold, + CCASignalDetectThreshold, + CharacteristicValueTransitionControl, + SupportedCharacteristicValueTransitionConfiguration, + CurrentTransport, + DataStreamHAPTransport, + DataStreamHAPTransportInterrupt, + EventRetransmissionMaximum, + EventTransmissionCounters, + HeartBeat, + MACRetransmissionMaximum, + MACTransmissionCounters, + OperatingStateResponse, + Ping, + ReceiverSensitivity, + ReceivedSignalStrengthIndication, + SleepInterval, + SignalToNoiseRatio, + SupportedDiagnosticsSnapshot, + TransmitPower, + TransmitPowerMaximum, + VideoAnalysisActive, + WiFiCapabilities, + WiFiConfigurationControl, + AppMatchingIdentifier, + ProgrammableSwitchOutputState, + SoftwareRevision, + AccessoryIdentifier, + Category, + ConfigureBridgedAccessory, + ConfigureBridgedAccessoryStatus, + CurrentTime, + DayoftheWeek, + DiscoverBridgedAccessories, + DiscoveredBridgedAccessories, + LinkQuality, + Reachable, + RelayControlPoint, + RelayEnabled, + RelayState, + TimeUpdate, + TunnelConnectionTimeout, + TunneledAccessoryAdvertising, + TunneledAccessoryConnected, + TunneledAccessoryStateNumber, + ActiveIdentifier, + ConfiguredName, + SleepDiscoveryMode, + ClosedCaptions, + DisplayOrder, + CurrentMediaState, + TargetMediaState, + PictureMode, + PowerModeSelection, + RemoteKey, + InputSourceType, + InputDeviceType, + Identifier, + CurrentVisibilityState, + TargetVisibilityState, + VolumeControlType, + VolumeSelector, + TargetControlSupportedConfiguration, + TargetControlList, + ButtonEvent, + SelectedAudioStreamConfiguration, + SiriInputType, + SupportedDataStreamTransportConfiguration, + SetupDataStreamTransport, + Unknown, +} + +#[derive(Deserialize)] +#[serde(field_identifier)] +enum CharacteristicTypeInner { + #[serde(rename = "000000E5-0000-1000-8000-0026BB765291")] + AccessControlLevel, + #[serde(rename = "000000A6-0000-1000-8000-0026BB765291")] + AccessoryFlags, + #[serde(rename = "00000220-0000-1000-8000-0026BB765291")] + ProductData, + #[serde(rename = "000000B0-0000-1000-8000-0026BB765291")] + Active, + #[serde(rename = "00000001-0000-1000-8000-0026BB765291")] + AdministratorOnlyAccess, + #[serde(rename = "00000064-0000-1000-8000-0026BB765291")] + AirParticulateDensity, + #[serde(rename = "00000065-0000-1000-8000-0026BB765291")] + AirParticulateSize, + #[serde(rename = "00000095-0000-1000-8000-0026BB765291")] + AirQuality, + #[serde(rename = "00000005-0000-1000-8000-0026BB765291")] + AudioFeedback, + #[serde(rename = "00000068-0000-1000-8000-0026BB765291")] + BatteryLevel, + #[serde(rename = "00000008-0000-1000-8000-0026BB765291")] + Brightness, + #[serde(rename = "00000092-0000-1000-8000-0026BB765291")] + CarbonDioxideDetected, + #[serde(rename = "00000093-0000-1000-8000-0026BB765291")] + CarbonDioxideLevel, + #[serde(rename = "00000094-0000-1000-8000-0026BB765291")] + CarbonDioxidePeakLevel, + #[serde(rename = "00000069-0000-1000-8000-0026BB765291")] + CarbonMonoxideDetected, + #[serde(rename = "00000090-0000-1000-8000-0026BB765291")] + CarbonMonoxideLevel, + #[serde(rename = "00000091-0000-1000-8000-0026BB765291")] + CarbonMonoxidePeakLevel, + #[serde(rename = "0000008F-0000-1000-8000-0026BB765291")] + ChargingState, + #[serde(rename = "000000CE-0000-1000-8000-0026BB765291")] + ColorTemperature, + #[serde(rename = "0000006A-0000-1000-8000-0026BB765291")] + ContactSensorState, + #[serde(rename = "0000000D-0000-1000-8000-0026BB765291")] + CoolingThresholdTemperature, + #[serde(rename = "000000A9-0000-1000-8000-0026BB765291")] + CurrentAirPurifierState, + #[serde(rename = "0000006B-0000-1000-8000-0026BB765291")] + CurrentAmbientLightLevel, + #[serde(rename = "0000000E-0000-1000-8000-0026BB765291")] + CurrentDoorState, + #[serde(rename = "000000AF-0000-1000-8000-0026BB765291")] + CurrentFanState, + #[serde(rename = "000000B1-0000-1000-8000-0026BB765291")] + CurrentHeaterCoolerState, + #[serde(rename = "0000000F-0000-1000-8000-0026BB765291")] + CurrentHeatingCoolingState, + #[serde(rename = "0000006C-0000-1000-8000-0026BB765291")] + CurrentHorizontalTiltAngle, + #[serde(rename = "000000B3-0000-1000-8000-0026BB765291")] + CurrentHumidifierDehumidifierState, + #[serde(rename = "0000006D-0000-1000-8000-0026BB765291")] + CurrentPosition, + #[serde(rename = "00000010-0000-1000-8000-0026BB765291")] + CurrentRelativeHumidity, + #[serde(rename = "000000AA-0000-1000-8000-0026BB765291")] + CurrentSlatState, + #[serde(rename = "00000011-0000-1000-8000-0026BB765291")] + CurrentTemperature, + #[serde(rename = "000000C1-0000-1000-8000-0026BB765291")] + CurrentTiltAngle, + #[serde(rename = "0000006E-0000-1000-8000-0026BB765291")] + CurrentVerticalTiltAngle, + #[serde(rename = "0000011D-0000-1000-8000-0026BB765291")] + DigitalZoom, + #[serde(rename = "000000AC-0000-1000-8000-0026BB765291")] + FilterChangeIndication, + #[serde(rename = "000000AB-0000-1000-8000-0026BB765291")] + FilterLifeLevel, + #[serde(rename = "00000052-0000-1000-8000-0026BB765291")] + FirmwareRevision, + #[serde(rename = "00000053-0000-1000-8000-0026BB765291")] + HardwareRevision, + #[serde(rename = "00000012-0000-1000-8000-0026BB765291")] + HeatingThresholdTemperature, + #[serde(rename = "0000006F-0000-1000-8000-0026BB765291")] + HoldPosition, + #[serde(rename = "00000013-0000-1000-8000-0026BB765291")] + Hue, + #[serde(rename = "00000014-0000-1000-8000-0026BB765291")] + Identify, + #[serde(rename = "0000011F-0000-1000-8000-0026BB765291")] + ImageMirroring, + #[serde(rename = "0000011E-0000-1000-8000-0026BB765291")] + ImageRotation, + #[serde(rename = "000000D2-0000-1000-8000-0026BB765291")] + InUse, + #[serde(rename = "000000D6-0000-1000-8000-0026BB765291")] + IsConfigured, + #[serde(rename = "00000070-0000-1000-8000-0026BB765291")] + LeakDetected, + #[serde(rename = "00000019-0000-1000-8000-0026BB765291")] + LockControlPoint, + #[serde(rename = "0000001D-0000-1000-8000-0026BB765291")] + LockCurrentState, + #[serde(rename = "0000001C-0000-1000-8000-0026BB765291")] + LockLastKnownAction, + #[serde(rename = "0000001A-0000-1000-8000-0026BB765291")] + LockManagementAutoSecurityTimeout, + #[serde(rename = "000000A7-0000-1000-8000-0026BB765291")] + LockPhysicalControls, + #[serde(rename = "0000001E-0000-1000-8000-0026BB765291")] + LockTargetState, + #[serde(rename = "0000001F-0000-1000-8000-0026BB765291")] + Logs, + #[serde(rename = "00000020-0000-1000-8000-0026BB765291")] + Manufacturer, + #[serde(rename = "00000021-0000-1000-8000-0026BB765291")] + Model, + #[serde(rename = "00000022-0000-1000-8000-0026BB765291")] + MotionDetected, + #[serde(rename = "0000011A-0000-1000-8000-0026BB765291")] + Mute, + #[serde(rename = "00000023-0000-1000-8000-0026BB765291")] + Name, + #[serde(rename = "0000011B-0000-1000-8000-0026BB765291")] + NightVision, + #[serde(rename = "000000C4-0000-1000-8000-0026BB765291")] + NitrogenDioxideDensity, + #[serde(rename = "00000024-0000-1000-8000-0026BB765291")] + ObstructionDetected, + #[serde(rename = "00000071-0000-1000-8000-0026BB765291")] + OccupancyDetected, + #[serde(rename = "00000025-0000-1000-8000-0026BB765291")] + On, + #[serde(rename = "0000011C-0000-1000-8000-0026BB765291")] + OpticalZoom, + #[serde(rename = "00000026-0000-1000-8000-0026BB765291")] + OutletInUse, + #[serde(rename = "000000C3-0000-1000-8000-0026BB765291")] + OzoneDensity, + #[serde(rename = "0000004C-0000-1000-8000-0026BB765291")] + PairSetup, + #[serde(rename = "0000004E-0000-1000-8000-0026BB765291")] + PairVerify, + #[serde(rename = "0000004F-0000-1000-8000-0026BB765291")] + PairingFeatures, + #[serde(rename = "00000050-0000-1000-8000-0026BB765291")] + PairingPairings, + #[serde(rename = "000000E4-0000-1000-8000-0026BB765291")] + PasswordSetting, + #[serde(rename = "000000C7-0000-1000-8000-0026BB765291")] + PM10Density, + #[serde(rename = "000000C6-0000-1000-8000-0026BB765291")] + PM2_5Density, + #[serde(rename = "00000072-0000-1000-8000-0026BB765291")] + PositionState, + #[serde(rename = "000000D1-0000-1000-8000-0026BB765291")] + ProgramMode, + #[serde(rename = "00000073-0000-1000-8000-0026BB765291")] + ProgrammableSwitchEvent, + #[serde(rename = "000000C9-0000-1000-8000-0026BB765291")] + RelativeHumidityDehumidifierThreshold, + #[serde(rename = "000000CA-0000-1000-8000-0026BB765291")] + RelativeHumidityHumidifierThreshold, + #[serde(rename = "000000D4-0000-1000-8000-0026BB765291")] + RemainingDuration, + #[serde(rename = "000000AD-0000-1000-8000-0026BB765291")] + ResetFilterIndication, + #[serde(rename = "00000028-0000-1000-8000-0026BB765291")] + RotationDirection, + #[serde(rename = "00000029-0000-1000-8000-0026BB765291")] + RotationSpeed, + #[serde(rename = "0000002F-0000-1000-8000-0026BB765291")] + Saturation, + #[serde(rename = "0000008E-0000-1000-8000-0026BB765291")] + SecuritySystemAlarmType, + #[serde(rename = "00000066-0000-1000-8000-0026BB765291")] + SecuritySystemCurrentState, + #[serde(rename = "00000067-0000-1000-8000-0026BB765291")] + SecuritySystemTargetState, + #[serde(rename = "00000117-0000-1000-8000-0026BB765291")] + SelectedRTPStreamConfiguration, + #[serde(rename = "00000030-0000-1000-8000-0026BB765291")] + SerialNumber, + #[serde(rename = "000000CB-0000-1000-8000-0026BB765291")] + ServiceLabelIndex, + #[serde(rename = "000000CD-0000-1000-8000-0026BB765291")] + ServiceLabelNamespace, + #[serde(rename = "000000D3-0000-1000-8000-0026BB765291")] + SetDuration, + #[serde(rename = "00000118-0000-1000-8000-0026BB765291")] + SetupEndpoints, + #[serde(rename = "000000C0-0000-1000-8000-0026BB765291")] + SlatType, + #[serde(rename = "00000076-0000-1000-8000-0026BB765291")] + SmokeDetected, + #[serde(rename = "00000075-0000-1000-8000-0026BB765291")] + StatusActive, + #[serde(rename = "00000077-0000-1000-8000-0026BB765291")] + StatusFault, + #[serde(rename = "00000078-0000-1000-8000-0026BB765291")] + StatusJammed, + #[serde(rename = "00000079-0000-1000-8000-0026BB765291")] + StatusLowBattery, + #[serde(rename = "0000007A-0000-1000-8000-0026BB765291")] + StatusTampered, + #[serde(rename = "00000120-0000-1000-8000-0026BB765291")] + StreamingStatus, + #[serde(rename = "000000C5-0000-1000-8000-0026BB765291")] + SulphurDioxideDensity, + #[serde(rename = "00000115-0000-1000-8000-0026BB765291")] + SupportedAudioStreamConfiguration, + #[serde(rename = "00000116-0000-1000-8000-0026BB765291")] + SupportedRTPConfiguration, + #[serde(rename = "00000114-0000-1000-8000-0026BB765291")] + SupportedVideoStreamConfiguration, + #[serde(rename = "000000B6-0000-1000-8000-0026BB765291")] + SwingMode, + #[serde(rename = "000000A8-0000-1000-8000-0026BB765291")] + TargetAirPurifierState, + #[serde(rename = "000000AE-0000-1000-8000-0026BB765291")] + TargetAirQuality, + #[serde(rename = "00000032-0000-1000-8000-0026BB765291")] + TargetDoorState, + #[serde(rename = "000000BF-0000-1000-8000-0026BB765291")] + TargetFanState, + #[serde(rename = "000000B2-0000-1000-8000-0026BB765291")] + TargetHeaterCoolerState, + #[serde(rename = "00000033-0000-1000-8000-0026BB765291")] + TargetHeatingCoolingState, + #[serde(rename = "0000007B-0000-1000-8000-0026BB765291")] + TargetHorizontalTiltAngle, + #[serde(rename = "000000B4-0000-1000-8000-0026BB765291")] + TargetHumidifierDehumidifierState, + #[serde(rename = "0000007C-0000-1000-8000-0026BB765291")] + TargetPosition, + #[serde(rename = "00000034-0000-1000-8000-0026BB765291")] + TargetRelativeHumidity, + #[serde(rename = "000000BE-0000-1000-8000-0026BB765291")] + TargetSlatState, + #[serde(rename = "00000035-0000-1000-8000-0026BB765291")] + TargetTemperature, + #[serde(rename = "000000C2-0000-1000-8000-0026BB765291")] + TargetTiltAngle, + #[serde(rename = "0000007D-0000-1000-8000-0026BB765291")] + TargetVerticalTiltAngle, + #[serde(rename = "00000036-0000-1000-8000-0026BB765291")] + TemperatureDisplayUnits, + #[serde(rename = "000000D5-0000-1000-8000-0026BB765291")] + ValveType, + #[serde(rename = "00000037-0000-1000-8000-0026BB765291")] + Version, + #[serde(rename = "000000C8-0000-1000-8000-0026BB765291")] + VOCDensity, + #[serde(rename = "00000119-0000-1000-8000-0026BB765291")] + Volume, + #[serde(rename = "000000B5-0000-1000-8000-0026BB765291")] + WaterLevel, + #[serde(rename = "00000226-0000-1000-8000-0026BB765291")] + RecordingAudioActive, + #[serde(rename = "00000205-0000-1000-8000-0026BB765291")] + SupportedCameraRecordingConfiguration, + #[serde(rename = "00000206-0000-1000-8000-0026BB765291")] + SupportedVideoRecordingConfiguration, + #[serde(rename = "00000207-0000-1000-8000-0026BB765291")] + SupportedAudioRecordingConfiguration, + #[serde(rename = "00000209-0000-1000-8000-0026BB765291")] + SelectedCameraRecordingConfiguration, + #[serde(rename = "0000021D-0000-1000-8000-0026BB765291")] + CameraOperatingModeIndicator, + #[serde(rename = "00000223-0000-1000-8000-0026BB765291")] + EventSnapshotsActive, + #[serde(rename = "00000224-0000-1000-8000-0026BB765291")] + DiagonalFieldOfView, + #[serde(rename = "0000021B-0000-1000-8000-0026BB765291")] + HomeKitCameraActive, + #[serde(rename = "00000227-0000-1000-8000-0026BB765291")] + ManuallyDisabled, + #[serde(rename = "0000021C-0000-1000-8000-0026BB765291")] + ThirdPartyCameraActive, + #[serde(rename = "00000225-0000-1000-8000-0026BB765291")] + PeriodicSnapshotsActive, + #[serde(rename = "0000020C-0000-1000-8000-0026BB765291")] + NetworkClientProfileControl, + #[serde(rename = "0000020D-0000-1000-8000-0026BB765291")] + NetworkClientStatusControl, + #[serde(rename = "0000020E-0000-1000-8000-0026BB765291")] + RouterStatus, + #[serde(rename = "00000210-0000-1000-8000-0026BB765291")] + SupportedRouterConfiguration, + #[serde(rename = "00000211-0000-1000-8000-0026BB765291")] + WANConfigurationList, + #[serde(rename = "00000212-0000-1000-8000-0026BB765291")] + WANStatusList, + #[serde(rename = "00000215-0000-1000-8000-0026BB765291")] + ManagedNetworkEnable, + #[serde(rename = "0000021F-0000-1000-8000-0026BB765291")] + NetworkAccessViolationControl, + #[serde(rename = "0000021E-0000-1000-8000-0026BB765291")] + WiFiSatelliteStatus, + #[serde(rename = "00000222-0000-1000-8000-0026BB765291")] + WakeConfiguration, + #[serde(rename = "00000202-0000-1000-8000-0026BB765291")] + SupportedTransferTransportConfiguration, + #[serde(rename = "00000201-0000-1000-8000-0026BB765291")] + SetupTransferTransport, + #[serde(rename = "0000021E-0000-1000-8000-0000023B")] + ActivityInterval, + #[serde(rename = "0000021E-0000-1000-8000-00000246")] + CCAEnergyDetectThreshold, + #[serde(rename = "0000021E-0000-1000-8000-00000245")] + CCASignalDetectThreshold, + #[serde(rename = "0000021E-0000-1000-8000-00000143")] + CharacteristicValueTransitionControl, + #[serde(rename = "0000021E-0000-1000-8000-00000144")] + SupportedCharacteristicValueTransitionConfiguration, + #[serde(rename = "0000021E-0000-1000-8000-0000022B")] + CurrentTransport, + #[serde(rename = "0000021E-0000-1000-8000-00000138")] + DataStreamHAPTransport, + #[serde(rename = "0000021E-0000-1000-8000-00000139")] + DataStreamHAPTransportInterrupt, + #[serde(rename = "0000021E-0000-1000-8000-0000023D")] + EventRetransmissionMaximum, + #[serde(rename = "0000021E-0000-1000-8000-0000023E")] + EventTransmissionCounters, + #[serde(rename = "0000021E-0000-1000-8000-0000024A")] + HeartBeat, + #[serde(rename = "0000021E-0000-1000-8000-00000247")] + MACRetransmissionMaximum, + #[serde(rename = "0000021E-0000-1000-8000-00000248")] + MACTransmissionCounters, + #[serde(rename = "0000021E-0000-1000-8000-00000232")] + OperatingStateResponse, + #[serde(rename = "0000021E-0000-1000-8000-0000023C")] + Ping, + #[serde(rename = "0000021E-0000-1000-8000-00000244")] + ReceiverSensitivity, + #[serde(rename = "0000021E-0000-1000-8000-0000023F")] + ReceivedSignalStrengthIndication, + #[serde(rename = "0000021E-0000-1000-8000-0000023A")] + SleepInterval, + #[serde(rename = "0000021E-0000-1000-8000-00000241")] + SignalToNoiseRatio, + #[serde(rename = "0000021E-0000-1000-8000-00000238")] + SupportedDiagnosticsSnapshot, + #[serde(rename = "0000021E-0000-1000-8000-00000242")] + TransmitPower, + #[serde(rename = "0000021E-0000-1000-8000-00000243")] + TransmitPowerMaximum, + #[serde(rename = "0000021E-0000-1000-8000-00000229")] + VideoAnalysisActive, + #[serde(rename = "0000021E-0000-1000-8000-0000022C")] + WiFiCapabilities, + #[serde(rename = "0000021E-0000-1000-8000-0000022D")] + WiFiConfigurationControl, + #[serde(rename = "000000A4-0000-1000-8000-0026BB765291")] + AppMatchingIdentifier, + #[serde(rename = "00000074-0000-1000-8000-0026BB765291")] + ProgrammableSwitchOutputState, + #[serde(rename = "00000054-0000-1000-8000-0026BB765291")] + SoftwareRevision, + #[serde(rename = "00000057-0000-1000-8000-0026BB765291")] + AccessoryIdentifier, + #[serde(rename = "000000A3-0000-1000-8000-0026BB765291")] + Category, + #[serde(rename = "000000A0-0000-1000-8000-0026BB765291")] + ConfigureBridgedAccessory, + #[serde(rename = "0000009D-0000-1000-8000-0026BB765291")] + ConfigureBridgedAccessoryStatus, + #[serde(rename = "0000009B-0000-1000-8000-0026BB765291")] + CurrentTime, + #[serde(rename = "00000098-0000-1000-8000-0026BB765291")] + DayoftheWeek, + #[serde(rename = "0000009E-0000-1000-8000-0026BB765291")] + DiscoverBridgedAccessories, + #[serde(rename = "0000009F-0000-1000-8000-0026BB765291")] + DiscoveredBridgedAccessories, + #[serde(rename = "0000009C-0000-1000-8000-0026BB765291")] + LinkQuality, + #[serde(rename = "00000063-0000-1000-8000-0026BB765291")] + Reachable, + #[serde(rename = "0000005E-0000-1000-8000-0026BB765291")] + RelayControlPoint, + #[serde(rename = "0000005B-0000-1000-8000-0026BB765291")] + RelayEnabled, + #[serde(rename = "0000005C-0000-1000-8000-0026BB765291")] + RelayState, + #[serde(rename = "0000009A-0000-1000-8000-0026BB765291")] + TimeUpdate, + #[serde(rename = "00000061-0000-1000-8000-0026BB765291")] + TunnelConnectionTimeout, + #[serde(rename = "00000060-0000-1000-8000-0026BB765291")] + TunneledAccessoryAdvertising, + #[serde(rename = "00000059-0000-1000-8000-0026BB765291")] + TunneledAccessoryConnected, + #[serde(rename = "00000058-0000-1000-8000-0026BB765291")] + TunneledAccessoryStateNumber, + #[serde(rename = "000000E7-0000-1000-8000-0026BB765291")] + ActiveIdentifier, + #[serde(rename = "000000E3-0000-1000-8000-0026BB765291")] + ConfiguredName, + #[serde(rename = "000000E8-0000-1000-8000-0026BB765291")] + SleepDiscoveryMode, + #[serde(rename = "000000DD-0000-1000-8000-0026BB765291")] + ClosedCaptions, + #[serde(rename = "00000136-0000-1000-8000-0026BB765291")] + DisplayOrder, + #[serde(rename = "000000E0-0000-1000-8000-0026BB765291")] + CurrentMediaState, + #[serde(rename = "00000137-0000-1000-8000-0026BB765291")] + TargetMediaState, + #[serde(rename = "000000E2-0000-1000-8000-0026BB765291")] + PictureMode, + #[serde(rename = "000000DF-0000-1000-8000-0026BB765291")] + PowerModeSelection, + #[serde(rename = "000000E1-0000-1000-8000-0026BB765291")] + RemoteKey, + #[serde(rename = "000000DB-0000-1000-8000-0026BB765291")] + InputSourceType, + #[serde(rename = "000000DC-0000-1000-8000-0026BB765291")] + InputDeviceType, + #[serde(rename = "000000E6-0000-1000-8000-0026BB765291")] + Identifier, + #[serde(rename = "00000135-0000-1000-8000-0026BB765291")] + CurrentVisibilityState, + #[serde(rename = "00000134-0000-1000-8000-0026BB765291")] + TargetVisibilityState, + #[serde(rename = "000000E9-0000-1000-8000-0026BB765291")] + VolumeControlType, + #[serde(rename = "000000EA-0000-1000-8000-0026BB765291")] + VolumeSelector, + #[serde(rename = "00000123-0000-1000-8000-0026BB765291")] + TargetControlSupportedConfiguration, + #[serde(rename = "00000124-0000-1000-8000-0026BB765291")] + TargetControlList, + #[serde(rename = "00000126-0000-1000-8000-0026BB765291")] + ButtonEvent, + #[serde(rename = "00000128-0000-1000-8000-0026BB765291")] + SelectedAudioStreamConfiguration, + #[serde(rename = "00000132-0000-1000-8000-0026BB765291")] + SiriInputType, + #[serde(rename = "00000130-0000-1000-8000-0026BB765291")] + SupportedDataStreamTransportConfiguration, + #[serde(rename = "00000131-0000-1000-8000-0026BB765291")] + SetupDataStreamTransport, + Unknown(String), +} + +impl From for CharacteristicType { + fn from(value: CharacteristicTypeInner) -> Self { + match value { + CharacteristicTypeInner::Unknown(v) => { + log::warn!("unknown characteristic type: {v}"); + Self::Unknown + } + CharacteristicTypeInner::AccessControlLevel => Self::AccessControlLevel, + CharacteristicTypeInner::AccessoryFlags => Self::AccessoryFlags, + CharacteristicTypeInner::ProductData => Self::ProductData, + CharacteristicTypeInner::Active => Self::Active, + CharacteristicTypeInner::AdministratorOnlyAccess => Self::AdministratorOnlyAccess, + CharacteristicTypeInner::AirParticulateDensity => Self::AirParticulateDensity, + CharacteristicTypeInner::AirParticulateSize => Self::AirParticulateSize, + CharacteristicTypeInner::AirQuality => Self::AirQuality, + CharacteristicTypeInner::AudioFeedback => Self::AudioFeedback, + CharacteristicTypeInner::BatteryLevel => Self::BatteryLevel, + CharacteristicTypeInner::Brightness => Self::Brightness, + CharacteristicTypeInner::CarbonDioxideDetected => Self::CarbonDioxideDetected, + CharacteristicTypeInner::CarbonDioxideLevel => Self::CarbonDioxideLevel, + CharacteristicTypeInner::CarbonDioxidePeakLevel => Self::CarbonDioxidePeakLevel, + CharacteristicTypeInner::CarbonMonoxideDetected => Self::CarbonMonoxideDetected, + CharacteristicTypeInner::CarbonMonoxideLevel => Self::CarbonMonoxideLevel, + CharacteristicTypeInner::CarbonMonoxidePeakLevel => Self::CarbonMonoxidePeakLevel, + CharacteristicTypeInner::ChargingState => Self::ChargingState, + CharacteristicTypeInner::ColorTemperature => Self::ColorTemperature, + CharacteristicTypeInner::ContactSensorState => Self::ContactSensorState, + CharacteristicTypeInner::CoolingThresholdTemperature => { + Self::CoolingThresholdTemperature + } + CharacteristicTypeInner::CurrentAirPurifierState => Self::CurrentAirPurifierState, + CharacteristicTypeInner::CurrentAmbientLightLevel => Self::CurrentAmbientLightLevel, + CharacteristicTypeInner::CurrentDoorState => Self::CurrentDoorState, + CharacteristicTypeInner::CurrentFanState => Self::CurrentFanState, + CharacteristicTypeInner::CurrentHeaterCoolerState => Self::CurrentHeaterCoolerState, + CharacteristicTypeInner::CurrentHeatingCoolingState => Self::CurrentHeatingCoolingState, + CharacteristicTypeInner::CurrentHorizontalTiltAngle => Self::CurrentHorizontalTiltAngle, + CharacteristicTypeInner::CurrentHumidifierDehumidifierState => { + Self::CurrentHumidifierDehumidifierState + } + CharacteristicTypeInner::CurrentPosition => Self::CurrentPosition, + CharacteristicTypeInner::CurrentRelativeHumidity => Self::CurrentRelativeHumidity, + CharacteristicTypeInner::CurrentSlatState => Self::CurrentSlatState, + CharacteristicTypeInner::CurrentTemperature => Self::CurrentTemperature, + CharacteristicTypeInner::CurrentTiltAngle => Self::CurrentTiltAngle, + CharacteristicTypeInner::CurrentVerticalTiltAngle => Self::CurrentVerticalTiltAngle, + CharacteristicTypeInner::DigitalZoom => Self::DigitalZoom, + CharacteristicTypeInner::FilterChangeIndication => Self::FilterChangeIndication, + CharacteristicTypeInner::FilterLifeLevel => Self::FilterLifeLevel, + CharacteristicTypeInner::FirmwareRevision => Self::FirmwareRevision, + CharacteristicTypeInner::HardwareRevision => Self::HardwareRevision, + CharacteristicTypeInner::HeatingThresholdTemperature => { + Self::HeatingThresholdTemperature + } + CharacteristicTypeInner::HoldPosition => Self::HoldPosition, + CharacteristicTypeInner::Hue => Self::Hue, + CharacteristicTypeInner::Identify => Self::Identify, + CharacteristicTypeInner::ImageMirroring => Self::ImageMirroring, + CharacteristicTypeInner::ImageRotation => Self::ImageRotation, + CharacteristicTypeInner::InUse => Self::InUse, + CharacteristicTypeInner::IsConfigured => Self::IsConfigured, + CharacteristicTypeInner::LeakDetected => Self::LeakDetected, + CharacteristicTypeInner::LockControlPoint => Self::LockControlPoint, + CharacteristicTypeInner::LockCurrentState => Self::LockCurrentState, + CharacteristicTypeInner::LockLastKnownAction => Self::LockLastKnownAction, + CharacteristicTypeInner::LockManagementAutoSecurityTimeout => { + Self::LockManagementAutoSecurityTimeout + } + CharacteristicTypeInner::LockPhysicalControls => Self::LockPhysicalControls, + CharacteristicTypeInner::LockTargetState => Self::LockTargetState, + CharacteristicTypeInner::Logs => Self::Logs, + CharacteristicTypeInner::Manufacturer => Self::Manufacturer, + CharacteristicTypeInner::Model => Self::Model, + CharacteristicTypeInner::MotionDetected => Self::MotionDetected, + CharacteristicTypeInner::Mute => Self::Mute, + CharacteristicTypeInner::Name => Self::Name, + CharacteristicTypeInner::NightVision => Self::NightVision, + CharacteristicTypeInner::NitrogenDioxideDensity => Self::NitrogenDioxideDensity, + CharacteristicTypeInner::ObstructionDetected => Self::ObstructionDetected, + CharacteristicTypeInner::OccupancyDetected => Self::OccupancyDetected, + CharacteristicTypeInner::On => Self::On, + CharacteristicTypeInner::OpticalZoom => Self::OpticalZoom, + CharacteristicTypeInner::OutletInUse => Self::OutletInUse, + CharacteristicTypeInner::OzoneDensity => Self::OzoneDensity, + CharacteristicTypeInner::PairSetup => Self::PairSetup, + CharacteristicTypeInner::PairVerify => Self::PairVerify, + CharacteristicTypeInner::PairingFeatures => Self::PairingFeatures, + CharacteristicTypeInner::PairingPairings => Self::PairingPairings, + CharacteristicTypeInner::PasswordSetting => Self::PasswordSetting, + CharacteristicTypeInner::PM10Density => Self::PM10Density, + CharacteristicTypeInner::PM2_5Density => Self::PM2_5Density, + CharacteristicTypeInner::PositionState => Self::PositionState, + CharacteristicTypeInner::ProgramMode => Self::ProgramMode, + CharacteristicTypeInner::ProgrammableSwitchEvent => Self::ProgrammableSwitchEvent, + CharacteristicTypeInner::RelativeHumidityDehumidifierThreshold => { + Self::RelativeHumidityDehumidifierThreshold + } + CharacteristicTypeInner::RelativeHumidityHumidifierThreshold => { + Self::RelativeHumidityHumidifierThreshold + } + CharacteristicTypeInner::RemainingDuration => Self::RemainingDuration, + CharacteristicTypeInner::ResetFilterIndication => Self::ResetFilterIndication, + CharacteristicTypeInner::RotationDirection => Self::RotationDirection, + CharacteristicTypeInner::RotationSpeed => Self::RotationSpeed, + CharacteristicTypeInner::Saturation => Self::Saturation, + CharacteristicTypeInner::SecuritySystemAlarmType => Self::SecuritySystemAlarmType, + CharacteristicTypeInner::SecuritySystemCurrentState => Self::SecuritySystemCurrentState, + CharacteristicTypeInner::SecuritySystemTargetState => Self::SecuritySystemTargetState, + CharacteristicTypeInner::SelectedRTPStreamConfiguration => { + Self::SelectedRTPStreamConfiguration + } + CharacteristicTypeInner::SerialNumber => Self::SerialNumber, + CharacteristicTypeInner::ServiceLabelIndex => Self::ServiceLabelIndex, + CharacteristicTypeInner::ServiceLabelNamespace => Self::ServiceLabelNamespace, + CharacteristicTypeInner::SetDuration => Self::SetDuration, + CharacteristicTypeInner::SetupEndpoints => Self::SetupEndpoints, + CharacteristicTypeInner::SlatType => Self::SlatType, + CharacteristicTypeInner::SmokeDetected => Self::SmokeDetected, + CharacteristicTypeInner::StatusActive => Self::StatusActive, + CharacteristicTypeInner::StatusFault => Self::StatusFault, + CharacteristicTypeInner::StatusJammed => Self::StatusJammed, + CharacteristicTypeInner::StatusLowBattery => Self::StatusLowBattery, + CharacteristicTypeInner::StatusTampered => Self::StatusTampered, + CharacteristicTypeInner::StreamingStatus => Self::StreamingStatus, + CharacteristicTypeInner::SulphurDioxideDensity => Self::SulphurDioxideDensity, + CharacteristicTypeInner::SupportedAudioStreamConfiguration => { + Self::SupportedAudioStreamConfiguration + } + CharacteristicTypeInner::SupportedRTPConfiguration => Self::SupportedRTPConfiguration, + CharacteristicTypeInner::SupportedVideoStreamConfiguration => { + Self::SupportedVideoStreamConfiguration + } + CharacteristicTypeInner::SwingMode => Self::SwingMode, + CharacteristicTypeInner::TargetAirPurifierState => Self::TargetAirPurifierState, + CharacteristicTypeInner::TargetAirQuality => Self::TargetAirQuality, + CharacteristicTypeInner::TargetDoorState => Self::TargetDoorState, + CharacteristicTypeInner::TargetFanState => Self::TargetFanState, + CharacteristicTypeInner::TargetHeaterCoolerState => Self::TargetHeaterCoolerState, + CharacteristicTypeInner::TargetHeatingCoolingState => Self::TargetHeatingCoolingState, + CharacteristicTypeInner::TargetHorizontalTiltAngle => Self::TargetHorizontalTiltAngle, + CharacteristicTypeInner::TargetHumidifierDehumidifierState => { + Self::TargetHumidifierDehumidifierState + } + CharacteristicTypeInner::TargetPosition => Self::TargetPosition, + CharacteristicTypeInner::TargetRelativeHumidity => Self::TargetRelativeHumidity, + CharacteristicTypeInner::TargetSlatState => Self::TargetSlatState, + CharacteristicTypeInner::TargetTemperature => Self::TargetTemperature, + CharacteristicTypeInner::TargetTiltAngle => Self::TargetTiltAngle, + CharacteristicTypeInner::TargetVerticalTiltAngle => Self::TargetVerticalTiltAngle, + CharacteristicTypeInner::TemperatureDisplayUnits => Self::TemperatureDisplayUnits, + CharacteristicTypeInner::ValveType => Self::ValveType, + CharacteristicTypeInner::Version => Self::Version, + CharacteristicTypeInner::VOCDensity => Self::VOCDensity, + CharacteristicTypeInner::Volume => Self::Volume, + CharacteristicTypeInner::WaterLevel => Self::WaterLevel, + CharacteristicTypeInner::RecordingAudioActive => Self::RecordingAudioActive, + CharacteristicTypeInner::SupportedCameraRecordingConfiguration => { + Self::SupportedCameraRecordingConfiguration + } + CharacteristicTypeInner::SupportedVideoRecordingConfiguration => { + Self::SupportedVideoRecordingConfiguration + } + CharacteristicTypeInner::SupportedAudioRecordingConfiguration => { + Self::SupportedAudioRecordingConfiguration + } + CharacteristicTypeInner::SelectedCameraRecordingConfiguration => { + Self::SelectedCameraRecordingConfiguration + } + CharacteristicTypeInner::CameraOperatingModeIndicator => { + Self::CameraOperatingModeIndicator + } + CharacteristicTypeInner::EventSnapshotsActive => Self::EventSnapshotsActive, + CharacteristicTypeInner::DiagonalFieldOfView => Self::DiagonalFieldOfView, + CharacteristicTypeInner::HomeKitCameraActive => Self::HomeKitCameraActive, + CharacteristicTypeInner::ManuallyDisabled => Self::ManuallyDisabled, + CharacteristicTypeInner::ThirdPartyCameraActive => Self::ThirdPartyCameraActive, + CharacteristicTypeInner::PeriodicSnapshotsActive => Self::PeriodicSnapshotsActive, + CharacteristicTypeInner::NetworkClientProfileControl => { + Self::NetworkClientProfileControl + } + CharacteristicTypeInner::NetworkClientStatusControl => Self::NetworkClientStatusControl, + CharacteristicTypeInner::RouterStatus => Self::RouterStatus, + CharacteristicTypeInner::SupportedRouterConfiguration => { + Self::SupportedRouterConfiguration + } + CharacteristicTypeInner::WANConfigurationList => Self::WANConfigurationList, + CharacteristicTypeInner::WANStatusList => Self::WANStatusList, + CharacteristicTypeInner::ManagedNetworkEnable => Self::ManagedNetworkEnable, + CharacteristicTypeInner::NetworkAccessViolationControl => { + Self::NetworkAccessViolationControl + } + CharacteristicTypeInner::WiFiSatelliteStatus => Self::WiFiSatelliteStatus, + CharacteristicTypeInner::WakeConfiguration => Self::WakeConfiguration, + CharacteristicTypeInner::SupportedTransferTransportConfiguration => { + Self::SupportedTransferTransportConfiguration + } + CharacteristicTypeInner::SetupTransferTransport => Self::SetupTransferTransport, + CharacteristicTypeInner::ActivityInterval => Self::ActivityInterval, + CharacteristicTypeInner::CCAEnergyDetectThreshold => Self::CCAEnergyDetectThreshold, + CharacteristicTypeInner::CCASignalDetectThreshold => Self::CCASignalDetectThreshold, + CharacteristicTypeInner::CharacteristicValueTransitionControl => { + Self::CharacteristicValueTransitionControl + } + CharacteristicTypeInner::SupportedCharacteristicValueTransitionConfiguration => { + Self::SupportedCharacteristicValueTransitionConfiguration + } + CharacteristicTypeInner::CurrentTransport => Self::CurrentTransport, + CharacteristicTypeInner::DataStreamHAPTransport => Self::DataStreamHAPTransport, + CharacteristicTypeInner::DataStreamHAPTransportInterrupt => { + Self::DataStreamHAPTransportInterrupt + } + CharacteristicTypeInner::EventRetransmissionMaximum => Self::EventRetransmissionMaximum, + CharacteristicTypeInner::EventTransmissionCounters => Self::EventTransmissionCounters, + CharacteristicTypeInner::HeartBeat => Self::HeartBeat, + CharacteristicTypeInner::MACRetransmissionMaximum => Self::MACRetransmissionMaximum, + CharacteristicTypeInner::MACTransmissionCounters => Self::MACTransmissionCounters, + CharacteristicTypeInner::OperatingStateResponse => Self::OperatingStateResponse, + CharacteristicTypeInner::Ping => Self::Ping, + CharacteristicTypeInner::ReceiverSensitivity => Self::ReceiverSensitivity, + CharacteristicTypeInner::ReceivedSignalStrengthIndication => { + Self::ReceivedSignalStrengthIndication + } + CharacteristicTypeInner::SleepInterval => Self::SleepInterval, + CharacteristicTypeInner::SignalToNoiseRatio => Self::SignalToNoiseRatio, + CharacteristicTypeInner::SupportedDiagnosticsSnapshot => { + Self::SupportedDiagnosticsSnapshot + } + CharacteristicTypeInner::TransmitPower => Self::TransmitPower, + CharacteristicTypeInner::TransmitPowerMaximum => Self::TransmitPowerMaximum, + CharacteristicTypeInner::VideoAnalysisActive => Self::VideoAnalysisActive, + CharacteristicTypeInner::WiFiCapabilities => Self::WiFiCapabilities, + CharacteristicTypeInner::WiFiConfigurationControl => Self::WiFiConfigurationControl, + CharacteristicTypeInner::AppMatchingIdentifier => Self::AppMatchingIdentifier, + CharacteristicTypeInner::ProgrammableSwitchOutputState => { + Self::ProgrammableSwitchOutputState + } + CharacteristicTypeInner::SoftwareRevision => Self::SoftwareRevision, + CharacteristicTypeInner::AccessoryIdentifier => Self::AccessoryIdentifier, + CharacteristicTypeInner::Category => Self::Category, + CharacteristicTypeInner::ConfigureBridgedAccessory => Self::ConfigureBridgedAccessory, + CharacteristicTypeInner::ConfigureBridgedAccessoryStatus => { + Self::ConfigureBridgedAccessoryStatus + } + CharacteristicTypeInner::CurrentTime => Self::CurrentTime, + CharacteristicTypeInner::DayoftheWeek => Self::DayoftheWeek, + CharacteristicTypeInner::DiscoverBridgedAccessories => Self::DiscoverBridgedAccessories, + CharacteristicTypeInner::DiscoveredBridgedAccessories => { + Self::DiscoveredBridgedAccessories + } + CharacteristicTypeInner::LinkQuality => Self::LinkQuality, + CharacteristicTypeInner::Reachable => Self::Reachable, + CharacteristicTypeInner::RelayControlPoint => Self::RelayControlPoint, + CharacteristicTypeInner::RelayEnabled => Self::RelayEnabled, + CharacteristicTypeInner::RelayState => Self::RelayState, + CharacteristicTypeInner::TimeUpdate => Self::TimeUpdate, + CharacteristicTypeInner::TunnelConnectionTimeout => Self::TunnelConnectionTimeout, + CharacteristicTypeInner::TunneledAccessoryAdvertising => { + Self::TunneledAccessoryAdvertising + } + CharacteristicTypeInner::TunneledAccessoryConnected => Self::TunneledAccessoryConnected, + CharacteristicTypeInner::TunneledAccessoryStateNumber => { + Self::TunneledAccessoryStateNumber + } + CharacteristicTypeInner::ActiveIdentifier => Self::ActiveIdentifier, + CharacteristicTypeInner::ConfiguredName => Self::ConfiguredName, + CharacteristicTypeInner::SleepDiscoveryMode => Self::SleepDiscoveryMode, + CharacteristicTypeInner::ClosedCaptions => Self::ClosedCaptions, + CharacteristicTypeInner::DisplayOrder => Self::DisplayOrder, + CharacteristicTypeInner::CurrentMediaState => Self::CurrentMediaState, + CharacteristicTypeInner::TargetMediaState => Self::TargetMediaState, + CharacteristicTypeInner::PictureMode => Self::PictureMode, + CharacteristicTypeInner::PowerModeSelection => Self::PowerModeSelection, + CharacteristicTypeInner::RemoteKey => Self::RemoteKey, + CharacteristicTypeInner::InputSourceType => Self::InputSourceType, + CharacteristicTypeInner::InputDeviceType => Self::InputDeviceType, + CharacteristicTypeInner::Identifier => Self::Identifier, + CharacteristicTypeInner::CurrentVisibilityState => Self::CurrentVisibilityState, + CharacteristicTypeInner::TargetVisibilityState => Self::TargetVisibilityState, + CharacteristicTypeInner::VolumeControlType => Self::VolumeControlType, + CharacteristicTypeInner::VolumeSelector => Self::VolumeSelector, + CharacteristicTypeInner::TargetControlSupportedConfiguration => { + Self::TargetControlSupportedConfiguration + } + CharacteristicTypeInner::TargetControlList => Self::TargetControlList, + CharacteristicTypeInner::ButtonEvent => Self::ButtonEvent, + CharacteristicTypeInner::SelectedAudioStreamConfiguration => { + Self::SelectedAudioStreamConfiguration + } + CharacteristicTypeInner::SiriInputType => Self::SiriInputType, + CharacteristicTypeInner::SupportedDataStreamTransportConfiguration => { + Self::SupportedDataStreamTransportConfiguration + } + CharacteristicTypeInner::SetupDataStreamTransport => Self::SetupDataStreamTransport, + } + } +} + +pub(crate) fn deserialize_service_type<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + ServiceTypeInner::deserialize(deserializer).map(|v| v.into()) +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum ServiceType { + AccessControl, + AccessoryInformation, + AirPurifier, + AirQualitySensor, + BatteryService, + CameraRTPStreamManagement, + CarbonDioxideSensor, + CarbonMonoxideSensor, + ContactSensor, + Door, + Doorbell, + Fan, + Fanv2, + FilterMaintenance, + Faucet, + GarageDoorOpener, + HeaterCooler, + HumidifierDehumidifier, + HumiditySensor, + IrrigationSystem, + LeakSensor, + LightSensor, + Lightbulb, + LockManagement, + LockMechanism, + Microphone, + MotionSensor, + OccupancySensor, + Outlet, + SecuritySystem, + ServiceLabel, + Slat, + SmokeSensor, + SmartSpeaker, + Speaker, + StatelessProgrammableSwitch, + Switch, + TemperatureSensor, + Thermostat, + Valve, + Window, + WindowCovering, + CameraOperatingMode, + CameraEventRecordingManagement, + WiFiRouter, + WiFiSatellite, + PowerManagement, + TransferTransportManagement, + AccessoryRuntimeInformation, + Diagnostics, + WiFiTransport, + CameraControl, + StatefulProgrammableSwitch, + BridgeConfiguration, + BridgingState, + Pairing, + ProtocolInformation, + Relay, + TimeInformation, + TunneledBTLEAccessoryService, + Television, + InputSource, + TargetControlManagement, + TargetControl, + AudioStreamManagement, + Siri, + DataStreamTransportManagement, + Unknown, +} + +#[derive(Deserialize)] +#[serde(field_identifier)] +pub enum ServiceTypeInner { + #[serde(rename = "'000000DA-0000-1000-8000-0026BB765291")] + AccessControl, + #[serde(rename = "0000003E-0000-1000-8000-0026BB765291")] + AccessoryInformation, + #[serde(rename = "000000BB-0000-1000-8000-0026BB765291")] + AirPurifier, + #[serde(rename = "0000008D-0000-1000-8000-0026BB765291")] + AirQualitySensor, + #[serde(rename = "00000096-0000-1000-8000-0026BB765291")] + BatteryService, + #[serde(rename = "00000110-0000-1000-8000-0026BB765291")] + CameraRTPStreamManagement, + #[serde(rename = "00000097-0000-1000-8000-0026BB765291")] + CarbonDioxideSensor, + #[serde(rename = "0000007F-0000-1000-8000-0026BB765291")] + CarbonMonoxideSensor, + #[serde(rename = "00000080-0000-1000-8000-0026BB765291")] + ContactSensor, + #[serde(rename = "00000081-0000-1000-8000-0026BB765291")] + Door, + #[serde(rename = "00000121-0000-1000-8000-0026BB765291")] + Doorbell, + #[serde(rename = "00000040-0000-1000-8000-0026BB765291")] + Fan, + #[serde(rename = "000000B7-0000-1000-8000-0026BB765291")] + Fanv2, + #[serde(rename = "000000BA-0000-1000-8000-0026BB765291")] + FilterMaintenance, + #[serde(rename = "000000D7-0000-1000-8000-0026BB765291")] + Faucet, + #[serde(rename = "00000041-0000-1000-8000-0026BB765291")] + GarageDoorOpener, + #[serde(rename = "000000BC-0000-1000-8000-0026BB765291")] + HeaterCooler, + #[serde(rename = "000000BD-0000-1000-8000-0026BB765291")] + HumidifierDehumidifier, + #[serde(rename = "00000082-0000-1000-8000-0026BB765291")] + HumiditySensor, + #[serde(rename = "000000CF-0000-1000-8000-0026BB765291")] + IrrigationSystem, + #[serde(rename = "00000083-0000-1000-8000-0026BB765291")] + LeakSensor, + #[serde(rename = "00000084-0000-1000-8000-0026BB765291")] + LightSensor, + #[serde(rename = "00000043-0000-1000-8000-0026BB765291")] + Lightbulb, + #[serde(rename = "00000044-0000-1000-8000-0026BB765291")] + LockManagement, + #[serde(rename = "00000045-0000-1000-8000-0026BB765291")] + LockMechanism, + #[serde(rename = "00000112-0000-1000-8000-0026BB765291")] + Microphone, + #[serde(rename = "00000085-0000-1000-8000-0026BB765291")] + MotionSensor, + #[serde(rename = "00000086-0000-1000-8000-0026BB765291")] + OccupancySensor, + #[serde(rename = "00000047-0000-1000-8000-0026BB765291")] + Outlet, + #[serde(rename = "0000007E-0000-1000-8000-0026BB765291")] + SecuritySystem, + #[serde(rename = "000000CC-0000-1000-8000-0026BB765291")] + ServiceLabel, + #[serde(rename = "000000B9-0000-1000-8000-0026BB765291")] + Slat, + #[serde(rename = "00000087-0000-1000-8000-0026BB765291")] + SmokeSensor, + #[serde(rename = "00000228-0000-1000-8000-0026BB765291")] + SmartSpeaker, + #[serde(rename = "00000113-0000-1000-8000-0026BB765291")] + Speaker, + #[serde(rename = "00000089-0000-1000-8000-0026BB765291")] + StatelessProgrammableSwitch, + #[serde(rename = "00000049-0000-1000-8000-0026BB765291")] + Switch, + #[serde(rename = "0000008A-0000-1000-8000-0026BB765291")] + TemperatureSensor, + #[serde(rename = "0000004A-0000-1000-8000-0026BB765291")] + Thermostat, + #[serde(rename = "000000D0-0000-1000-8000-0026BB765291")] + Valve, + #[serde(rename = "0000008B-0000-1000-8000-0026BB765291")] + Window, + #[serde(rename = "0000008C-0000-1000-8000-0026BB765291")] + WindowCovering, + #[serde(rename = "0000021A-0000-1000-8000-0026BB765291")] + CameraOperatingMode, + #[serde(rename = "00000204-0000-1000-8000-0026BB765291")] + CameraEventRecordingManagement, + #[serde(rename = "0000020A-0000-1000-8000-0026BB765291")] + WiFiRouter, + #[serde(rename = "0000020F-0000-1000-8000-0026BB765291")] + WiFiSatellite, + #[serde(rename = "00000221-0000-1000-8000-0026BB765291")] + PowerManagement, + #[serde(rename = "00000203-0000-1000-8000-0026BB765291")] + TransferTransportManagement, + #[serde(rename = "00000203-0000-1000-8000-00000239")] + AccessoryRuntimeInformation, + #[serde(rename = "00000203-0000-1000-8000-00000237")] + Diagnostics, + #[serde(rename = "00000203-0000-1000-8000-0000022A")] + WiFiTransport, + #[serde(rename = "00000111-0000-1000-8000-0026BB765291")] + CameraControl, + #[serde(rename = "00000088-0000-1000-8000-0026BB765291")] + StatefulProgrammableSwitch, + #[serde(rename = "000000A1-0000-1000-8000-0026BB765291")] + BridgeConfiguration, + #[serde(rename = "00000062-0000-1000-8000-0026BB765291")] + BridgingState, + #[serde(rename = "00000055-0000-1000-8000-0026BB765291")] + Pairing, + #[serde(rename = "000000A2-0000-1000-8000-0026BB765291")] + ProtocolInformation, + #[serde(rename = "0000005A-0000-1000-8000-0026BB765291")] + Relay, + #[serde(rename = "00000099-0000-1000-8000-0026BB765291")] + TimeInformation, + #[serde(rename = "00000056-0000-1000-8000-0026BB765291")] + TunneledBTLEAccessoryService, + #[serde(rename = "000000D8-0000-1000-8000-0026BB765291")] + Television, + #[serde(rename = "000000D9-0000-1000-8000-0026BB765291")] + InputSource, + #[serde(rename = "00000122-0000-1000-8000-0026BB765291")] + TargetControlManagement, + #[serde(rename = "00000125-0000-1000-8000-0026BB765291")] + TargetControl, + #[serde(rename = "00000127-0000-1000-8000-0026BB765291")] + AudioStreamManagement, + #[serde(rename = "00000133-0000-1000-8000-0026BB765291")] + Siri, + #[serde(rename = "00000129-0000-1000-8000-0026BB765291")] + DataStreamTransportManagement, + Unknown(String), +} + +impl From for ServiceType { + fn from(value: ServiceTypeInner) -> Self { + match value { + ServiceTypeInner::Unknown(v) => { + log::warn!("unknown service type: {v}"); + Self::Unknown + } + ServiceTypeInner::AccessControl => Self::AccessControl, + ServiceTypeInner::AccessoryInformation => Self::AccessoryInformation, + ServiceTypeInner::AirPurifier => Self::AirPurifier, + ServiceTypeInner::AirQualitySensor => Self::AirQualitySensor, + ServiceTypeInner::BatteryService => Self::BatteryService, + ServiceTypeInner::CameraRTPStreamManagement => Self::CameraRTPStreamManagement, + ServiceTypeInner::CarbonDioxideSensor => Self::CarbonDioxideSensor, + ServiceTypeInner::CarbonMonoxideSensor => Self::CarbonMonoxideSensor, + ServiceTypeInner::ContactSensor => Self::ContactSensor, + ServiceTypeInner::Door => Self::Door, + ServiceTypeInner::Doorbell => Self::Doorbell, + ServiceTypeInner::Fan => Self::Fan, + ServiceTypeInner::Fanv2 => Self::Fanv2, + ServiceTypeInner::FilterMaintenance => Self::FilterMaintenance, + ServiceTypeInner::Faucet => Self::Faucet, + ServiceTypeInner::GarageDoorOpener => Self::GarageDoorOpener, + ServiceTypeInner::HeaterCooler => Self::HeaterCooler, + ServiceTypeInner::HumidifierDehumidifier => Self::HumidifierDehumidifier, + ServiceTypeInner::HumiditySensor => Self::HumiditySensor, + ServiceTypeInner::IrrigationSystem => Self::IrrigationSystem, + ServiceTypeInner::LeakSensor => Self::LeakSensor, + ServiceTypeInner::LightSensor => Self::LightSensor, + ServiceTypeInner::Lightbulb => Self::Lightbulb, + ServiceTypeInner::LockManagement => Self::LockManagement, + ServiceTypeInner::LockMechanism => Self::LockMechanism, + ServiceTypeInner::Microphone => Self::Microphone, + ServiceTypeInner::MotionSensor => Self::MotionSensor, + ServiceTypeInner::OccupancySensor => Self::OccupancySensor, + ServiceTypeInner::Outlet => Self::Outlet, + ServiceTypeInner::SecuritySystem => Self::SecuritySystem, + ServiceTypeInner::ServiceLabel => Self::ServiceLabel, + ServiceTypeInner::Slat => Self::Slat, + ServiceTypeInner::SmokeSensor => Self::SmokeSensor, + ServiceTypeInner::SmartSpeaker => Self::SmartSpeaker, + ServiceTypeInner::Speaker => Self::Speaker, + ServiceTypeInner::StatelessProgrammableSwitch => Self::StatelessProgrammableSwitch, + ServiceTypeInner::Switch => Self::Switch, + ServiceTypeInner::TemperatureSensor => Self::TemperatureSensor, + ServiceTypeInner::Thermostat => Self::Thermostat, + ServiceTypeInner::Valve => Self::Valve, + ServiceTypeInner::Window => Self::Window, + ServiceTypeInner::WindowCovering => Self::WindowCovering, + ServiceTypeInner::CameraOperatingMode => Self::CameraOperatingMode, + ServiceTypeInner::CameraEventRecordingManagement => { + Self::CameraEventRecordingManagement + } + ServiceTypeInner::WiFiRouter => Self::WiFiRouter, + ServiceTypeInner::WiFiSatellite => Self::WiFiSatellite, + ServiceTypeInner::PowerManagement => Self::PowerManagement, + ServiceTypeInner::TransferTransportManagement => Self::TransferTransportManagement, + ServiceTypeInner::AccessoryRuntimeInformation => Self::AccessoryRuntimeInformation, + ServiceTypeInner::Diagnostics => Self::Diagnostics, + ServiceTypeInner::WiFiTransport => Self::WiFiTransport, + ServiceTypeInner::CameraControl => Self::CameraControl, + ServiceTypeInner::StatefulProgrammableSwitch => Self::StatefulProgrammableSwitch, + ServiceTypeInner::BridgeConfiguration => Self::BridgeConfiguration, + ServiceTypeInner::BridgingState => Self::BridgingState, + ServiceTypeInner::Pairing => Self::Pairing, + ServiceTypeInner::ProtocolInformation => Self::ProtocolInformation, + ServiceTypeInner::Relay => Self::Relay, + ServiceTypeInner::TimeInformation => Self::TimeInformation, + ServiceTypeInner::TunneledBTLEAccessoryService => Self::TunneledBTLEAccessoryService, + ServiceTypeInner::Television => Self::Television, + ServiceTypeInner::InputSource => Self::InputSource, + ServiceTypeInner::TargetControlManagement => Self::TargetControlManagement, + ServiceTypeInner::TargetControl => Self::TargetControl, + ServiceTypeInner::AudioStreamManagement => Self::AudioStreamManagement, + ServiceTypeInner::Siri => Self::Siri, + ServiceTypeInner::DataStreamTransportManagement => Self::DataStreamTransportManagement, + } + } +} diff --git a/homekit-controller/src/lib.rs b/homekit-controller/src/lib.rs new file mode 100644 index 0000000..1c8d184 --- /dev/null +++ b/homekit-controller/src/lib.rs @@ -0,0 +1,118 @@ +use std::{collections::HashMap, path::PathBuf}; + +use characteristics::{ + deserialize_characteristic_type, deserialize_service_type, CharacteristicType, ServiceType, +}; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +mod characteristics; + +#[derive(Debug, Clone)] +pub struct HomekitController { + devices: HashMap, +} + +impl HomekitController { + pub fn load(pairing_data: PathBuf) -> Result { + let devices: HashMap = + serde_json::from_str(&std::fs::read_to_string(pairing_data)?)?; + + Ok(Self { devices }) + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct DevicePairingData { + #[serde(rename = "AccessoryPairingID")] + accessory_pairing_id: String, + #[serde(rename = "AccessoryLTPK")] + accessory_ltpk: String, + #[serde(rename = "iOSPairingId")] + ios_pairing_id: String, + #[serde(rename = "iOSDeviceLTSK")] + ios_device_ltsk: String, + #[serde(rename = "iOSDeviceLTPK")] + ios_device_ltpk: String, + #[serde(rename = "AccessoryIP")] + accessory_ip: String, + #[serde(rename = "AccessoryPort")] + accessory_port: usize, + #[serde(rename = "Connection")] + connection: ConnectionType, + #[serde(rename = "accessories")] + accessories: Vec, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Accessory { + #[serde(rename = "aid")] + id: usize, + services: Vec, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct AccessoryService { + #[serde(rename = "iid")] + id: usize, + #[serde(rename = "type", deserialize_with = "deserialize_service_type")] + service_type: ServiceType, + primary: bool, + hidden: bool, + characteristics: Vec, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ServiceCharacteristic { + #[serde(rename = "iid")] + id: usize, + #[serde(rename = "type", deserialize_with = "deserialize_characteristic_type")] + characteristic_type: CharacteristicType, + perms: Vec, + #[serde(flatten)] + value: Option, + ev: Option, + enc: Option, + #[serde(rename = "maxDataLen")] + max_data_len: Option, + #[serde(rename = "minValue")] + min_value: Option, + #[serde(rename = "maxValue")] + max_value: Option, + #[serde(rename = "minStep")] + min_step: Option, + unit: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(tag = "format", content = "value")] +pub enum Data { + #[serde(rename = "string")] + String(String), + #[serde(rename = "bool")] + Bool(bool), + #[serde(rename = "data")] + Data(String), + #[serde(rename = "uint32")] + Uint(u32), + #[serde(rename = "float")] + Float(f64), +} + +#[derive(Serialize, Deserialize, Debug, Clone, Copy)] +pub enum ConnectionType { + #[serde(rename = "IP")] + Ip, + #[serde(rename = "BLE")] + Ble, + #[serde(rename = "ADDITIONAL_PAIRING")] + AdditionalPairing, +} + +#[derive(Debug, Error)] +pub enum HomekitError { + #[error("io")] + Io(#[from] std::io::Error), + #[error("serde_json")] + SerdeJson(#[from] serde_json::Error), +} diff --git a/homekit-exporter/Cargo.toml b/homekit-exporter/Cargo.toml new file mode 100644 index 0000000..d7ab2e4 --- /dev/null +++ b/homekit-exporter/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "homekit-exporter" +version = "0.1.0" +edition = "2021" + +[dependencies] +tokio = { version = "1.35.1", features = ["full"] } +env_logger = "0.11" +log = "0.4" +clap = { version = "4.0", features = ["derive"] } +homekit-controller = { path = "../homekit-controller" } diff --git a/homekit-exporter/src/main.rs b/homekit-exporter/src/main.rs new file mode 100644 index 0000000..ebb9ef1 --- /dev/null +++ b/homekit-exporter/src/main.rs @@ -0,0 +1,33 @@ +use std::path::PathBuf; + +use clap::{Parser, Subcommand}; +use homekit_controller::{HomekitController, HomekitError}; + +#[derive(Parser, Debug, Clone)] +#[clap(author, version, about, long_about = None)] +struct Args { + #[command(subcommand)] + command: Commands, + #[clap(long)] + pairing_data: PathBuf, +} + +#[derive(Subcommand, Debug, Clone)] +enum Commands { + /// Run logging server + Watch, + /// List endpoints + ListEndpoints, +} + +#[tokio::main] +async fn main() -> Result<(), HomekitError> { + env_logger::init(); + let args = Args::parse(); + if args.pairing_data.is_file() { + let controller = HomekitController::load(args.pairing_data)?; + } else { + log::error!("{:?} is not a file!", args.pairing_data) + } + Ok(()) +}