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

Minutely Summary #41

Open
3 tasks done
cloneofghosts opened this issue Dec 28, 2024 · 0 comments
Open
3 tasks done

Minutely Summary #41

cloneofghosts opened this issue Dec 28, 2024 · 0 comments
Assignees
Labels
enhancement New feature or request Needs Review

Comments

@cloneofghosts
Copy link
Collaborator

cloneofghosts commented Dec 28, 2024

Describe the issue

@alexander0042 Was working on getting the minutely summary setup and was able to get something working:

Minutely Summary
from javascript import require

def calculate_text(precipIntensity, prepIntensityUnit, precipType):
    """
    Calculates the textual precipitation text for the week.

    Parameters:
    - avgIntensity (float): The average precipitation intensity for the week
    - intensityUnit (int): The conversion factor for the precipitation intensity
    - precipType (str): The type of precipitation for the week

    Returns:
    - cSummary (str): The textual summary of conditions (very-light-rain, medium-sleet, etc.).
    """
    possibleText = ""

    if precipIntensity < (0.02 * prepIntensityUnit):
        possibleText = "possible-"

    if precipType == "rain":
        if precipIntensity < (0.4 * prepIntensityUnit):
            cSummary = possibleText + "very-light-rain"
        elif precipIntensity >= (0.4 * prepIntensityUnit) and precipIntensity < (
            2.5 * prepIntensityUnit
        ):
            cSummary = "light-rain"
        elif precipIntensity >= (2.5 * prepIntensityUnit) and precipIntensity < (
            10 * prepIntensityUnit
        ):
            cSummary = "medium-rain"
        else:
            cSummary = "heavy-rain"
    elif precipType == "snow":
        if precipIntensity < (0.13 * prepIntensityUnit):
            cSummary = possibleText + "very-light-snow"
        elif precipIntensity >= (0.13 * prepIntensityUnit) and precipIntensity < (
            0.83 * prepIntensityUnit
        ):
            cSummary = "light-snow"
        elif precipIntensity >= (0.83 * prepIntensityUnit) and precipIntensity < (
            3.33 * prepIntensityUnit
        ):
            cSummary = "medium-snow"
        else:
            cSummary = "heavy-snow"
    elif precipType == "sleet":
        if precipIntensity < (0.4 * prepIntensityUnit):
            cSummary = possibleText + "very-light-sleet"
        elif precipIntensity >= (0.4 * prepIntensityUnit) and precipIntensity < (
            2.5 * prepIntensityUnit
        ):
            cSummary = "light-sleet"
        elif precipIntensity >= (2.5 * prepIntensityUnit) and precipIntensity < (
            10 * prepIntensityUnit
        ):
            cSummary = "medium-sleet"
        else:
            cSummary = "heavy-sleet"
    else:
        # Because soemtimes there's precipitation not no type use a generic precipitation summary
        if precipIntensity < (0.4 * prepIntensityUnit):
            cSummary = possibleText + "very-light-precipitation"
        elif precipIntensity >= (0.4 * prepIntensityUnit) and precipIntensity < (
            2.5 * prepIntensityUnit
        ):
            cSummary = "light-precipitation"
        elif precipIntensity >= (2.5 * prepIntensityUnit) and precipIntensity < (
            10 * prepIntensityUnit
        ):
            cSummary = "medium-precipitation"
        else:
            cSummary = "heavy-precipitation"

    return cSummary


