1543411337077 true 1646488154627 114 115 ContextChanged 3050 0 %modes_contexts 1485323611359 true 1590293383258 130 true 137 138 Headphones-Example 30 1544825256683 true 1629861081403 144 true 143 CheckForModesUpdate 2 6 165 %modes_updatecheck 2 true 1544301750876 true 1628065949892 148 true 187 ModesMediaOverride 3050 0 %VOLM 1646488205355 true 1646488205355 8 184 115 ContextCleared 3060 0 %Modes_Contexts 1545541948475 true 1629861645518 51 52 MonitorStart 50 307 0 1443816148810 true 1570590264884 55 true 56 57 Night-Example 1469483841722 Modes 51,114,184,55,148,144,130 175,115,187,52,113,180,138,154,60,9,83,202,186,18,143,112,56,201,39,34,82,192,140,137,181,57,20,13 false Modes - A contextual settings framework to streamline the process of changing settings based on your current situation. GitHub page with more details: https://github.com/jhotmann/tasker-phone-modes

false

Setup
1543115059459 1637607784568 112 AddToContext 100 true 129 const par1 = local('par1'); const par2 = local('par2'); let context = global('Modes_Contexts').split(',').filter(c => c.length > 0); if (par1) { switch (par2) { case ('if-not-exist'): case ('if-not-exists'): { if (context.indexOf(par1) === -1) appendToContext(par1); break; } case (par2.match(/^max-count=\d+$/) || {}).input: { let maxCount = parseInt(par2.toLowerCase().replace('max-count=', '')); if (maxCount) { let currentCount = context.filter((c) => { return c === par1; }).length; if (currentCount < maxCount) appendToContext(par1); } break; } default: { appendToContext(par1); } } } function appendToContext(c) { context.push(c); setGlobal('Modes_Contexts', context.join(',')); } %par1 12 mw_av_playlist_add 1543115059459 1646488127512 113 RemoveFromContext 100 true 129 const par1 = local('par1'); const par2 = local('par2') || ''; let context = global('Modes_Contexts').split(',').filter(c => c.length > 0); let index = context.indexOf(par1); if (index > -1) { if (par2.toLowerCase() === 'all') { // remove all occurances while (index > -1) { context.splice(index, 1); index = context.indexOf(par1); } setGlobal('Modes_Contexts', context.join(',')); } else { // remove first occurance context.splice(index, 1); setGlobal('Modes_Contexts', context.join(',')); } } %par1 12 mw_av_playlist_play 1543411345625 1646870976978 115 ContextChanged 100 2 true 30 129 let version = '1.9.0'; setGlobal('Modes_Version', version); const ALL_CONFIGS = JSON.parse(global('Modes_Configs')); const DEFAULT_CONTEXT = global('Modes_DefaultContext'); let contexts = global('Modes_Contexts').split(',').filter(c => { return (c !== '') }); let previousContexts = global('Modes_ActiveContexts').split(',').filter(c => { return (c !== '') }); // Filter down to only configs in %Modes_Contexts let configs = ALL_CONFIGS.filter(c => { return contexts.indexOf(c.name) > -1 }); let defaultContext = (DEFAULT_CONTEXT && typeof DEFAULT_CONTEXT === 'string' ? ALL_CONFIGS.find(c => { return c.name === DEFAULT_CONTEXT }) : null) || { priority: 0 }; // Determine which contexts will be activated based upon type and priority let activeContexts = []; let primaryContext = configs.filter(c => { return c.type === 1; }).sort((a, b) => { return a.priority - b.priority; }).pop() || defaultContext; let primaryPriority = primaryContext.priority || 0; activeContexts.push(primaryContext.name); let secondaryContexts = configs.filter(c => { return (c.type === 2 && c.priority >= primaryPriority); }).sort((a, b) => { return a.priority - b.priority; }); secondaryContexts.forEach(c => { activeContexts.push(c.name); }); // Determine which contexts are newly active and inactive let newContexts = missingItems(activeContexts, previousContexts); let inactivatedContexts = missingItems(previousContexts, activeContexts); // Perform exit parameters for inactivated contexts ALL_CONFIGS .filter(c => { return inactivatedContexts.indexOf(c.name) > -1 }) .forEach(context => { if (context.exit) { if (context.exit.profilesToDisable && Array.isArray(context.exit.profilesToDisable)) context.exit.profilesToDisable.forEach(prof => { changeProfileStatus(prof, false); }); if (context.exit.profilesToEnable && Array.isArray(context.exit.profilesToEnable)) context.exit.profilesToEnable.forEach(prof => { changeProfileStatus(prof, true); }); if (context.exit.tasksToRun && Array.isArray(context.exit.tasksToRun)) context.exit.tasksToRun.forEach(tsk => { if (typeof tsk === 'string') { executeTask(tsk, 10, null, null); } else if (typeof tsk === 'object' && tsk.name) { executeTask(tsk.name, tsk.priority, tsk.param1, tsk.param2); } }); } }); // Merge active context's settings let merged = {}; if (primaryContext) { Object.keys(primaryContext).forEach(key => { if (['name', 'type', 'priority', 'enter', 'exit'].indexOf(key) === -1 && primaryContext[key] !== null) merged[key] = primaryContext[key]; }); } secondaryContexts.forEach(context => { Object.keys(context).forEach(key => { if (['name', 'type', 'priority', 'enter', 'exit'].indexOf(key) === -1 && context[key] !== null) merged[key] = context[key]; }); }); // Change settings according to merged context // DND first, if going from none/priority to all it must occur for media volume changes to occur (Android 12+) if (existsIsType(merged, 'dnd', 'string')) performTask('DoNotDisturb', 10, merged.dnd, ''); // Only change media volume if %Modes_MediaOverride != 1 const mediaVolExists = existsIsType(merged, 'volume_media', 'int'); if (existsIsType(merged, 'volume_media_override', 'boolean') && merged.volume_media_override) { if (mediaVolExists && global('Modes_MediaOverride') !== '1') mediaVol(merged.volume_media, false, false); enableProfile('ModesMediaOverride', true); } else { enableProfile('ModesMediaOverride', false); setGlobal('Modes_MediaOverride', '0'); if (mediaVolExists) mediaVol(merged.volume_media, false, false); } if (existsIsType(merged, 'volume_notification', 'int')) notificationVol(merged.volume_notification, false, false); if (existsIsType(merged, 'location', 'string')) performTask('LocationMode', 10, merged.location, ''); if (existsIsType(merged, 'wifiOn', 'boolean')) setWifi(merged.wifiOn); if (existsIsType(merged, 'bluetoothOn', 'boolean')) setBT(merged.bluetoothOn); if (existsIsType(merged, 'mobileDataOn', 'boolean')) performTask('MobileData', 10, merged.mobileDataOn, ''); if (existsIsType(merged, 'airplaneModeOn', 'boolean')) setAirplaneMode(merged.airplaneModeOn); if (existsIsType(merged, 'screenRotationOn', 'boolean')) performTask('DisplayRotate', 10, merged.screenRotationOn, ''); if (existsIsType(merged, 'displayTimeout', 'int')) displayTimeout(0, merged.displayTimeout, 0); if (existsIsType(merged, 'displayBrightness', 'int') || existsIsType(merged, 'displayBrightness', 'string')) performTask('DisplayBrightness', 10, merged.displayBrightness, ''); if (existsIsType(merged, 'nightLightOn', 'boolean')) performTask('NightLight', 10, merged.nightLightOn, ''); if (existsIsType(merged, 'extraDimOn', 'boolean')) performTask('ExtraDim', 10, merged.extraDimOn, ''); if (existsIsType(merged, 'immersiveMode', 'string')) performTask('ImmersiveMode', 10, merged.immersiveMode, ''); if (existsIsType(merged, 'darkMode', 'boolean')) performTask('DarkMode', 10, merged.darkMode, ''); if (existsIsType(merged, 'grayscaleMode', 'boolean')) performTask('GrayscaleMode', 10, merged.grayscaleMode, ''); if (existsIsType(merged, 'hapticFeedbackOn', 'boolean')) performTask('TouchVibrations', 10, merged.hapticFeedbackOn, ''); if (existsIsType(merged, 'batterySaverOn', 'boolean')) performTask('BatterySaver', 10, merged.batterySaverOn, ''); if (existsIsType(merged, 'owntracksMode', 'int')) performTask("OwntracksMode", 10, merged.owntracksMode, ''); if (existsIsType(merged, 'owntracksMode', 'string')) performTask("OwntracksMode", 10, owntracksStringToInt(merged.owntracksMode), ''); // Perform enter parameters for new contexts ALL_CONFIGS .filter(context => { return (newContexts.indexOf(context.name) > -1) }) .forEach(context => { if (context.enter) { if (context.enter.profilesToDisable && Array.isArray(context.enter.profilesToDisable)) context.enter.profilesToDisable.forEach(prof => { changeProfileStatus(prof, false); }); if (context.enter.profilesToEnable && Array.isArray(context.enter.profilesToEnable)) context.enter.profilesToEnable.forEach(prof => { changeProfileStatus(prof, true); }); if (context.enter.tasksToRun && Array.isArray(context.enter.tasksToRun)) context.enter.tasksToRun.forEach(tsk => { if (typeof tsk === 'string') { executeTask(tsk, 10, null, null); } else if (typeof tsk === 'object' && tsk.name) { executeTask(tsk.name, tsk.priority, tsk.param1, tsk.param2); } }); } }); setGlobal('Modes_ActiveContexts', activeContexts.join(',')); setLocal('active', activeContexts.join(', ') || DEFAULT_CONTEXT); exit(); // Helper functions function missingItems(arr1, arr2) { var missing = arr1.filter(function(item) { return arr2.indexOf(item) === -1; }); return missing; } function existsIsType(obj, key, type) { if (Object.keys(obj).indexOf(key) === -1) return false; if (type === 'int') return (Number.isInteger(obj[key])); else return (typeof obj[key] === type); } function changeProfileStatus(name, on) { enableProfile(name, on); wait(1000); } function executeTask(name, priority, param1, param2) { performTask(name, priority, param1, param2); wait(500); } function owntracksStringToInt(mode) { switch (mode.toLowerCase()) { case 'quiet': return -1; case 'manual': return 0; case 'move': return 2; default: return 1; } } 120 548 %active #FFFFFFFF Top ℹ️ Context Changed #BF606060 EditContext 4000 %SCREEN 2 on mw_image_photo_filter 1469555817040 1544736509880 13 DisplayRotate 596 %par1 %rotate %par1 12 822 Or %rotate 4 true|on %par1 13 822 %rotate 4 false|off mw_device_screen_rotation 1485323616243 1590293377013 137 130 AddToContext %priority earbuds 1543422275395 1590293383258 138 130 RemoveFromContext %priority earbuds 130 RemoveFromContext %priority mediaoverride all 1544453972007 1621575081741 140 BatterySaver 100 596 %par1 %par1 12 175 Or %par1 4 false|off %par1 13 175 %par1 4 true|on mw_device_battery_alert 1544822459344 1572403451994 143 CheckForModesUpdate 100 339 <StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%http_data Data Data that the server responded from the HTTP request.</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1>%http_response_code Response Code The HTTP Code the server responded</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2>%http_headers() Response Headers The HTTP Headers the server sent in the response. Each header is in the 'key:value' format</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3>%http_response_length Response Length The size of the response in bytes</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3></StringArray> [Ljava.lang.String; https://github.com/jhotmann/tasker-phone-modes/releases.atom 598 %http_data (?<=title>)\d+\.\d+\.\d+ %versions 43 And And %versions13 7 %currentversion3 %versions12 8 %currentversion2 %versions11 8 %currentversion1 135 NotifyUpdate 43 137 38 523 Modes Update Available Select UPDATE to launch Taskernet modes_updates mw_notification_system_update 104 https://taskernet.com/shares/?user=AS35m8k7601Z2ol5UAzuT033Ll5H1yhruZrDvDITEN2l4b5o%2Fm1AF9Dpj3WrfO36Pgh2&id=Project%3AModes 137 %versions1 13 590 %versions1 . 547 %currentversion %Modes_Version 590 %currentversion . 37 %versions11 7 %currentversion1 135 NotifyUpdate 43 And %versions12 7 %currentversion2 %versions11 8 %currentversion1 135 NotifyUpdate mw_notification_system_update 1572830036452 1646871493540 154 ReadConfigFiles 100 1 129 const CONFIG_PATH = global('Modes_ConfigPath'); let configs = []; let fileList = listFiles(CONFIG_PATH).split('\n').filter(f => { return (f !== '') }); fileList.forEach(f => { let conf = readConfigFile(f); configs.push(conf); }); setGlobal('Modes_Configs', JSON.stringify(configs)); exit(); function readConfigFile(configName) { let configText = '{}'; try { configText = readFile(configName); } catch (error) { flash('Error reading configuration file ' + configName); } let conf = JSON.parse(configText); if (!conf.name) conf.name = configName.replace(/^.*\/|\.[A-Za-z]+$/g, ''); if (!conf.type) conf.type = 1; if (!conf.priority) conf.priority = 50; // Translate old configuration format if (Object.keys(conf).indexOf('volume') > -1) { if (conf.volume.media !== null) conf.volume_media = conf.volume.media; if (conf.volume.notification !== null) conf.volume_notification = conf.volume.notification; if (conf.volume.dnd !== null) conf.dnd = conf.volume.dnd; delete conf.volume; } return conf; } mw_editor_format_line_spacing 1572209034876 1637607936585 175 EditContext 100 1 512 false 360 <StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%input Input The text that was inserted in the dialog</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0></StringArray> [Ljava.lang.String; Edit Context A comma-separtated lists of contexts %Modes_Contexts 524289 547 %Modes_Contexts %input mw_editor_border_color 1543968812849 1629861504870 18 ConfigCreator 100 true 104 https://rawgit.com/jhotmann/tasker-phone-modes/master/ConfigCreator/ConfigCreator.html mw_action_note_add 1469465053041 1575825633571 180 ImmersiveMode 596 %par1 %mode %par1 12 906 Or %par1 2 off %par1 13 906 %par1 2 status 906 %par1 2 navigation 906 %par1 4 both|full mw_navigation_fullscreen 1544453972007 1646720889824 181 DarkMode 100 596 %par1 %par1 12 361 <StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%new_state New State true if it after the action the setting is enabled, false if not</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0></StringArray> [Ljava.lang.String; %par1 4 true|on 361 <StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%new_state New State true if it after the action the setting is enabled, false if not</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0></StringArray> [Ljava.lang.String; %par1 4 false|off mw_action_invert_colors 1646720473481 1646720796001 186 NightLight 596 %par1 %par1 12 235 night_display_activated 1 %par1 4 true|on|1 235 night_display_activated 0 Or %par1 4 false|off|0 %par1 13 mw_image_brightness_3 1544301755191 1628065949892 187 6 1 547 %Modes_MediaOverride 1 1621575009022 1646720625423 192 ExtraDim 100 596 %par1 %par1 12 235 reduce_bright_colors_activated 1 %par1 4 true|on|1 235 reduce_bright_colors_activated 0 Or %par1 4 off|false|0 %par1 13 mw_image_brightness_3 1471285453782 1629861478164 20 Setup 100 129 var configPath = global('%Modes_ConfigPath'); var path = prompt('What folder will contain your config files? (No trailing slash)', (configPath ? configPath : '/sdcard/Tasker/ModeConfigs')); if (path != null) { setGlobal('Modes_ConfigPath', path); } 409 false %Modes_ConfigPath 129 performTask('ReadConfigFiles', 99, null, null); var defaultContext = global('Modes_DefaultContext'); var dc = prompt('What would you like to be the default primary context?', (defaultContext ? defaultContext : '')); if (dc != null) { setGlobal('Modes_DefaultContext', dc); } var cfu = confirm('Would you like to periodically check for project updates?'); enableProfile('CheckForModesUpdate', cfu); enableProfile('ContextChanged', true); enableProfile('MonitorStart', true); 130 false ReadConfigFiles %priority+1 159 false ContextChanged 159 false CheckForModesUpdate 159 false MonitorStart mw_communication_phonelink_setup 1519250213720 1628478108259 201 GrayscaleMode 100 547 %par1 off %par1 13 596 %par1 235 accessibility_display_daltonizer_enabled 1 %par1 4 true|on 235 accessibility_display_daltonizer_enabled 0 %par1 4 false|off mw_image_tonality 1629860223041 1646720852472 202 ModesTest 100 548 %modes_contexts mw_editor_text_fields 1452598211627 1621575058091 34 TouchVibrations 100 596 %par1 %par1 12 235 haptic_feedback_enabled 1 Or %par1 4 true|on %par1 13 235 haptic_feedback_enabled 0 %par1 4 false|off mw_action_touch_app 1469465053041 1575825941972 39 LocationMode 100 596 %par1 %mode %par1 12 905 Or %par1 13 %par1 2 accuracy 905 %par1 2 off 905 %par1 2 battery 905 %par1 2 device mw_maps_my_location 1545541953966 1629861645518 52 51 130 ReadConfigFiles %priority+1 549 %modes_contexts 1443816152178 1570590264884 56 100 130 AddToContext %priority night %Modes_Contexts 5 (^|,)night($|,) 1543421571650 1544048411472 57 100 130 RemoveFromContext %priority night 1638022399682 1646863554862 60 OwntracksMode 547 %par1 1 %par1 13 877 org.owntracks.android.CHANGE_MONITORING monitoring:%par1 mw_maps_pin_drop 1544039715157 1601029950628 82 DisplayBrightness 100 596 %par1 %par1 12 808 Or %par1 2 auto %par1 13 808 %par1 4 ^\d+$ 810 %par1 %par1 4 ^\d+$ mw_image_brightness_6 1544453972007 1576045465679 83 MobileData 100 596 %par1 %par1 12 433 Or %par1 2 false %par1 2 off 433 Or %par1 2 true %par1 2 on mw_device_signal_cellular_3_bar 1469465053041 1587299882744 9 DoNotDisturb 596 %par1 %mode %par1 12 312 Or %mode 2 all %par1 13 312 %mode 2 priority 312 %mode 2 alarms 312 %mode 2 none mw_notification_do_not_disturb_off