Class: SonyCameraRemoteAPI::CameraAPIGroupManager
- Inherits:
-
Object
- Object
- SonyCameraRemoteAPI::CameraAPIGroupManager
- Defined in:
- lib/sony_camera_remote_api/camera_api_group.rb,
lib/sony_camera_remote_api/camera_api_group_def.rb
Overview
Camera API group sublayer class, which is included in Camera API layer class. This class handles API groups that get/set specific parameters of the camera.
Defined Under Namespace
Classes: APIGroup
Constant Summary collapse
- @@api_groups_all =
{ ShootMode: APIGroup.new(:ShootMode, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, end_condition: ->(v, r) { r[21]['currentShootMode'] == v }, ), # setLiveviewSize API does not exist: we use startLiveviewWithSize API instead. LiveviewSize: APIGroup.new(:LiveviewSize, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, nil, ), ZoomSetting: APIGroup.new(:ZoomSetting, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['zoom'] }, ->(v, avl, cond) { [{ 'zoom' => v }] }, ), TrackingFocus: APIGroup.new(:TrackingFocus, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['trackingFocus'] }, ->(v, avl, cond) { [{ 'trackingFocus' => v }] }, ), ContShootingMode: APIGroup.new(:ContShootingMode, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['contShootingMode'] }, ->(v, avl, cond) { [{ 'contShootingMode' => v }] }, end_condition: ->(v, r) { r[38]['contShootingMode'] == v }, ), ContShootingSpeed: APIGroup.new(:ContShootingSpeed, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['contShootingSpeed'] }, ->(v, avl, cond) { [{ 'contShootingSpeed' => v }] }, end_condition: ->(v, r) { r[39]['contShootingSpeed'] == v }, ), SelfTimer: APIGroup.new(:SelfTimer, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, ), ExposureMode: APIGroup.new(:ExposureMode, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, ), FocusMode: APIGroup.new(:FocusMode, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, ), # Handle parameter value by EV instead of exposure compensation index value. ExposureCompensation: APIGroup.new(:ExposureCompensation, # Get supported exposure compensation Array by EV. ->(r, cond) do ev_list = [] r.transpose.each do | max, min, step | step = get_exposure_compensation_step step next if step == 0 ev_list << (min..max).map { |e| (e * step).round(1) } end ev_list.size == 1 ? ev_list[0] : ev_list end, # Get available exposure compensation Array by EV. ->(r, cond) do max, min, step = r[1..-1] step = get_exposure_compensation_step step (min..max).map { |e| (e * step).round(1) } end, # Get current exposure compensation by EV. ->(r, cond) do step = cond[25]['stepIndexOfExposureCompensation'] step = get_exposure_compensation_step step (r[0] * step).round(1) end, # Set exposure compensation By index from EV. ->(v, avl, cond) do avl.index(v) - avl.index(0) end, # Get exposure compensation step. start_condition: ->(r) do r[25]['stepIndexOfExposureCompensation'] != nil end, ), FNumber: APIGroup.new(:FNumber, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, end_condition: ->(v, r) { r[27]['currentFNumber'] == v }, ), ShutterSpeed: APIGroup.new(:ShutterSpeed, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, end_condition: ->(v, r) { r[32]['currentShutterSpeed'] == v }, ), IsoSpeedRate: APIGroup.new(:IsoSpeedRate, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, end_condition: ->(v, r) { r[29]['currentIsoSpeedRate'] == v }, ), # Enable more intuitive parameter format as followings: # * Hash-1 : { 'whiteBalanceMode' => mode, 'colorTemperature' => color-temperature } # * Hash-2 : { whiteBalanceMode: mode, colorTemperature: color-temperature} # * Array (original): [ mode, temperature-enabled-flag, color-temperature ] WhiteBalance: APIGroup.new(:WhiteBalance, # Get supported white-balance mode by Array of Hash. # * delete 'colorTemperatureRange' key if unneeded. # * get color temperature list rather than min/max/step. ->(r, cond) do mode_temp_list = [] r[0].map do |e| mt = {} mt['whiteBalanceMode'] = e['whiteBalanceMode'] if e['colorTemperatureRange'].present? max, min, step = e['colorTemperatureRange'] mt['colorTemperature'] = (min..max).step(step).to_a end mode_temp_list << mt end mode_temp_list end, # Get available white-balance mode by Array of Hash, almost same as supported-accessor. ->(r, cond) do mode_temp_list = [] r[1].map do |e| mt = {} mt['whiteBalanceMode'] = e['whiteBalanceMode'] if e['colorTemperatureRange'].present? max, min, step = e['colorTemperatureRange'] mt['colorTemperature'] = (min..max).step(step).to_a end mode_temp_list << mt end mode_temp_list end, # Get current white-balance mode and temperature by Hash. # temperature key is deleted if unneeded. ->(r, cond) do r[0].delete_if { |k,v| k == 'colorTemperature' and v == -1 } end, # Set white-balance mode, converting Hash-1 to Array. ->(v, avl, cond) do temp_flag = v.key?('colorTemperature') ? true : false temperature = v.key?('colorTemperature') ? v['colorTemperature'] : 0 [v['whiteBalanceMode'], temp_flag, temperature] end, # Accept the parameter forms as followings: # Array and Hash-2 is converted to Hash-1. preprocess_value: ->(v, arg, cond) do if v.is_a? Array ret = {} ret['whiteBalanceMode'] = v[0] ret['colorTemperature'] = v[2] if v[1] == true ret elsif v.is_a? Hash Hash[v.map { |k, v| [k.is_a?(Symbol) ? k.to_s : k , v] }] end end, # Check the given value is available by # * comparing mode # * color temperature value is included in 'colorTemperature' array # when Color Temperature mode check_availability: ->(v, avl, cond) do # check mode sel = avl.find {|e| v['whiteBalanceMode'] == e['whiteBalanceMode'] } return false if sel.nil? if sel.key? 'colorTemperatureRange' # temperature return true if sel['colorTemperature'].include? v['colorTemperature'] false else true end end, ), # ProgramShift: APIGroup.new(:ProgramShift, # ->(v, cond){ v[0] }, # ->(v, cond){ v[1] }, # ->(v, cond){ v[0] }, # ->(v, avl, cond){ [v] }, # ), FlashMode: APIGroup.new(:FlashMode, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] } ), # Enable more intuitive parameter format as followings: # * Hash-1 : { 'aspect' => aspect, 'size' => size } # * Hash-2 : { aspect: aspect, size: size } # * Array (original) : [ aspect, size ] # make setStillSize accept Hash as parameter, because getSupported/AvailableStillSize returns Hash StillSize: APIGroup.new(:StillSize, # Get supported still size and aspect by Array of Hash. ->(r, cond) { r[0] }, # Get available still size and aspect by Array of Hash. ->(r, cond) { r[1] }, # Get current still size and aspect by Hash. ->(r, cond) { r[0] }, # Set still size and aspect, converting Hash-1 to Array. ->(v, avl, cond) { [v['aspect'], v['size']] }, # Accept the parameter forms as followings: # Array and Hash-2 is converted to Hash-1. preprocess_value: ->(v, arg, cond) do if v.is_a? Array ret = {} ret['aspect'] = v[0] ret['size'] = v[1] ret elsif v.is_a? Hash Hash[v.map { |k, v| [k.is_a?(Symbol) ? k.to_s : k , v] }] end end, ), StillQuality: APIGroup.new(:StillQuality, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['stillQuality'] }, ->(v, avl, cond) { [{ 'stillQuality' => v }] }, ), PostviewImageSize: APIGroup.new(:PostviewImageSize, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, ), MovieFileFormat: APIGroup.new(:MovieFileFormat, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['movieFileFormat'] }, ->(v, avl, cond) { [{ 'movieFileFormat' => v }] }, end_condition: ->(v, r) { r[45]['movieFileFormat'] == v }, ), MovieQuality: APIGroup.new(:MovieQuality, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, end_condition: ->(v, r) { r[13]['currentMovieQuality'] == v }, ), SteadyMode: APIGroup.new(:SteadyMode, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, ), ViewAngle: APIGroup.new(:ViewAngle, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, ), SceneSelection: APIGroup.new(:SceneSelection, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['scene'] }, ->(v, avl, cond) { [{ 'scene' => v }] }, ), ColorSetting: APIGroup.new(:ColorSetting, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['colorSetting'] }, ->(v, avl, cond) { [{ 'colorSetting' => v }] }, ), IntervalTime: APIGroup.new(:IntervalTime, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['intervalTimeSec'] }, ->(v, avl, cond) { [{ 'intervalTimeSec' => v }] }, ), LoopRecTime: APIGroup.new(:LoopRecTime, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['loopRecTimeMin'] }, ->(v, avl, cond) { [{ 'loopRecTimeMin' => v }] }, ), WindNoiseReduction: APIGroup.new(:WindNoiseReduction, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['windNoiseReduction'] }, ->(v, avl, cond) { [{ 'windNoiseReduction' => v }] }, ), AudioRecording: APIGroup.new(:AudioRecording, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['audioRecording'] }, ->(v, avl, cond) { [{ 'audioRecording' => v }] }, ), FlipSetting: APIGroup.new(:FlipSetting, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['flip'] }, ->(v, avl, cond) { [{ 'flip' => v }] }, ), TvColorSystem: APIGroup.new(:TvColorSystem, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['tvColorSystem'] }, ->(v, avl, cond) { [{ 'tvColorSystem' => v }] }, ), # 'cameraFunctionResult' does not work depending on the timing of setCameraFunction call... CameraFunction: APIGroup.new(:CameraFunction, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, end_condition: ->(v, r) do # r[15]['cameraFunctionResult'] == 'Success' r[12]['currentCameraFunction'] == v end ), InfraredRemoteControl: APIGroup.new(:InfraredRemoteControl, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['infraredRemoteControl'] }, ->(v, avl, cond) { [{ 'infraredRemoteControl' => v }] }, ), AutoPowerOff: APIGroup.new(:AutoPowerOff, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['candidate'] }, ->(r, cond) { r[0]['autoPowerOff'] }, ->(v, avl, cond) { [{ 'autoPowerOff' => v }] }, ), BeepMode: APIGroup.new(:BeepMode, ->(r, cond) { r[0] }, ->(r, cond) { r[1] }, ->(r, cond) { r[0] }, ->(v, avl, cond) { [v] }, ), }
Class Method Summary collapse
-
.get_exposure_compensation_step(step) ⇒ Object
Convert exposure compensation step of ExposureCompensation API group into the real step.
Instance Method Summary collapse
-
#get_current(group_name, **opts) ⇒ Object
Get current value of a camera parameter.
-
#get_current!(group_name, **opts) ⇒ Object
Almost same as get_current, but this method does not raise Exception even if the parameter is not supported, available or its arguments illegal.
-
#get_parameter(group_name, available: true, supported: true, **opts) ⇒ Hash
Get supported/available/current value of a camera parameter.
-
#get_parameter!(group_name, **opts) ⇒ Object
Almost same as get_parameter, but this method does not raise Exception even if the parameter is not supported, available or its arguments illegal.
-
#initialize(camera_api_manager) ⇒ CameraAPIGroupManager
constructor
Create CameraAPIManager object.
-
#set_parameter(group_name, value, *args, **opts) ⇒ Hash
Set a camera parameter to the given value.
-
#set_parameter!(group_name, value, **opts) ⇒ Object
Almost same as set_parameter, but this method does not raise Exception even if the parameter is not supported, available or its arguments illegal.
-
#support_group?(group_name) ⇒ Boolean
Returns whether the parameter is supported or not.
Methods included from Utils
generate_sequencial_filenames, get_next_file_number, partial_and_unique_match, print_array_in_columns
Methods included from Logging
configure_logger_for, #log, log_file, logger_for, #output_to
Constructor Details
#initialize(camera_api_manager) ⇒ CameraAPIGroupManager
Create CameraAPIManager object.
127 128 129 130 |
# File 'lib/sony_camera_remote_api/camera_api_group.rb', line 127 def initialize(camera_api_manager) @api_manager = camera_api_manager @api_groups = make_api_group_list camera_api_manager.apis end |
Class Method Details
.get_exposure_compensation_step(step) ⇒ Object
Convert exposure compensation step of ExposureCompensation API group into the real step.
5 6 7 8 9 10 11 |
# File 'lib/sony_camera_remote_api/camera_api_group_def.rb', line 5 def self.get_exposure_compensation_step(step) case step when 1 then 0.33 when 2 then 0.5 else 0 end end |
Instance Method Details
#get_current(group_name, **opts) ⇒ Object
Get current value of a camera parameter.
137 138 139 |
# File 'lib/sony_camera_remote_api/camera_api_group.rb', line 137 def get_current(group_name, **opts) get_parameter(group_name, available: false, supported: false, **opts)[:current] end |
#get_current!(group_name, **opts) ⇒ Object
Almost same as get_current, but this method does not raise Exception even if the parameter is not supported, available or its arguments illegal.
146 147 148 |
# File 'lib/sony_camera_remote_api/camera_api_group.rb', line 146 def get_current!(group_name, **opts) get_parameter!(group_name, available: false, supported: false, **opts)[:current] end |
#get_parameter(group_name, available: true, supported: true, **opts) ⇒ Hash
Get supported/available/current value of a camera parameter.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/sony_camera_remote_api/camera_api_group.rb', line 157 def get_parameter(group_name, available: true, supported: true, **opts) result = { current: nil, available: [], supported: [] } begin grp = search_group group_name rescue APIForbidden, APINotSupported => e raise e.class.new(result), e. end condition = grp.start_condition(@api_manager) begin result.merge! grp.current_value(@api_manager, condition, **opts) rescue APINotAvailable, IllegalArgument => e raise e.class.new(result), e. end begin # Timeout is set shorter than usual for getting hardware-affected parameter. result.merge! grp.available_values(@api_manager, condition, timeout: 1, **opts) if available result.merge! grp.supported_values(@api_manager, condition, timeout: 1, **opts) if supported rescue APINotAvailable, IllegalArgument => e # Comes here if the parameter is hardware-affected. end result end |
#get_parameter!(group_name, **opts) ⇒ Object
Almost same as get_parameter, but this method does not raise Exception even if the parameter is not supported, available or its arguments illegal.
183 184 185 186 187 188 189 190 |
# File 'lib/sony_camera_remote_api/camera_api_group.rb', line 183 def get_parameter!(group_name, **opts) get_parameter(group_name, **opts) rescue APIForbidden, APINotSupported, APINotAvailable, IllegalArgument => e log.error e. e.object rescue HTTPClient::BadResponseError => e log.error e. end |
#set_parameter(group_name, value, *args, **opts) ⇒ Hash
Set a camera parameter to the given value.
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/sony_camera_remote_api/camera_api_group.rb', line 198 def set_parameter(group_name, value, *args, **opts) result = { current: nil, available: [], old: nil } begin grp = search_group group_name rescue APIForbidden, APINotSupported => e raise e.class.new(result), e. end condition = grp.start_condition(@api_manager) begin value = grp.preprocess_value(value, args, condition) # If value is equal to current value, do nothing. result.merge! grp.current_value(@api_manager, condition, **opts) result[:old] = result[:current] if grp.eq_current? value, result[:current], condition return result end # If not, check if the value is available. result.merge! grp.available_values(@api_manager, condition, **opts) if grp.is_available? value, result[:available], condition # Save current value and call set API. result[:old] = result[:current] result.merge! grp.set_value(@api_manager, value, result[:available], condition) else # If the value is not available, raise error. raise IllegalArgument.new, "The value '#{value}' is not available for parameter '#{group_name}'. current: #{result[:current]}, available: #{result[:available]}" end rescue APINotAvailable, IllegalArgument => e raise e.class.new(result), e. end result end |
#set_parameter!(group_name, value, **opts) ⇒ Object
Almost same as set_parameter, but this method does not raise Exception even if the parameter is not supported, available or its arguments illegal.
234 235 236 237 238 239 240 241 |
# File 'lib/sony_camera_remote_api/camera_api_group.rb', line 234 def set_parameter!(group_name, value, **opts) set_parameter(group_name, value, **opts) rescue APIForbidden, APINotSupported, APINotAvailable, IllegalArgument => e log.error e. e.object rescue HTTPClient::BadResponseError => e log.error e. end |
#support_group?(group_name) ⇒ Boolean
Returns whether the parameter is supported or not.
246 247 248 |
# File 'lib/sony_camera_remote_api/camera_api_group.rb', line 246 def support_group?(group_name) @api_groups.key? group_name end |