def calculate_minutely_text(minuteArr, currentText, currentIcon):
    """
    Calculates the minutely summary given an array of minutes

    Parameters:
    - minuteArr (arr): An array of the minutes
    - currentText (str/arr): The current conditions in translations format
    - currentIcon (str): The icon representing the current conditions

    Returns:
    - cText (arr): The precipitation and temperature summary for the hour.
    - cIcon (str): The icon representing the conditions for the hour.
    """

    # Variables to use in calculating the minutely summary
    cIcon = None
    cText = None
    rainStart1 = -1
    rainEnd1 = -1
    rainStart2 = -1
    snowStart1 = -1
    snowEnd1 = -1
    snowStart2 = -1
    sleetStart1 = -1
    sleetEnd1 = -1
    sleetStart2 = -1
    noneStart1 = -1
    noneEnd1 = -1
    noneStart2 = -1
    avgIntensity = 0
    precipMinutes = 0
    rainMaxIntensity = 0
    snowMaxIntensity = 0
    sleetMaxIntensity = 0
    noneMaxIntensity = 0
    precipIntensityUnit = 1
    first_precip = "none"

    # Loop through the minute array
    for idx, minute in enumerate(minuteArr):
        # If there is rain for the current minute in the array
        if minute[1] == "rain" and minute[0] > 0:
            # Increase the minutes of precipitation, the precipitation unit and average intensity
            avgIntensity += minute[0]
            precipMinutes += 1
            precipIntensityUnit = minute[2]

            # Set the maxiumum rain intensity
            if rainMaxIntensity == 0:
                rainMaxIntensity = minute[0]
            elif rainMaxIntensity > 0 and minute[0] > rainMaxIntensity:
                rainMaxIntensity = minute[0]

            # Set the first rain first index if not set to the current index
            if rainStart1 == -1:
                rainStart1 = idx
            # If the first rain starting and ending index is already set then set the second starting index
            elif rainStart1 != -1 and rainEnd1 != -1 and rainStart2 == -1:
                rainStart2 = idx
            # If there is a first snow starting index but no ending index then set that to the current index
            if snowStart1 != -1 and snowStart2 == -1 and snowEnd1 == -1:
                snowEnd1 = idx
            # If there is a first sleet starting index but no ending index then set that to the current index
            if sleetStart1 != -1 and sleetStart2 == -1 and sleetEnd1 == -1:
                sleetEnd1 = idx
            # If there is a first none starting index but no ending index then set that to the current index
            if noneStart1 != -1 and noneStart2 == -1 and noneEnd1 == -1:
                noneEnd1 = idx
        # If there is snow for the current minute in the array
        elif minute[1] == "snow" and minute[0] > 0:
            # Increase the minutes of precipitation, the precipitation unit and average intensity
            avgIntensity += minute[0]
            precipMinutes += 1
            precipIntensityUnit = minute[2]

            # Set the maxiumum snow intensity
            if snowMaxIntensity == 0:
                snowMaxIntensity = minute[0]
            elif snowMaxIntensity > 0 and minute[0] > snowMaxIntensity:
                snowMaxIntensity = minute[0]

            # Set the first snow first index if not set to the current index
            if snowStart1 == -1:
                snowStart1 = idx
            # If the first snow starting and ending index is already set then set the second starting index
            elif snowStart1 != -1 and snowEnd1 != -1 and snowStart2 == -1:
                snowStart2 = idx
            # If there is a first rain starting index but no ending index then set that to the current index
            if rainStart1 != -1 and rainStart2 == -1 and rainEnd1 == -1:
                rainEnd1 = idx
            # If there is a first sleet starting index but no ending index then set that to the current index
            if sleetStart1 != -1 and sleetStart2 == -1 and sleetEnd1 == -1:
                sleetEnd1 = idx
            # If there is a first none starting index but no ending index then set that to the current index
            if noneStart1 != -1 and noneStart2 == -1 and noneEnd1 == -1:
                noneEnd1 = idx
        # If there is sleet for the current minute in the array
        elif minute[1] == "sleet" and minute[0] > 0:
            # Increase the minutes of precipitation, the precipitation unit and average intensity
            avgIntensity += minute[0]
            precipMinutes += 1
            precipIntensityUnit = minute[2]

            # Set the maxiumum sleet intensity
            if sleetMaxIntensity == 0:
                sleetMaxIntensity = minute[0]
            elif sleetMaxIntensity > 0 and minute[0] > sleetMaxIntensity:
                sleetMaxIntensity = minute[0]

            # Set the first sleet first index if not set to the current index
            if sleetStart1 == -1:
                sleetStart1 = idx
            # If the first sleet starting and ending index is already set then set the second starting index
            elif sleetStart1 != -1 and sleetEnd1 != -1 and sleetStart2 == -1:
                sleetStart2 = idx
            # If there is a first rain starting index but no ending index then set that to the current index
            if rainStart1 != -1 and rainStart2 == -1 and rainEnd1 == -1:
                rainEnd1 = idx
            # If there is a first snow starting index but no ending index then set that to the current index
            if snowStart1 != -1 and snowStart2 == -1 and snowEnd1 == -1:
                sleetEnd1 = idx
            # If there is a first none starting index but no ending index then set that to the current index
            if noneStart1 != -1 and noneStart2 == -1 and noneEnd1 == -1:
                noneEnd1 = idx
        elif minute[1] == "none" and minute[0] > 0:
            # Increase the minutes of precipitation, the precipitation unit and average intensity
            avgIntensity += minute[0]
            precipMinutes += 1
            precipIntensityUnit = minute[2]

            # Set the none maxiumum precipitation intensity
            if noneMaxIntensity == 0:
                noneMaxIntensity = minute[0]
            elif noneMaxIntensity > 0 and minute[0] > noneMaxIntensity:
                noneMaxIntensity = minute[0]

            # Set the first none first index if not set to the current index
            if noneStart1 == -1:
                noneStart1 = idx
            # If the first none starting and ending index is already set then set the second starting index
            elif noneStart1 != -1 and noneEnd1 != -1 and noneStart2 == -1:
                noneStart2 = idx
            # If there is a first rain starting index but no ending index then set that to the current index
            if rainStart1 != -1 and rainStart2 == -1 and rainEnd1 == -1:
                rainEnd1 = idx
            # If there is a first snow starting index but no ending index then set that to the current index
            if snowStart1 != -1 and snowStart2 == -1 and snowEnd1 == -1:
                snowEnd1 = idx
        # If there is no precipitation for the current minute
        else:
            # If there is a first rain starting index but no ending index then set that to the current index
            if rainStart1 != -1 and rainStart2 == -1 and rainEnd1 == -1:
                rainEnd1 = idx
            # If there is a first snow starting index but no ending index then set that to the current index
            if snowStart1 != -1 and snowStart2 == -1 and snowEnd1 == -1:
                snowEnd1 = idx
            # If there is a first sleet starting index but no ending index then set that to the current index
            if sleetStart1 != -1 and snowStart2 == -1 and snowEnd1 == -1:
                sleetEnd1 = idx
            # If there is a first none starting index but no ending index then set that to the current index
            if noneStart1 != -1 and noneStart2 == -1 and noneEnd1 == -1:
                noneEnd1 = idx

    # If there is a first starting index for rain/snow/sleet but no ending index then set it to 60
    if rainStart1 != -1 and rainEnd1 == -1:
        rainEnd1 = 60
    if snowStart1 != -1 and snowEnd1 == -1:
        snowEnd1 = 60
    if sleetStart1 != -1 and sleetEnd1 == -1:
        sleetEnd1 = 60
    if noneStart1 != -1 and noneEnd1 == -1:
        noneEnd1 = 60

    # Calculate the average precipitaiton intensity
    if precipMinutes > 0:
        avgIntensity = avgIntensity / precipMinutes

    # Create an array of the starting times for the precipitation
    starts = []
    if sleetStart1 >= 0:
        starts.append(sleetStart1)
    if snowStart1 >= 0:
        starts.append(snowStart1)
    if rainStart1 >= 0:
        starts.append(rainStart1)
    if noneStart1 >= 0:
        starts.append(noneStart1)

    # If the array has any values check the minimum against the different precipitation start times and set that as the first precipitaion
    if starts:
        if sleetStart1 == min(starts):
            first_precip = "sleet"
        elif snowStart1 == min(starts):
            first_precip = "snow"
        elif rainStart1 == min(starts):
            first_precip = "rain"
        elif noneStart1 == min(starts):
            first_precip = "none"

    # If there is no precipitation then set the minutely summary/icon to the current icon/summary
    if (
        rainStart1
        == rainEnd1
        == rainStart2
        == snowStart1
        == snowEnd1
        == snowStart2
        == sleetStart1
        == sleetEnd1
        == sleetStart2
        == noneStart1
        == noneEnd1
        == noneStart2
        == -1
    ):
        cText = ["sentence", ["for-hour", currentText]]
        cIcon = currentIcon
    # If the current precipitation is sleet and it stops before the end of the hour
    elif sleetStart1 == 0 and sleetEnd1 < 60 and sleetStart2 == -1:
        cText = [
            "sentence",
            [
                "stopping-in",
                calculate_text(sleetMaxIntensity, precipIntensityUnit, "sleet"),
                ["minutes", sleetEnd1],
            ],
        ]
        cIcon = "sleet"
    # If the current precipitation is snow and it stops before the end of the hour
    elif snowStart1 == 0 and snowEnd1 < 60 and snowStart2 == -1:
        cText = [
            "sentence",
            [
                "stopping-in",
                calculate_text(snowMaxIntensity, precipIntensityUnit, "snow"),
                ["minutes", snowEnd1],
            ],
        ]
        cIcon = "snow"
    # If the current precipitation is rain and it stops before the end of the hour
    elif rainStart1 == 0 and rainEnd1 < 60 and rainStart2 == -1:
        cText = [
            "sentence",
            [
                "stopping-in",
                calculate_text(rainMaxIntensity, precipIntensityUnit, "rain"),
                ["minutes", rainEnd1],
            ],
        ]
        cIcon = "rain"
    # If the current precipitation is none and it stops before the end of the hour
    elif noneStart1 == 0 and noneEnd1 < 60 and noneStart2 == -1:
        cText = [
            "sentence",
            [
                "stopping-in",
                calculate_text(avgIntensity, precipIntensityUnit, "none"),
                ["minutes", noneEnd1],
            ],
        ]
        cIcon = "rain"
    # If the current precipitation is sleet and it doesn't stop before the end of the hour
    elif sleetStart1 == 0 and sleetEnd1 == 60:
        cText = [
            "sentence",
            [
                "for-hour",
                calculate_text(sleetMaxIntensity, precipIntensityUnit, "sleet"),
            ],
        ]
        cIcon = "sleet"
    # If the current precipitation is snow and it doesn't stop before the end of the hour
    elif snowStart1 == 0 and snowEnd1 == 60:
        cText = [
            "sentence",
            ["for-hour", calculate_text(snowMaxIntensity, precipIntensityUnit, "snow")],
        ]
        cIcon = "snow"
    # If the current precipitation is rain and it doesn't stop before the end of the hour
    elif rainStart1 == 0 and rainEnd1 == 60:
        cText = [
            "sentence",
            ["for-hour", calculate_text(rainMaxIntensity, precipIntensityUnit, "rain")],
        ]
        cIcon = "rain"
    # If the current precipitation is rain and it doesn't stop before the end of the hour
    elif noneStart1 == 0 and noneEnd1 == 60:
        cText = [
            "sentence",
            ["for-hour", calculate_text(avgIntensity, precipIntensityUnit, "none")],
        ]
        cIcon = "rain"
    # If the first precipitation is sleet
    elif first_precip == "sleet":
        # If the current precipitation is sleet and it stops before the hour but starts again
        if sleetStart1 == 0 and sleetEnd1 < 60 and sleetStart2 != -1:
            cText = [
                "sentence",
                [
                    "stopping-then-starting-later",
                    calculate_text(sleetMaxIntensity, precipIntensityUnit, "sleet"),
                    ["minutes", sleetEnd1],
                    ["minutes", sleetStart2 - sleetEnd1],
                ],
            ]
            cIcon = "sleet"
        # If sleet starts during the hour and lasts until the end of the hour
        elif sleetStart1 > 0 and sleetEnd1 == 60:
            cText = [
                "sentence",
                [
                    "starting-in",
                    calculate_text(sleetMaxIntensity, precipIntensityUnit, "sleet"),
                    ["minutes", sleetStart1],
                ],
            ]
            cIcon = "sleet"
        # If sleet starts during the hour and ends before the end of the hour
        elif sleetStart1 > 0 and sleetEnd1 < 60:
            cText = [
                "sentence",
                [
                    "starting-then-stopping-later",
                    calculate_text(sleetMaxIntensity, precipIntensityUnit, "sleet"),
                    ["minutes", sleetStart1],
                    ["minutes", sleetEnd1 - sleetStart1],
                ],
            ]
            cIcon = "sleet"
    # If the first precipitation is snow
    elif first_precip == "snow":
        # If snow starts during the hour and lasts until the end of the hour
        if snowStart1 > 0 and snowEnd1 == 60:
            cText = [
                "sentence",
                [
                    "starting-in",
                    calculate_text(snowMaxIntensity, precipIntensityUnit, "snow"),
                    ["minutes", snowStart1],
                ],
            ]
            cIcon = "snow"
        # If snow starts during the hour and ends before the end of the hour
        elif snowStart1 > 0 and snowEnd1 < 60:
            cText = [
                "sentence",
                [
                    "starting-then-stopping-later",
                    calculate_text(snowMaxIntensity, precipIntensityUnit, "snow"),
                    ["minutes", snowStart1],
                    ["minutes", snowEnd1 - snowStart1],
                ],
            ]
            cIcon = "snow"
        # If the current precipitation is snow and it stops before the hour but starts again
        elif snowStart1 == 0 and snowEnd1 < 60:
            cText = [
                "sentence",
                [
                    "stopping-then-starting-later",
                    calculate_text(snowMaxIntensity, precipIntensityUnit, "snow"),
                    ["minutes", snowEnd1],
                    ["minutes", snowStart2 - snowEnd1],
                ],
            ]
            cIcon = "snow"
    # Otherwise use rain
    elif first_precip == "rain":
        # If rain starts during the hour and lasts until the end of the hour
        if rainStart1 > 0 and rainEnd1 == 60:
            cText = [
                "sentence",
                [
                    "starting-in",
                    calculate_text(rainMaxIntensity, precipIntensityUnit, "rain"),
                    ["minutes", rainStart1],
                ],
            ]
            cIcon = "rain"
        # If snow starts during the hour and ends before the end of the hour
        elif rainStart1 > 0 and rainEnd1 < 60:
            cText = [
                "sentence",
                [
                    "starting-then-stopping-later",
                    calculate_text(rainMaxIntensity, precipIntensityUnit, "rain"),
                    ["minutes", rainStart1],
                    ["minutes", rainEnd1 - rainStart1],
                ],
            ]
            cIcon = "rain"
        # If the current precipitation is rain and it stops before the hour but starts again
        elif rainStart1 == 0 and rainEnd1 < 60 and rainStart2 != -1:
            cText = [
                "sentence",
                [
                    "stopping-then-starting-later",
                    calculate_text(rainMaxIntensity, precipIntensityUnit, "rain"),
                    ["minutes", rainEnd1],
                    ["minutes", rainStart2 - rainEnd1],
                ],
            ]
            cIcon = "rain"
    else:
        # If rain starts during the hour and lasts until the end of the hour
        if noneStart1 > 0 and noneEnd1 == 60:
            cText = [
                "sentence",
                [
                    "starting-in",
                    calculate_text(noneMaxIntensity, precipIntensityUnit, "none"),
                    ["minutes", noneStart1],
                ],
            ]
            cIcon = "rain"
        # If snow starts during the hour and ends before the end of the hour
        elif noneStart1 > 0 and noneEnd1 < 60:
            cText = [
                "sentence",
                [
                    "starting-then-stopping-later",
                    calculate_text(noneMaxIntensity, precipIntensityUnit, "none"),
                    ["minutes", noneStart1],
                    ["minutes", noneEnd1 - noneStart1],
                ],
            ]
            cIcon = "rain"
        # If the current precipitation is rain and it stops before the hour but starts again
        elif noneStart1 == 0 and noneEnd1 < 60 and noneStart2 != -1:
            cText = [
                "sentence",
                [
                    "stopping-then-starting-later",
                    calculate_text(noneMaxIntensity, precipIntensityUnit, "none"),
                    ["minutes", noneEnd1],
                    ["minutes", noneStart2 - noneEnd1],
                ],
            ]
            cIcon = "rain"

    return cText, cIcon


