Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support mute volume on linux #106

Merged
merged 1 commit into from
Mar 27, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 35 additions & 15 deletions IoTuring/Entity/Deployments/Volume/Volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from IoTuring.Entity.Entity import Entity
from IoTuring.Entity.EntityData import EntityCommand, EntitySensor
from IoTuring.Entity.ValueFormat import ValueFormatter, ValueFormatterOptions
from IoTuring.Entity.ValueFormat import ValueFormatterOptions
from IoTuring.MyApp.SystemConsts import OperatingSystemDetection as OsD

KEY_STATE = 'volume_state'
Expand All @@ -20,19 +20,18 @@
OsD.MACOS: 'osascript -e "set volume output volume {}"'
}

UNMUTE_PREFIX_LINUX = 'pactl set-sink-mute @DEFAULT_SINK@ 0'


class Volume(Entity):
NAME = "Volume"

def Initialize(self):

# Extra attributes only on macos:
extra_attributes = OsD.IsMacos()

# Register:
self.RegisterEntitySensor(EntitySensor(
self, KEY_STATE,
supportsExtraAttributes=extra_attributes,
supportsExtraAttributes=True,
valueFormatterOptions=VALUEFORMATTEROPTIONS_PERCENTAGE_ROUND0))
self.RegisterEntityCommand(EntityCommand(
self, KEY_CMD, self.Callback, KEY_STATE))
Expand All @@ -41,14 +40,29 @@ def Update(self):
if OsD.IsMacos():
self.UpdateMac()
elif OsD.IsLinux():
# Example: 'Volume: front-left: 39745 / 61% / -13,03 dB, ...
# Only care about the first percent.
p = self.RunCommand(command="pactl get-sink-volume @DEFAULT_SINK@",
# Check if it's muted:
p = self.RunCommand(command="pactl get-sink-mute @DEFAULT_SINK@",
shell=True)
m = re.search(r"/ +(\d{1,3})% /", p.stdout)
if m:
volume = m.group(1)
self.SetEntitySensorValue(KEY_STATE, volume)
output_muted = bool(re.search("Mute: yes", p.stdout))

if output_muted:
output_volume = 0

else:
# Example: 'Volume: front-left: 39745 / 61% / -13,03 dB, ...
# Only care about the first percent.
p = self.RunCommand(command="pactl get-sink-volume @DEFAULT_SINK@",
shell=True)
m = re.search(r"/ +(\d{1,3})% /", p.stdout)

if not m:
raise Exception(f"Error getting volume from {p.stdout}")

output_volume = m.group(1)

self.SetEntitySensorValue(KEY_STATE, output_volume)
self.SetEntitySensorExtraAttribute(
KEY_STATE, EXTRA_KEY_MUTED_OUTPUT, output_muted)

def Callback(self, message):
payloadString = message.payload.decode('utf-8')
Expand All @@ -57,9 +71,15 @@ def Callback(self, message):
volume = int(payloadString)
if not 0 <= volume <= 100:
raise Exception('Incorrect payload!')
else:
self.RunCommand(command=commands[OsD.GetOs()].format(volume),
shell=True)

cmd = commands[OsD.GetOs()]

# Unmute on Linux:
if 0 < volume and OsD.IsLinux():
cmd = UNMUTE_PREFIX_LINUX + " && " + cmd

self.RunCommand(command=cmd.format(volume),
shell=True)

def UpdateMac(self):
# result like: output volume:44, input volume:89, alert volume:100, output muted:false
Expand Down
Loading