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

sunrise: Add sunrise module to pixlet. #124

Merged
merged 3 commits into from
Jan 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,16 @@ The schema module provides configuration options for your app. See the [schema d
Example:

See [examples/schema_hello_world.star](../examples/schema_hello_world.star) for an example.

## Pixlet module: Sunrise

The `sunrise` module calculates sunrise and sunset times for a given set of GPS coordinates and timestamp.

| Function | Description |
| --- | --- |
| `sunrise(lat, lng, date)` | Calculates the sunrise time for a given location and date. |
| `sunset(lat, lng, date)` | Calculates the sunset time for a given location and date. |

Example:

See [examples/sunrise.star](../examples/sunrise.star) for an example.
65 changes: 65 additions & 0 deletions examples/sunrise.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
load("render.star", "render")
load("schema.star", "schema")
load("time.star", "time")
load("encoding/json.star", "json")
load("sunrise.star", "sunrise")

DEFAULT_LOCATION = """
{
"lat": "40.6781784",
"lng": "-73.9441579",
"description": "Brooklyn, NY, USA",
"locality": "Brooklyn",
"place_id": "ChIJCSF8lBZEwokRhngABHRcdoI",
"timezone": "America/New_York"
}
"""

def main(config):
location = config.get("location", DEFAULT_LOCATION)
loc = json.decode(location)
lat, lng = float(loc["lat"]), float(loc["lng"])

now = time.now()
rise = sunrise.sunrise(lat, lng, now)
set = sunrise.sunset(lat, lng, now)

# Check if the sun does not rise or set today. This would happen if the
# location of the deivce is close to the north or south pole where there are
# many days of light or darkness. Maybe someone brought their Tidbyt to the
# Amundsen-Scott South Pole Station! How cool would that be?
if rise == None or set == None:
return render.Root(
child = render.Column(
children = [
render.Text("Now: %s" % now.in_location(loc["timezone"]).format("3:04 PM")),
render.Marquee(
width = 64,
child = render.Text("Sun doesn't rise or set today."),
),
],
),
)

return render.Root(
child = render.Column(
children = [
render.Text("Now: %s" % now.in_location(loc["timezone"]).format("3:04 PM")),
render.Text("Rise: %s" % rise.in_location(loc["timezone"]).format("3:04 PM")),
render.Text("Set: %s" % set.in_location(loc["timezone"]).format("3:04 PM")),
],
),
)

def get_schema():
return schema.Schema(
version = "1",
fields = [
schema.Location(
id = "location",
name = "Location",
desc = "Location for which to display time.",
icon = "place",
),
],
)
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/harukasan/go-libwebp v0.0.0-20190703060927-68562c9c99af
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/nathan-osman/go-sunrise v1.0.0 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/pkg/errors v0.9.1
github.com/qri-io/starlib v0.5.1-0.20211102160121-ae835e29cd41
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nathan-osman/go-sunrise v1.0.0 h1:mvjoVmXjmiHDSwKRA5t4T/1rNuHQDhodfQoxrUU39ck=
github.com/nathan-osman/go-sunrise v1.0.0/go.mod h1:RcWqhT+5ShCZDev79GuWLayetpJp78RSjSWxiDowmlM=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
Expand Down
94 changes: 94 additions & 0 deletions runtime/modules/sunrise/sunrise.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package sunrise

import (
"fmt"
"sync"
"time"

gosunrise "github.com/nathan-osman/go-sunrise"
startime "go.starlark.net/lib/time"
"go.starlark.net/starlark"
"go.starlark.net/starlarkstruct"
)

const (
ModuleName = "sunrise"
)

var (
once sync.Once
module starlark.StringDict
empty time.Time
)

func LoadModule() (starlark.StringDict, error) {
once.Do(func() {
module = starlark.StringDict{
ModuleName: &starlarkstruct.Module{
Name: ModuleName,
Members: starlark.StringDict{
"sunrise": starlark.NewBuiltin("sunrise", sunrise),
"sunset": starlark.NewBuiltin("sunset", sunset),
},
},
}
})

return module, nil
}

func sunrise(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var (
starLat starlark.Float
starLng starlark.Float
starDate startime.Time
)

if err := starlark.UnpackArgs(
"sunrise",
args, kwargs,
"lat", &starLat,
"lng", &starLng,
"date", &starDate,
); err != nil {
return nil, fmt.Errorf("unpacking arguments for sunrise: %s", err)
}

lat := float64(starLat)
lng := float64(starLng)
date := time.Time(starDate)
rise, _ := gosunrise.SunriseSunset(lat, lng, date.Year(), date.Month(), date.Day())
if rise == empty {
return starlark.None, nil
}

return startime.Time(rise), nil
}

func sunset(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var (
starLat starlark.Float
starLng starlark.Float
starDate startime.Time
)

if err := starlark.UnpackArgs(
"sunset",
args, kwargs,
"lat", &starLat,
"lng", &starLng,
"date", &starDate,
); err != nil {
return nil, fmt.Errorf("unpacking arguments for sunset: %s", err)
}

lat := float64(starLat)
lng := float64(starLng)
date := time.Time(starDate)
_, set := gosunrise.SunriseSunset(lat, lng, date.Year(), date.Month(), date.Day())
if set == empty {
return starlark.None, nil
}

return startime.Time(set), nil
}
47 changes: 47 additions & 0 deletions runtime/modules/sunrise/sunrise_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package sunrise_test

import (
"testing"

"github.com/stretchr/testify/assert"
"tidbyt.dev/pixlet/runtime"
)

var sunSource = `
load("time.star", "time")
load("sunrise.star", "sunrise")

def assert(success, message=None):
if not success:
fail(message or "assertion failed")


# Setup.
format = "2006-01-02T15:04:05"
input = time.parse_time("2022-01-15T22:40:24", format = format)
expectedRise = time.parse_time("2022-01-15T12:17:29", format = format)
expectedSet = time.parse_time("2022-01-15T21:52:30", format = format)
lat = 40.6781784
lng = -73.9441579

# Call methods.
rise = sunrise.sunrise(lat, lng, input)
set = sunrise.sunset(lat, lng, input)

# Assert.
assert(rise == expectedRise)
assert(set == expectedSet)

def main():
return []
`

func TestSunrise(t *testing.T) {
app := &runtime.Applet{}
err := app.Load("sun.star", []byte(sunSource), nil)
assert.NoError(t, err)

screens, err := app.Run(map[string]string{})
assert.NoError(t, err)
assert.NotNil(t, screens)
}
4 changes: 4 additions & 0 deletions runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"go.starlark.net/starlarkstruct"

"tidbyt.dev/pixlet/render"
"tidbyt.dev/pixlet/runtime/modules/sunrise"
"tidbyt.dev/pixlet/schema"
"tidbyt.dev/pixlet/starlarkutil"
)
Expand Down Expand Up @@ -321,6 +322,9 @@ func (a *Applet) loadModule(thread *starlark.Thread, module string) (starlark.St
case "re.star":
return starlibre.LoadModule()

case "sunrise.star":
return sunrise.LoadModule()

case "time.star":
return starlark.StringDict{
starlibtime.Module.Name: starlibtime.Module,
Expand Down