Translations = require("./node_modules/translations/index.js")

lang = "en"
translation = Translations[lang]

if translation is None:
    translation = Translations["en"]

currentText = "light-rain"
currIcon = "rain"
minuteArr = []
# Intensity, type, units
minuteArr.append([2.3207, "rain", 1])
minuteArr.append([2.2243, "rain", 1])
minuteArr.append([2.1278, "rain", 1])
minuteArr.append([2.0314, "rain", 1])
minuteArr.append([1.935, "rain", 1])
minuteArr.append([1.8385, "rain", 1])
minuteArr.append([1.7421, "rain", 1])
minuteArr.append([1.6457, "rain", 1])
minuteArr.append([1.5493, "rain", 1])
minuteArr.append([1.4528, "rain", 1])
minuteArr.append([1.3564, "rain", 1])
minuteArr.append([1.26, "rain", 1])
minuteArr.append([1.1635, "rain", 1])
minuteArr.append([1.0735, "rain", 1])
minuteArr.append([1.0253, "rain", 1])
minuteArr.append([0.9771, "rain", 1])
minuteArr.append([0.9289, "rain", 1])
minuteArr.append([0.8807, "rain", 1])
minuteArr.append([0.8325, "rain", 1])
minuteArr.append([0.7843, "rain", 1])
minuteArr.append([0.7361, "rain", 1])
minuteArr.append([0.6878, "rain", 1])
minuteArr.append([0.6396, "rain", 1])
minuteArr.append([0.5914, "rain", 1])
minuteArr.append([0.5432, "rain", 1])
minuteArr.append([0.495, "rain", 1])
minuteArr.append([0.4468, "rain", 1])
minuteArr.append([0.3986, "rain", 1])
minuteArr.append([0.3552, "rain", 1])
minuteArr.append([0.3311, "rain", 1])
minuteArr.append([0.307, "rain", 1])
minuteArr.append([0.2829, "rain", 1])
minuteArr.append([0.2588, "rain", 1])
minuteArr.append([0.2346, "rain", 1])
minuteArr.append([0.2105, "rain", 1])
minuteArr.append([0.1864, "rain", 1])
minuteArr.append([0.1623, "rain", 1])
minuteArr.append([0.1382, "rain", 1])
minuteArr.append([0.1141, "rain", 1])
minuteArr.append([0.09, "rain", 1])
minuteArr.append([0.0659, "rain", 1])
minuteArr.append([0.0418, "rain", 1])
minuteArr.append([0.0177, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])
minuteArr.append([0, "rain", 1])

summary_text, cIcon = calculate_minutely_text(minuteArr, currentText, currIcon)

cText = translation.translate(summary_text)

print(cText)
print(cIcon)

It's a bit messy but from my local testing everything seems to work. The one thing I'm not sure about is how to handle multiple precipitation types in an hour. I'm not sure how Dark Sky did it but the logic is show whichever precipitation starts first.

So if there's rain from minute 0 to minute 10 and snow starts at minute 47 then the summary will be: Rain stopping in 10 min. and mentions nothing about snow. Same goes if snow will start in x minutes but switches to sleet x minutes later it will show Snow starting in 29 min., stopping 19 min. later.

Acknowledgements

  • This issue is related to the self-hosting code and not an API issue.
  • I have read through the README before opening this issue.
  • I have written an informative title.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Needs Review
Projects
None yet
Development

No branches or pull requests

2 participants