User:Bulek
From LinuxMCE
'Add Ruby snippets to commands'
I've created new IR/Codeset group called "Marantz SR Multiroom RS232", although I'm not sure how to handle it. Have also edited coresponding Ruby snippets for each command. Basically those are just simple strings that get send on rs232 to take proper action on device according to received command from LinuxMCE... There are also a lot of other functions that help :
- determining for which child zone command is targeted - to "normalize" volume levels between Marantz's internal dB units and range of 0-100
Simpler commands from Ruby part of template :
Power #193 Off #SendMultiZoneCommand(cmd, ["@PWR:1", "@MSP:1", "@MAM:2"]) SendMultiZonePowerOffCommand(cmd, ["@AMT:2", "@MSP:1", "@MAM:2"]) #192 On #SendMultiZoneCommand(cmd, ["@PWR:2", "@MSP:2", "@MAM:1"]) SendMultiZonePowerOnCommand(cmd, ["@AMT:1", "@MSP:2", "@MAM:1"]) #194 Toggle Power Inputs #169 AM SendMultiZoneCommand(cmd, ["@SRC:H", "@MSC:H", "@MSC:H"]) #164 Aux SendMultiZoneCommand(cmd, ["@SRC:9", "@MSC:9", "@MSC:9"]) #172 Aux 2 SendMultiZoneCommand(cmd, ["@SRC:A", "@MSC:A", "@MSC:A"]) #162 CD SendMultiZoneCommand(cmd, ["@SRC:C", "@MSC:C", "@MSC:C"]) #420 CDR SendMultiZoneCommand(cmd, ["@SRC:D", "@MSC:D", "@MSC:D"]) #178 DSS SendMultiZoneCommand(cmd, ["@SRC:4", "@MSC:4", "@MSC:4"]) #165 DVD SendMultiZoneCommand(cmd, ["@SRC:2", "@MSC:2", "@MSC:2"]) #170 FM SendMultiZoneCommand(cmd, ["@SRC:G", "@MSC:G", "@MSC:G"]) #160 Tape / Tape 1 SendMultiZoneCommand(cmd, ["@SRC:E", "@MSC:E", "@MSC:E"]) #166 Tuner SendMultiZoneCommand(cmd, ["@SRC:F", "@MSC:F", "@MSC:F"]) #161 TV SendMultiZoneCommand(cmd, ["@SRC:1", "@MSC:1", "@MSC:1"]) #282 VCR-1 SendMultiZoneCommand(cmd, ["@SRC:3", "@MSC:3", "@MSC:3"]) DSP Modes (Audio) #891 All Ch Stereo #<$"@SUR:0H\r"$> SendIrCommand("@SUR:0H") #97 Mute SendMultiZoneCommand(cmd, ["@AMT:0", "@MSM:0", "@MAM:0"]) #90 Vol Down SendMultiZoneCommand(cmd, ["@VOL:2", "@MSV:2", "@MVL:2"]) #89 Vol Up SendMultiZoneCommand(cmd, ["@VOL:1", "@MSV:1", "@MVL:1"]) Speed Ctrl #125 Scan Back/Rewind
More important parts with more Ruby code :
###########################################################3 Internal Methods # To do list : # - parsing of input messages (inputs,mute,volume,power) # - handling of tuner (with live/TV child device) # - to properly send events and set device current volume data def DecodeReceivedInfo_candidate(response) # Examples: Mute/On/Off: @AMT:1,@MSP:2,@MAM:2, Volume: @VOL:-25,@MSV:-56,@MVL:-56 Inputs:@MSC:2E,@SRC:22,@SRC:2E log("DecodeReceivedInfo1: " + response + "\n"); avrcommand = response[1..3] avrvalue = response[5] log("DecodeReceivedInfo2: " + response + " -> Command:"+ avrcommand.to_s + " Value: " + avrvalue.to_s + "\n"); case avrcommand # Input Source changed when 'SRC' log("Main Zone Input Changed to "+ avrvalue.to_s+ "\n"); input_param=0 case avrvalue when '1' log('Main Zone Input Changed to #161: TV') input_param=161 temp_state="Input: TV" when '2' log('Main Zone Input Changed to #165: DVD') input_param=165 temp_state="Input: TV" when '3' log('Main Zone Input Changed to #282: VCR-1') input_param=282 temp_state="Input: TV" when '4' log('Main Zone Input Changed to #178: DSS') input_param=178 temp_state="Input: TV" when '9' log('Main Zone Input Changed to #164: AUX') input_param=164 temp_state="Input: TV" when 'A' log('Main Zone Input Changed to #171: AUX2') input_param=171 temp_state="Input: TV" when 'C' log('Main Zone Input Changed to #162: CD') input_param=162 temp_state="Input: TV" when 'D' log('Main Zone Input Changed to #420: CDR') input_param=420 temp_state="Input: TV" when 'E' log('Main Zone Input Changed to #160: TAPE') input_param=160 temp_state="Input: TV" when 'F' log('Main Zone Input Changed to #166: TUNER') input_param=166 temp_state="Input: TV" when 'G' log('Main Zone Input Changed to #170: FM') input_param=160 temp_state="Input: TV" when 'H' log('Main Zone Input Changed to #169: AM') input_param=169 temp_state="Input: TV" end # device_id = device_.mapPortChannel_Device_.[0.to_s] log("======= Determiming device ID for Zone 0 : " + device_id.to_s + "\n") device_.mapPortChannel_Device_.each do |key, value| log(key.to_s + " => " + value.to_s+ "\n") end cmd = Command.new(device_id, -1001, 1, 2, 49); cmd.params_[41] = input_param.to_s(); SendCommand(cmd); SetDeviceDataInDB( device_id, 200, temp_state ) # 200 = DEVICEDATA_State_CONST when 'VOL' volume = response[5..-1].to_i(); volume_norm = NormalizeVolume_MainZone(volume) log("Main Zone Volume Changed: " + volume.to_s + " Normalized Value: " + volume_norm.to_s + "\n"); # device_id = device_.mapPortChannel_Device_.[0.to_s] log("======= Determiming device ID for Zone 0 : " + device_id.to_s + "\n") device_.mapPortChannel_Device_.each do |key, value| log(key.to_s + " => " + value.to_s+ "\n") end SetDeviceDataInDB( device_id, 158, volume_norm ) # 158 = DEVICEDATA_Volume_Level_CONST cmd = Command.new(device_id, -1001, 1, 2, 71); cmd.params_[30] = volume_norm SendCommand(cmd); when 'PWR' case avrvalue when '1' log("Device Power Changed: OFF"); cmd.params_[10] = "0"; $DevicePower = 0 when '2' log("Device Power Changed: ON"); cmd.params_[10] = "1"; $DevicePower = 1 end cmd = Command.new(device_.devid_, -1001, 1, 2, 48); SendCommand(cmd); else log("Yet not implemented: Handler for command: " + avrcommand.to_s) end end def DecodeReceivedInfo(response) # Examples: Mute/On/Off: @AMT:1,@MSP:2,@MAM:2, Volume: @VOL:-25,@MSV:-56,@MVL:-56 Inputs:@MSC:2E,@SRC:22,@SRC:2E log("DecodeReceivedInfo1: " + response + "\n"); avrcommand = response[1..3] avrvalue = response[5] log("DecodeReceivedInfo2: " + response + " -> Command:"+ avrcommand.to_s + " Value: " + avrvalue.to_s + "\n"); case avrcommand when 'VOL' volume = response[5..-1].to_i(); volume_norm = NormalizeVolume_MainZone(volume) log("Main Zone Volume Changed: " + volume.to_s + " Normalized Value: " + volume_norm.to_s + "\n"); # device_id = device_.mapPortChannel_Device_.[0.to_s] log("======= Determiming device ID for Zone 0 : " + device_id.to_s + "\n") device_.mapPortChannel_Device_.each do |key, value| log(key.to_s + " => " + value.to_s+ "\n") if (key.to_s == "0") device_id = value end end SetDeviceDataInDB( device_id, 158, volume_norm ) # 158 = DEVICEDATA_Volume_Level_CONST cmd = Command.new(device_id, -1001, 1, 2, 71); cmd.params_[30] = volume_norm SendCommand(cmd); when 'PWR' case avrvalue when '1' log("Device Power Changed: OFF") cmd.params_[10] = "0"; $DevicePower = 0 when '2' log("Device Power Changed: ON"); cmd.params_[10] = "1"; $DevicePower = 1 end cmd = Command.new(device_.devid_, -1001, 1, 2, 48); SendCommand(cmd); else log("Yet not implemented: Handler for command: " + avrcommand.to_s) end end def ReceiveReportCommand() @buff = conn_.RecvDelimited("\r", 1000) log("Cmd response from Marantz: " + @buff + "\n") log("Calling DecodeReceivedInfo: " + @buff + "\n") temp_resp=@buff; DecodeReceivedInfo(temp_resp) log("End of DecodeReceivedInfo: " + temp_resp + "\n") end def SendIrCommand(command) log("SendIrCommand: " + command + "\n") conn_.Send(command+ "\r") log("Sending Command: " + command + "\n") ReceiveReportCommand() end def log(line) # $log = File.open("/var/log/pluto/" + device_.devid_.to_s + "_Generic_Serial_Device.log", "a") $log = File.open("/var/log/pluto/Marantz_SR5600.log", "a") logTime = Time.now timeStr = logTime.strftime("%d-%m-%Y %H:%M:%S ") $log.puts timeStr + "(***):" + line.to_s $log.close end def SendMultiZoneCommand(cmd, commandsArray, commandParam="") log("Got Command with ID: " + cmd.id_.to_s + " from: " + cmd.devidfrom_.to_s + " to: " + cmd.devidto_.to_s + "\n") zone = GetZone(cmd.devidto_) if( zone >= 0 and zone < commandsArray.size ) zone_desc=device_.childdevices_[cmd.devidto_].devdata_[186] log("Determine zone for command : " + zone_desc + "[" + zone.to_s + "]\n") SendIrCommand(commandsArray[zone] + commandParam.to_s) else log("SendMultiZoneCommand: invalid zone " + zone.to_s + ". Send commands only to valid child devices!!!") end end def SendMultiZonePowerOnCommand(cmd, commandsArray, commandParam="") #It will Unmute Zone first and then see also global power should be turned on... log("Got Power On Command with ID: " + cmd.id_.to_s + " from: " + cmd.devidfrom_.to_s + " to: " + cmd.devidto_.to_s + "\n") zone = GetZone(cmd.devidto_) if( zone >= 0 and zone < commandsArray.size ) zone_desc=device_.childdevices_[cmd.devidto_].devdata_[186] log("Determine zone for command : " + zone_desc + "[" + zone.to_s + "]\n") SendIrCommand(commandsArray[zone] + commandParam.to_s) $ZoneStatus[zone.to_s] = 'ON' log("*** Setting zone : " + zone_desc + "[" + zone.to_s + "] to ON\n") ShowZones() if ($DevicePower == 0) SendIrCommand("@PWR:2") end $DevicePower = 1 elsif (zone == -1) if ($DevicePower == 0) SendIrCommand("@PWR:2") end $DevicePower = 1 log("####### Powering device On\n") else log("SendMultiZonePowerOnCommand: invalid zone " + zone.to_s + ". Send commands only to valid child devices!!!") end end def SendMultiZonePowerOffCommand(cmd, commandsArray, commandParam="") #It will Mute Zone first and then see if also global power can be turned off... log("Got Power Off Command with ID: " + cmd.id_.to_s + " from: " + cmd.devidfrom_.to_s + " to: " + cmd.devidto_.to_s + "\n") zone = GetZone(cmd.devidto_) if( zone >= 0 and zone < commandsArray.size ) zone_desc=device_.childdevices_[cmd.devidto_].devdata_[186] log("Determine zone for command : " + zone_desc + "[" + zone.to_s + "]\n") SendIrCommand(commandsArray[zone] + commandParam.to_s) $ZoneStatus[zone.to_s] = 'OFF' log("*** Setting zone : " + zone_desc + "[" + zone.to_s + "] to OFF\n") ShowZones() if (($ZoneStatus["0"] == 'OFF') and ($ZoneStatus["1"] == 'OFF') and ($ZoneStatus["2"] == 'OFF')) SendIrCommand("@PWR:1") $DevicePower = 0 log("####### All zones are muted - device is powered Off\n") end else log("SendMultiZonePowerOffCommand: invalid zone " + zone.to_s + ". Send commands only to valid child devices!!!") end end def GetZone(deviceDestination) if( device_.mapDevice_PortChannel_.has_key?(deviceDestination) and device_.mapDevice_PortChannel_[deviceDestination] != nil and !device_.mapDevice_PortChannel_[deviceDestination].empty? ) return device_.mapDevice_PortChannel_[deviceDestination].to_i end return -1 end def ShowZonesDebug() log("####### Dev 2 PortChanel\n") device_.mapDevice_PortChannel_.each do |key, value| log(key.to_s + " => " + value.to_s + "\n") end log("======= PortChanel 2 Dev\n") device_.mapPortChannel_Device_.each do |key, value| log(key.to_s + " => " + value.to_s+ "\n") end end def ShowZonesInitialVolumes() log("####### Show Initial Volume Levels for zones\n") device_.mapDevice_PortChannel_.each do |key, value| volume = device_.childdevices_[key].devdata_[208] log("Zone " + value.to_s + " => " + volume.to_s + "\n") SetVolumeInZone(volume,value) end end def ShowZones() temp = "####### Zones Status : " device_.mapDevice_PortChannel_.each do |key, value| temp = temp + " | Zone " + value.to_s + " => " + $ZoneStatus[value] end temp = temp + "\n" log(temp) end def SetZones(state) log("####### Setting all zones to " + state + "\n") device_.mapDevice_PortChannel_.each do |key, value| $ZoneStatus[value] = state log("Zone " + value.to_s + " => " + state + "\n") end end def InitZones() log("####### Initializing all zones to OFF\n") device_.mapDevice_PortChannel_.each do |key, value| $ZoneStatus[value] = 'OFF' log("Zone " + value.to_s + " => " + $ZoneStatus[value] + "\n") end log("####### Print $ZoneStatus Hash:\n") $ZoneStatus.each do |key, value| log("Zone " + key.to_s + " => " + value.to_s + "\n") end end def SetVolumeInZone(level,zone) # Sets Normalized Volume Level (0..100) in certain zone log("SetVolumeInZone: volume: " + level.to_s + " => Zone: " + zone + "\n") if ( zone == "0") log("SetVolumeInZone0: volume: " + level.to_s + " => Zone: " + zone + "\n") new_level = DeNormalizeVolume_MainZone(level.to_i) log("SetVolumeInZone00: volume: " + level.to_s + " => Zone: " + zone + "\n") temp_str="@VOL:0"+new_level.to_s; log("SetVolumeInZone: About to send command :" + temp_str + "\n") SendIrCommand(temp_str) elsif ( zone == "1") log("SetVolumeInZone1: volume: " + level.to_s + " => Zone: " + zone + "\n") new_level = DeNormalizeVolume_OtherZone(level.to_i) log("SetVolumeInZone11: volume: " + level.to_s + " => Zone: " + zone + "\n") temp_str="@MSV:0"+new_level.to_s; log("SetVolumeInZone: About to send command :" + temp_str + "\n") SendIrCommand(temp_str) elsif ( zone == "2") log("SetVolumeInZone2: volume: " + level.to_s + " => Zone: " + zone + "\n") new_level = DeNormalizeVolume_OtherZone(level.to_i) # log("SetVolumeInZone22: volume: " + level + " => Zone: " + zone + "\n") temp_str="@MVL:0"+new_level.to_s; log("SetVolumeInZone: About to send command :" + temp_str + "\n") SendIrCommand(temp_str) else log("SetVolumeInZone: invalid zone " + zone.to_s + ". Send commands only to valid child devices!!!") end log("SetVolumeInZone End: volume: " + level.to_s + " => Zone: " + zone + "\n") end def NormalizeVolume_MainZone(level) # Normalizes Marantz Volume Level (-99..+10) to 0-100 boundaries for Main Zone temp = (level+100)/110.0*100.0 temp=temp.round log("Normalizing Main Zone Volume Level from : " + level.to_s + " to " + temp.to_s + "\n") return temp end def NormalizeVolume_OtherZone(level) # Normalizes Marantz Volume Level to 0-100 boundaries for Second Zone (-90..0) temp = ((level+90.0)/90.0)*100.0 temp=temp.round log("Normalizing Other Zone Volume Level from : " + level.to_s + " to " + temp.to_s + "\n") return temp end def DeNormalizeVolume_MainZone(level) # DeNormalizes volume level in 0-100 boundaries to Marantz Volume Level (-99..+10) for Main Zone temp = (level/100.0)*110.0-99 temp=temp.round log("DeNormalizing Main Zone Volume Level from : " + level.to_s + " to " + temp.to_s + "\n") return temp end def DeNormalizeVolume_OtherZone(level) # DeNormalizes volume level in 0-100 boundaries to Marantz Volume Level (-90..0) for Other Zone temp = ((level/100.0)*90.0)-90.0 temp=temp.round log("DeNormalizing Other Zone Volume Level from : " + level.to_s + " to " + temp.to_s + "\n") return temp end ###########################################################Process Incoming Data @buff = conn_.RecvDelimited("\r", 1000) log("Info from Marantz: " + @buff + "\n") temp_line=@buff log("1Calling DecodeReceivedInfo: " + temp_line + "\n") DecodeReceivedInfo(temp_line) log("1End of DecodeReceivedInfo: " + temp_line+ "\n") ###########################################################Set Tuner Frequency identifier = cmd.params_[216] # Main Frequency "TFQ:0xxxxx" from 08700 till + 10800 # Multiroom Frequency “MTF:0xxxxx“ from 08700 till + 10800 # switch to tuner mode first SendMultiZoneCommand(cmd, ["@SRC:G", "@MSC:G", "@MSC:G"]) # tune to desired frequency SendMultiZoneCommand(cmd, ["@TFQ:0"+identifier, "@MTF:0"+identifier, "@MTF:0"+identifier]) log("Sending Marantz : Setting tuner frequency to "+identifier+"\n") ###########################################################313 Set Volume command level = cmd.params_[76] # Main volume “VOL:0xxx” from - 99 till + 18 # Multiroom Speakers "MSV:0xxx" from - 99 till + 0 # Multiroom Speakers “MVL:0xxx” from - 99 till + 0 zone = GetZone(cmd.devidto_) log("313:Set Volume Command: Got Cmd with ID: " + cmd.id_.to_s + " from: " + cmd.devidfrom_.to_s + " to: " + cmd.devidto_.to_s + " | Zone : " + zone.to_s + "\n") if ( zone == 0) new_level = DeNormalizeVolume_MainZone(level.to_i) temp_str = "@VOL:0"+new_level.to_s log("SetVolumeCommand: About to send command :" + temp_str + "\n") SendIrCommand(temp_str) elsif ( zone == 1) new_level = DeNormalizeVolume_OtherZone(level.to_i) temp_str = "@MSV:0"+new_level.to_s SendIrCommand(temp_str) elsif ( zone == 2) new_level = DeNormalizeVolume_OtherZone(level.to_i) temp_str = "@MVL:0"+new_level.to_s log("SetVolumeCommand: About to send command :" + temp_str + "\n") SendIrCommand(temp_str) else log("SetVolumeCommand: invalid zone " + zone.to_s + ":" + zone.to_i + ". Send commands only to valid child devices!!!\n") end ###########################################################Process Initialize $DevicePower = 1 SendIrCommand("@PWR:2") log("Initializing Marantz GSD Device\n") SendIrCommand("@AST:F") # max level of feedback SendIrCommand("@MPW:2") # multi room always on SendIrCommand("@MSP:1") # turn multi room speakers off by default SendIrCommand("@MAM:2") # mute multi room line out by default SendIrCommand("@VOL:0-20") # default main volume -20 SendIrCommand("@MSV:0-60") # default multi speaker volume SendIrCommand("@MVL:0-60") # default multi room line out volume $ZoneStatus = Hash.new() InitZones() ShowZonesInitialVolumes() #$DevicePower = 0 #SendIrCommand("@PWR:1") log("Initialization of Marantz GSD Device finished - Device is powered off!!!!\n")