1
0
mirror of https://github.com/natekspencer/hacs-oasis_mini.git synced 2025-11-14 16:13:51 -05:00

1 Commits

Author SHA1 Message Date
Nathan Spencer
82a6a3cc1d Add temp fix for firmware 2.02 led issue 2025-03-13 04:32:44 +00:00
8 changed files with 2672 additions and 12641 deletions

View File

@@ -61,11 +61,6 @@ DESCRIPTORS = (
translation_key="random_track", translation_key="random_track",
press_fn=play_random_track, press_fn=play_random_track,
), ),
OasisMiniButtonEntityDescription(
key="sleep",
translation_key="sleep",
press_fn=lambda device: device.async_sleep(),
),
) )

View File

@@ -49,8 +49,8 @@ class OasisMiniMediaPlayerEntity(OasisMiniEntity, MediaPlayerEntity):
@property @property
def media_duration(self) -> int | None: def media_duration(self) -> int | None:
"""Duration of current playing media in seconds.""" """Duration of current playing media in seconds."""
if (track := self.device.track) and "reduced_svg_content_new" in track: if (track := self.device.track) and "reduced_svg_content" in track:
return track["reduced_svg_content_new"] return track["reduced_svg_content"].get("1")
return None return None
@property @property

View File

@@ -20,11 +20,9 @@ STATUS_CODE_MAP = {
3: "centering", 3: "centering",
4: "playing", 4: "playing",
5: "paused", 5: "paused",
6: "sleeping",
9: "error", 9: "error",
11: "updating", 11: "updating",
13: "downloading", 13: "downloading",
14: "busy",
15: "live", 15: "live",
} }
@@ -34,7 +32,6 @@ AUTOPLAY_MAP = {
"2": "5 minutes", "2": "5 minutes",
"3": "10 minutes", "3": "10 minutes",
"4": "30 minutes", "4": "30 minutes",
"5": "24 hours",
} }
LED_EFFECTS: Final[dict[str, str]] = { LED_EFFECTS: Final[dict[str, str]] = {
@@ -53,33 +50,6 @@ LED_EFFECTS: Final[dict[str, str]] = {
"12": "Follow Rainbow", "12": "Follow Rainbow",
"13": "Chasing Comet", "13": "Chasing Comet",
"14": "Gradient Follow", "14": "Gradient Follow",
"15": "Cumulative Fill",
"16": "Multi Comets A",
"17": "Rainbow Chaser",
"18": "Twinkle Lights",
"19": "Tennis Game",
"20": "Breathing Exercise 4-7-8",
"21": "Cylon Scanner",
"22": "Palette Mode",
"23": "Aurora Flow",
"24": "Colorful Drops",
"25": "Color Snake",
"26": "Flickering Candles",
"27": "Digital Rain",
"28": "Center Explosion",
"29": "Rainbow Plasma",
"30": "Comet Race",
"31": "Color Waves",
"32": "Meteor Storm",
"33": "Firefly Flicker",
"34": "Ripple",
"35": "Jelly Bean",
"36": "Forest Rain",
"37": "Multi Comets",
"38": "Multi Comets with Background",
"39": "Rainbow Fill",
"40": "White Red Comet",
"41": "Color Comets",
} }
CLOUD_BASE_URL = "https://app.grounded.so" CLOUD_BASE_URL = "https://app.grounded.so"
@@ -144,7 +114,7 @@ class OasisMini:
return None return None
svg_content = decrypt_svg_content(svg_content) svg_content = decrypt_svg_content(svg_content)
paths = svg_content.split("L") paths = svg_content.split("L")
total = self.track.get("reduced_svg_content_new", 0) or len(paths) total = self.track.get("reduced_svg_content", {}).get("1", len(paths))
percent = (100 * self.progress) / total percent = (100 * self.progress) / total
return percent return percent
@@ -258,7 +228,7 @@ class OasisMini:
"max_brightness": _parse_int(values[13 + shift]), "max_brightness": _parse_int(values[13 + shift]),
"wifi_connected": _bit_to_bool(values[14 + shift]), "wifi_connected": _bit_to_bool(values[14 + shift]),
"repeat_playlist": _bit_to_bool(values[15 + shift]), "repeat_playlist": _bit_to_bool(values[15 + shift]),
"autoplay": AUTOPLAY_MAP.get(value := values[16 + shift], value), "autoplay": AUTOPLAY_MAP.get(values[16 + shift]),
"autoclean": _bit_to_bool(values[17 + shift]) "autoclean": _bit_to_bool(values[17 + shift])
if len(values) > 17 if len(values) > 17
else False, else False,
@@ -360,10 +330,6 @@ class OasisMini:
"""Set repeat playlist.""" """Set repeat playlist."""
await self._async_command(params={"WRIREPEATJOB": 1 if repeat else 0}) await self._async_command(params={"WRIREPEATJOB": 1 if repeat else 0})
async def async_sleep(self) -> None:
"""Send sleep command."""
await self._async_command(params={"CMDSLEEP": ""})
async def async_stop(self) -> None: async def async_stop(self) -> None:
"""Send stop command.""" """Send stop command."""
await self._async_command(params={"CMDSTOP": ""}) await self._async_command(params={"CMDSTOP": ""})

File diff suppressed because it is too large Load Diff

View File

@@ -41,7 +41,7 @@ def draw_svg(track: dict, progress: int, model_id: str) -> str | None:
if progress is not None: if progress is not None:
svg_content = decrypt_svg_content(svg_content) svg_content = decrypt_svg_content(svg_content)
paths = svg_content.split("L") paths = svg_content.split("L")
total = track.get("reduced_svg_content_new", 0) or len(paths) total = track.get("reduced_svg_content", {}).get(model_id, len(paths))
percent = min((100 * progress) / total, 100) percent = min((100 * progress) / total, 100)
progress = math.floor((percent / 100) * (len(paths) - 1)) progress = math.floor((percent / 100) * (len(paths) - 1))

View File

@@ -41,9 +41,6 @@
"button": { "button": {
"random_track": { "random_track": {
"name": "Play random track" "name": "Play random track"
},
"sleep": {
"name": "Sleep"
} }
}, },
"binary_sensor": { "binary_sensor": {
@@ -96,11 +93,9 @@
"centering": "Centering", "centering": "Centering",
"playing": "Playing", "playing": "Playing",
"paused": "Paused", "paused": "Paused",
"sleeping": "Sleeping",
"error": "Error", "error": "Error",
"updating": "Updating", "updating": "Updating",
"downloading": "Downloading", "downloading": "Downloading",
"busy": "Busy",
"live": "Live drawing" "live": "Live drawing"
} }
} }

