Repository: postlund/pyatv
Pull request #2013 (2023-05-26 04:25:06)

Add Apple TV 4k (gen3) and new tvOS versions
Add Apple TV 4k (gen3):
https://www.theiphonewiki.com/wiki/J255AP

Add new tvOS versions:
https://en.wikipedia.org/wiki/TvOS#tvOS_16

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/postlund/pyatv/pull/2013?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl) Report
Patch coverage: **`100.00`**% and project coverage change: **`-0.20`** :warning:
> Comparison is base [(`e538496`)](https://app.codecov.io/gh/postlund/pyatv/commit/e5384967280b203a3807a46127d8aa438e52bc21?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl) 87.67% compared to head [(`eb34341`)](https://app.codecov.io/gh/postlund/pyatv/pull/2013?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl) 87.48%.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #2013      +/-   ##
==========================================
- Coverage   87.67%   87.48%   -0.20%     
==========================================
  Files         154      154              
  Lines        9967     9969       +2     
==========================================
- Hits         8739     8721      -18     
- Misses       1228     1248      +20     
```


| [Impacted Files](https://app.codecov.io/gh/postlund/pyatv/pull/2013?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl) | Coverage Δ | |
|---|---|---|
| [pyatv/convert.py](https://app.codecov.io/gh/postlund/pyatv/pull/2013?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvY29udmVydC5weQ==) | `100.00% <ø> (ø)` | |
| [pyatv/interface.py](https://app.codecov.io/gh/postlund/pyatv/pull/2013?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvaW50ZXJmYWNlLnB5) | `98.81% <ø> (ø)` | |
| [pyatv/support/device\_info.py](https://app.codecov.io/gh/postlund/pyatv/pull/2013?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvc3VwcG9ydC9kZXZpY2VfaW5mby5weQ==) | `100.00% <ø> (ø)` | |
| [pyatv/const.py](https://app.codecov.io/gh/postlund/pyatv/pull/2013?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl#diff-cHlhdHYvY29uc3QucHk=) | `100.00% <100.00%> (ø)` | |

... and [3 files with indirect coverage changes](https://app.codecov.io/gh/postlund/pyatv/pull/2013/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl)


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/postlund/pyatv/pull/2013?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Pierre+St%C3%A5hl).

postlund: Great, thanks for updating! 👍 

Patch:
diff --git a/docs/api/pyatv/const.html b/docs/api/pyatv/const.html
index 44a90de4..739666f5 100644
--- a/docs/api/pyatv/const.html
+++ b/docs/api/pyatv/const.html
@@ -23,6 +23,7 @@ link_group: api
 <li><code><a title="pyatv.const.DeviceModel.AirPortExpress" href="#pyatv.const.DeviceModel.AirPortExpress">AirPortExpress</a></code></li>
 <li><code><a title="pyatv.const.DeviceModel.AirPortExpressGen2" href="#pyatv.const.DeviceModel.AirPortExpressGen2">AirPortExpressGen2</a></code></li>
 <li><code><a title="pyatv.const.DeviceModel.AppleTV4KGen2" href="#pyatv.const.DeviceModel.AppleTV4KGen2">AppleTV4KGen2</a></code></li>
+<li><code><a title="pyatv.const.DeviceModel.AppleTV4KGen3" href="#pyatv.const.DeviceModel.AppleTV4KGen3">AppleTV4KGen3</a></code></li>
 <li><code><a title="pyatv.const.DeviceModel.Gen2" href="#pyatv.const.DeviceModel.Gen2">Gen2</a></code></li>
 <li><code><a title="pyatv.const.DeviceModel.Gen3" href="#pyatv.const.DeviceModel.Gen3">Gen3</a></code></li>
 <li><code><a title="pyatv.const.DeviceModel.Gen4" href="#pyatv.const.DeviceModel.Gen4">Gen4</a></code></li>
@@ -232,6 +233,10 @@ future.</p></section>
 <dd>
 <section class="desc"><p>Device model is sixth generation Apple TV (Apple TV 4K gen 2).</p></section>
 </dd>
+<dt id="pyatv.const.DeviceModel.AppleTV4KGen3"><code class="name">var <span class="ident">AppleTV4KGen3</span></code></dt>
+<dd>
+<section class="desc"><p>Device model is seventh generation Apple TV (Apple TV 4K gen 3).</p></section>
+</dd>
 <dt id="pyatv.const.DeviceModel.Gen2"><code class="name">var <span class="ident">Gen2</span></code></dt>
 <dd>
 <section class="desc"><p>Device model is second generation Apple TV (Apple TV 2).</p></section>
@@ -826,4 +831,4 @@ is Apple TV Software (pre-tvOS).</p></section>
 </article>
 <footer id="footer">
 <p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite>.</p>
-</footer>
\ No newline at end of file
+</footer>
diff --git a/pyatv/const.py b/pyatv/const.py
index ac4203b5..6da2263e 100644
--- a/pyatv/const.py
+++ b/pyatv/const.py
@@ -170,6 +170,9 @@ class DeviceModel(Enum):
     Music = 10
     """Music app (or iTunes) running on a desktop computer."""
 
+    AppleTV4KGen3 = 11
+    """Device model is seventh generation Apple TV (Apple TV 4K gen 3)."""
+
 
 class InputAction(Enum):
     """Type of input when pressing a button."""
diff --git a/pyatv/convert.py b/pyatv/convert.py
index aa125952..d8c330a2 100644
--- a/pyatv/convert.py
+++ b/pyatv/convert.py
@@ -75,4 +75,5 @@ def model_str(device_model: DeviceModel) -> str:
         DeviceModel.AirPortExpressGen2: "AirPort Express (gen 2)",
         DeviceModel.AppleTV4KGen2: "Apple TV 4K (gen2)",
         DeviceModel.Music: "Music/iTunes",
+        DeviceModel.AppleTV4KGen3: "Apple TV 4K (gen3)",
     }.get(device_model, "Unknown")
diff --git a/pyatv/interface.py b/pyatv/interface.py
index 9ea8dc27..44dff902 100644
--- a/pyatv/interface.py
+++ b/pyatv/interface.py
@@ -943,6 +943,7 @@ class DeviceInfo:
             DeviceModel.Gen4,
             DeviceModel.Gen4K,
             DeviceModel.AppleTV4KGen2,
+            DeviceModel.AppleTV4KGen3,
         ]:
             return OperatingSystem.TvOS
 
diff --git a/pyatv/support/device_info.py b/pyatv/support/device_info.py
index 77027203..c47150f7 100644
--- a/pyatv/support/device_info.py
+++ b/pyatv/support/device_info.py
@@ -14,6 +14,7 @@ _MODEL_LIST: Dict[str, DeviceModel] = {
     "AppleTV5,3": DeviceModel.Gen4,
     "AppleTV6,2": DeviceModel.Gen4K,
     "AppleTV11,1": DeviceModel.AppleTV4KGen2,
+    "AppleTV14,1": DeviceModel.AppleTV4KGen3,
     "AudioAccessory1,1": DeviceModel.HomePod,
     "AudioAccessory1,2": DeviceModel.HomePod,
     "AudioAccessory5,1": DeviceModel.HomePodMini,
@@ -27,6 +28,7 @@ _INTERNAL_NAME_LIST: Dict[str, DeviceModel] = {
     "J42dAP": DeviceModel.Gen4,
     "J105aAP": DeviceModel.Gen4K,
     "J305AP": DeviceModel.AppleTV4KGen2,
+    "J255AP": DeviceModel.AppleTV4KGen3,
 }
 
 # Incomplete list here! Only Apple TV version numbers for now.
@@ -48,6 +50,27 @@ _VERSION_LIST: Dict[str, str] = {
     "18L204": "14.5",
     "18L569": "14.6",
     "18M60": "14.7",
+    "19J346": "15.0",
+    "19J572": "15.1",
+    "19J581": "15.1.1",
+    "19K53": "15.2",
+    "19K547": "15.3",
+    "19L440": "15.4",
+    "19L452": "15.4.1",
+    "19L570": "15.5",
+    "19L580": "15.5.1",
+    "19M65": "15.6",
+    "20J373": "16.0",
+    "20K71": "16.1",
+    "20K80": "16.1.1",
+    "20K362": "16.2",
+    "20K650": "16.3",
+    "20K661": "16.3.1",
+    "20K672": "16.3.2",
+    "20K680": "16.3.3",
+    "20L497": "16.4",
+    "20L498": "16.4.1",
+    "20L563": "16.5",
 }
 
 


Test patch:
diff --git a/tests/test_convert.py b/tests/test_convert.py
index 7a21563b..9247fc47 100644
--- a/tests/test_convert.py
+++ b/tests/test_convert.py
@@ -97,6 +97,7 @@ def test_protocol_str(protocol, output):
         (DeviceModel.AirPortExpressGen2, "AirPort Express (gen 2)"),
         (DeviceModel.AppleTV4KGen2, "Apple TV 4K (gen2)"),
         (DeviceModel.Music, "Music/iTunes"),
+        (DeviceModel.AppleTV4KGen3, "Apple TV 4K (gen3)"),
         (1234, "Unknown"),
     ],
 )
diff --git a/tests/test_interface.py b/tests/test_interface.py
index 9fb9db1b..8995a2b6 100644
--- a/tests/test_interface.py
+++ b/tests/test_interface.py
@@ -298,6 +298,7 @@ def test_device_info_bad_types(properties):
         ({DeviceInfo.MODEL: DeviceModel.Gen4}, OperatingSystem.TvOS),
         ({DeviceInfo.MODEL: DeviceModel.Gen4K}, OperatingSystem.TvOS),
         ({DeviceInfo.MODEL: DeviceModel.AppleTV4KGen2}, OperatingSystem.TvOS),
+        ({DeviceInfo.MODEL: DeviceModel.AppleTV4KGen3}, OperatingSystem.TvOS),
     ],
 )
 def test_device_info_guess_os(properties, expected_os):