<commit_before>One of the frequent uses of Tasker is to change system settings and perform tasks based on your current situation.
Things like silencing your phone while in a meeting, turning down brightness at night, or launching a music app
when in the car are just the tip of the iceberg when it comes to Tasker automation. This sort of automation can
be approached in many different ways and often times leads to repeated steps in multiple tasks and disorganization.

Over time I have strived to refine my situation-based automation so that it's easy to modify, highly organized, and
doesn't use the same steps in multiple tasks. I have now also made it universal so that anyone can import my simple
profiles and quickly get automating.

See the technical details below and the examples from my own setup to help paint the full picture of how this framework can be beneficial to you.

[Installation and Configuration](#installation-and-configuration)  
[Configuration Spec](#configuration-spec)  
[Examples](#examples)

# Overview
This framework monitors a variable `%Modes_Contexts` which contains a list of your current, active contexts i.e. if you are home, if you have headphones plugged in, if you are in a work meeting, etc. These contexts are up to you to think of and manage based on your needs. The framework looks at the configuration for these contexts and based on priorities and context types will determine what your current settings should be and sets them accordingly. Also when a context becomes active or inactive you can easily run other tasks or enable/disable other profiles accordingly.

To activate a context, simply call the `AddToContext` task with the name of the context as the first parameter. The `ContextChanged` profile will pickup the change and read the configurations for all active contexts. Configuration file names should match the context names in Tasker i.e. if you have a context named `home`, the framework will look for a configuration file named `home.json` for its configuration.

If multiple contexts are active, the framework does a few things to determine how the device settings should be set. Only the highest priority `primary` context (see the [configuration spec](#configuration-spec) section for a description of `primary` vs `secondary` contexts) will be used. If there is a tie for highest priority, then the last to be activated will be used. All `secondary` contexts with a priority higher than the primary context will be used, and settings from higher priority contexts will take precidence over lower priority contexts if they change the same setting. Also, any `secondary` context's settings will take precidence over `primary` context's settings even if they share the same priority.

**Supported Settings**  
Out of the box the following settings changes are supported:

* Notification Volume
* Media Volume
* Do Not Disturb Mode
* Location Mode+
* Wifi on/off
* Bluetooth on/off
* Airplane Mode on/off
* Display Rotation on/off
* Display Timeout
* Display Brightness
* Haptic Feedback on/off+
* Battery Saver on/off+
* And much more\*

\+ *Requires you to grant Tasker the `WRITE_SECURE_SETTINGS` permission. Instructions [here](https://tasker.joaoapps.com/userguide/en/help/ah_secure_setting_grant.html)*  
\* *With the ability to call any task or enable/disable any profile, you can modify anything else that Tasker is able to modify.*

# Framework Advantages Over Standard Tasker Profiles
1. Profile conflict management
    
    With standard profiles if you want to avoid a profile being active while another is active you have to do some sort of check, like `%PACTIVE` regex matching the other profile name(s) or set a custom global variable with a value when the other profile is active and add that as a condition to your profile. With this framework you don't need those checks because the `type` and `priority` properties handle that for you, so you can create profiles with a simple, single condition and let the framework handle the rest.

1. Configuration merging

    With this framework, since multiple contexts can be active at once, your configurations for each state will be merged and the highest priority for each setting will take affect. When one of the states is deactivated, the settings are re-merged and changed accordingly. Doing this with normal profiles and tasks would be quite the challenge because you would have to write lengthy exit conditions, or a really big, nasty task to handle the changes. See the next point...

1. One task (and a few helpers) to take care of all the work

    When you use normal profiles and tasks to change settings dependent on your situation, you either have to create one giant task with a lot of `if` statements in it, or each profile has a task with a lot of the same steps repeated in them. With this framework you can change a bunch of settings without creating any extra tasks and all the logic is written in JavaScript which is a lot easier to work with than Tasker's.


# Installation and Configuration

1. ### Import Modes.prj.xml into Tasker
    **The easy way to install is to head to the [Taskernet url](https://taskernet.com/shares/?user=AS35m8k7601Z2ol5UAzuT033Ll5H1yhruZrDvDITEN2l4b5o%2Fm1AF9Dpj3WrfO36Pgh2&id=Project%3AModes) for the project to install.** If you'd like to install the project manually, long press (or right click) and save the [Modes.prj.xml file](https://raw.githubusercontent.com/jhotmann/tasker-phone-modes/master/Modes.prj.xml) to your phone.
    Then open up Tasker, long press on a project tab at the bottom, and select Import. Then browse to and select the downloaded file.

1. ### Run Setup task
    If installing from Taskernet you will be prompted to run the Setup task, otherwise select the Tasks tab for the Modes project in Tasker and open the Setup task. Select the play button and follow the on-screen prompts. It will ask you for the location you store your config files, a default context when no other primary contexts are active, and if you'd like to periodically check for updates.

1. ### Create config files
    As of version `1.2.0` there is a [Configuration Creator webpage](https://rawgit.com/jhotmann/tasker-phone-modes/master/ConfigCreator/ConfigCreator.html) that you can use to generate a json file and download to your device. There is also a `ConfigCreator` task that can be used to launch the configuration creator webpage so you don't need to bookmark the URL. You can also see the [Configuration Spec](#configuration-spec) section for manual config creation.

1. ### Create profiles and tasks to change the current context

    Create profiles and tasks *outside of the Modes project (so they don't get overwritten)* that determine when context changes have occurred. The name of your config files are important because they need to match a context's name. When the `home` context is active, `home.json` is used to lookup the settings for the `home` context. You can activate/deactivate contexts within a task or with a profile. I personally use profiles to handle the majority of context changes but tasks can be used as well.

    To activate a context, simply call the `AddToContext` task with the name of the context as the first parameter, and to deactivate a context call the `RemoveFromContext` task with the name of the context as the first parameter.

    *See the [Examples](#examples) section for my real world configuration files and profiles.*

# Configuration Spec
The configuration files each contain a single JSON object with the following properties. All properties are optional and a few have default values if they are not specified. If you omit a property that doesn't have a default value from your configuration, that setting will remain unchanged.

* `type` - whether the context is a primary or secondary type
  * `1` - a primary context (default). Think of a primary context as a place like home, work, car, etc. Primary contexts often contain multiple settings changes and possibly running other tasks or enabling/disabling other profiles. Only one primary context can be active at a time.
  * `2` - a secondary context. Think of a secondary context as a state that takes place within another context or can span multiple primary contexts like headphones plugged in, specific apps being open, or night time. Secondary contexts often change just a few settings like going into do not disturb mode when in a meeting. Multiple secondary contexts can be active at a time.
* `priority` - to determine what context(s) take priority when multiple are active
  * An integer from `0` to `100`
  * The default is `50`
* `volume_notification` - set the notification volume
  * An integer from `0` to `7`
  * I believe manufacturers can change how many volume steps there are so the max number could be different on your device
* `volume_media` - set the media volume
  * An integer from `0` to `15`<commit_msg>Upgrade instructions<commit_after>One of the frequent uses of Tasker is to change system settings and perform tasks based on your current situation.
Things like silencing your phone while in a meeting, turning down brightness at night, or launching a music app
when in the car are just the tip of the iceberg when it comes to Tasker automation. This sort of automation can
be approached in many different ways and often times leads to repeated steps in multiple tasks and disorganization.

Over time I have strived to refine my situation-based automation so that it's easy to modify, highly organized, and
doesn't use the same steps in multiple tasks. I have now also made it universal so that anyone can import my simple
profiles and quickly get automating.

See the technical details below and the examples from my own setup to help paint the full picture of how this framework can be beneficial to you.

[Installation and Configuration (and upgrades)](#installation-and-configuration)  
[Configuration Spec](#configuration-spec)  
[Examples](#examples)

# Overview
This framework monitors a variable `%Modes_Contexts` which contains a list of your current, active contexts i.e. if you are home, if you have headphones plugged in, if you are in a work meeting, etc. These contexts are up to you to think of and manage based on your needs. The framework looks at the configuration for these contexts and based on priorities and context types will determine what your current settings should be and sets them accordingly. Also when a context becomes active or inactive you can easily run other tasks or enable/disable other profiles accordingly.

To activate a context, simply call the `AddToContext` task with the name of the context as the first parameter. The `ContextChanged` profile will pickup the change and read the configurations for all active contexts. Configuration file names should match the context names in Tasker i.e. if you have a context named `home`, the framework will look for a configuration file named `home.json` for its configuration.

If multiple contexts are active, the framework does a few things to determine how the device settings should be set. Only the highest priority `primary` context (see the [configuration spec](#configuration-spec) section for a description of `primary` vs `secondary` contexts) will be used. If there is a tie for highest priority, then the last to be activated will be used. All `secondary` contexts with a priority higher than the primary context will be used, and settings from higher priority contexts will take precidence over lower priority contexts if they change the same setting. Also, any `secondary` context's settings will take precidence over `primary` context's settings even if they share the same priority.

**Supported Settings**  
Out of the box the following settings changes are supported:

* Notification Volume
* Media Volume
* Do Not Disturb Mode
* Location Mode+
* Wifi on/off
* Bluetooth on/off
* Airplane Mode on/off
* Display Rotation on/off
* Display Timeout
* Display Brightness
* Haptic Feedback on/off+
* Battery Saver on/off+
* And much more\*

\+ *Requires you to grant Tasker the `WRITE_SECURE_SETTINGS` permission. Instructions [here](https://tasker.joaoapps.com/userguide/en/help/ah_secure_setting_grant.html)*  
\* *With the ability to call any task or enable/disable any profile, you can modify anything else that Tasker is able to modify.*

# Framework Advantages Over Standard Tasker Profiles
1. Profile conflict management
    
    With standard profiles if you want to avoid a profile being active while another is active you have to do some sort of check, like `%PACTIVE` regex matching the other profile name(s) or set a custom global variable with a value when the other profile is active and add that as a condition to your profile. With this framework you don't need those checks because the `type` and `priority` properties handle that for you, so you can create profiles with a simple, single condition and let the framework handle the rest.

1. Configuration merging

    With this framework, since multiple contexts can be active at once, your configurations for each state will be merged and the highest priority for each setting will take affect. When one of the states is deactivated, the settings are re-merged and changed accordingly. Doing this with normal profiles and tasks would be quite the challenge because you would have to write lengthy exit conditions, or a really big, nasty task to handle the changes. See the next point...

1. One task (and a few helpers) to take care of all the work

    When you use normal profiles and tasks to change settings dependent on your situation, you either have to create one giant task with a lot of `if` statements in it, or each profile has a task with a lot of the same steps repeated in them. With this framework you can change a bunch of settings without creating any extra tasks and all the logic is written in JavaScript which is a lot easier to work with than Tasker's.


# Installation and Configuration

1. ### Import Modes.prj.xml into Tasker
    **The easy way to install is to head to the [Taskernet url](https://taskernet.com/shares/?user=AS35m8k7601Z2ol5UAzuT033Ll5H1yhruZrDvDITEN2l4b5o%2Fm1AF9Dpj3WrfO36Pgh2&id=Project%3AModes) for the project to install.** If you'd like to install the project manually, long press (or right click) and save the [Modes.prj.xml file](https://raw.githubusercontent.com/jhotmann/tasker-phone-modes/master/Modes.prj.xml) to your phone.
    Then open up Tasker, long press on a project tab at the bottom, and select Import. Then browse to and select the downloaded file.

    The same Taskernet url can be used for **upgrades**. Select `Import`, then `YES` on the resulting Import dialog, then `YES` when asked to overwrite the existing `Modes` project, let Tasker do its import process, you can select `NO` or `OK` on the Missing Permissions dialog, select `NO` when asked to enable all profiles, and lastly select `YES` when asked if you want to run the Setup task.

1. ### Run Setup task
    If installing from Taskernet you will be prompted to run the Setup task, otherwise select the Tasks tab for the Modes project in Tasker and open the Setup task. Select the play button and follow the on-screen prompts. It will ask you for the location you store your config files, a default context when no other primary contexts are active, and if you'd like to periodically check for updates.

1. ### Create config files
    As of version `1.2.0` there is a [Configuration Creator webpage](https://rawgit.com/jhotmann/tasker-phone-modes/master/ConfigCreator/ConfigCreator.html) that you can use to generate a json file and download to your device. There is also a `ConfigCreator` task that can be used to launch the configuration creator webpage so you don't need to bookmark the URL. You can also see the [Configuration Spec](#configuration-spec) section for manual config creation.

1. ### Create profiles and tasks to change the current context

    Create profiles and tasks *outside of the Modes project (so they don't get overwritten)* that determine when context changes have occurred. The name of your config files are important because they need to match a context's name. When the `home` context is active, `home.json` is used to lookup the settings for the `home` context. You can activate/deactivate contexts within a task or with a profile. I personally use profiles to handle the majority of context changes but tasks can be used as well.

    To activate a context, simply call the `AddToContext` task with the name of the context as the first parameter, and to deactivate a context call the `RemoveFromContext` task with the name of the context as the first parameter.

    *See the [Examples](#examples) section for my real world configuration files and profiles.*

# Configuration Spec
The configuration files each contain a single JSON object with the following properties. All properties are optional and a few have default values if they are not specified. If you omit a property that doesn't have a default value from your configuration, that setting will remain unchanged.

* `type` - whether the context is a primary or secondary type
  * `1` - a primary context (default). Think of a primary context as a place like home, work, car, etc. Primary contexts often contain multiple settings changes and possibly running other tasks or enabling/disabling other profiles. Only one primary context can be active at a time.
  * `2` - a secondary context. Think of a secondary context as a state that takes place within another context or can span multiple primary contexts like headphones plugged in, specific apps being open, or night time. Secondary contexts often change just a few settings like going into do not disturb mode when in a meeting. Multiple secondary contexts can be active at a time.
* `priority` - to determine what context(s) take priority when multiple are active
  * An integer from `0` to `100`
  * The default is `50`
* `volume_notification` - set the notification volume
  * An integer from `0` to `7`
  * I believe manufacturers can change how many volume steps there are so the max number could be different on your device
* `volume_media` - set the media volume
  * An integer from `0` to `15`
{'fraction_non_alphanumeric': 0.045780625376485404, 'fraction_numerical': 0.005257105306390669, 'mean_word_length': 4.454599761051374, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '841748', 'n_tokens_mistral': 4450, 'n_tokens_neox': 4245, 'n_words': 2795}