View File

@@ -41,9 +41,6 @@
"button": { "button": {
"random_track": { "random_track": {
"name": "Play random track" "name": "Play random track"
},
"sleep": {
"name": "Sleep"
} }
}, },
"binary_sensor": { "binary_sensor": {
@@ -96,11 +93,9 @@
"centering": "Centering", "centering": "Centering",
"playing": "Playing", "playing": "Playing",
"paused": "Paused", "paused": "Paused",
"sleeping": "Sleeping",
"error": "Error", "error": "Error",
"updating": "Updating", "updating": "Updating",
"downloading": "Downloading", "downloading": "Downloading",
"busy": "Busy",
"live": "Live drawing" "live": "Live drawing"
} }
} }

View File

@@ -13,12 +13,6 @@ from custom_components.oasis_mini.pyoasismini.const import TRACKS
ACCESS_TOKEN = os.getenv("GROUNDED_TOKEN") ACCESS_TOKEN = os.getenv("GROUNDED_TOKEN")
def get_author_name(data: dict) -> str:
"""Get author name from a dict."""
author = (data.get("author") or {}).get("user") or {}
return author.get("name") or author.get("nickname") or "Oasis Mini"
async def update_tracks() -> None: async def update_tracks() -> None:
"""Update tracks.""" """Update tracks."""
client = OasisMini("", ACCESS_TOKEN) client = OasisMini("", ACCESS_TOKEN)
@@ -38,22 +32,23 @@ async def update_tracks() -> None:
for result in filter(lambda d: d["public"], data): for result in filter(lambda d: d["public"], data):
if ( if (
(track_id := result["id"]) not in TRACKS (track_id := result["id"]) not in TRACKS
or any( or result["name"] != TRACKS[track_id].get("name")
result[field] != TRACKS[track_id].get(field) or result["image"] != TRACKS[track_id].get("image")
for field in ("name", "image", "png_image")
)
or TRACKS[track_id].get("author") != get_author_name(result)
): ):
print(f"Updating track {track_id}: {result['name']}") print(f"Updating track {track_id}: {result["name"]}")
track_info = await client.async_cloud_get_track_info(int(track_id)) track_info = await client.async_cloud_get_track_info(int(track_id))
if not track_info: if not track_info:
print("No track info") print("No track info")
break break
result["author"] = get_author_name(result) author = (result.get("author") or {}).get("user") or {}
result["reduced_svg_content_new"] = track_info.get( updated_tracks[track_id] = {
"reduced_svg_content_new" "id": track_id,
) "name": result["name"],
updated_tracks[track_id] = result "author": author.get("name") or author.get("nickname") or "Oasis Mini",
"image": result["image"],
"clean_pattern": track_info.get("cleanPattern", {}).get("id"),
"reduced_svg_content": track_info.get("reduced_svg_content"),
}
await client.session.close() await client.session.close()
if not updated_tracks: if not updated_tracks: