Skip to content

Commit

Permalink
sunrise: Add sunrise module to pixlet. (#124)
Browse files Browse the repository at this point in the history
* sunrise: Add sunrise module to pixlet.

This commit adds the go-sunrise module to pixlet so that apps can make
use of sunrise/sunset times. This has been a popular use case and
hopefully this module will make it easier for more folks to take
advantage of this information.

* Fix accidental change

* sunrise: Add better support for no sunrise/sunset.

This commit adds the None return type for an empty time zone and added
it to the example.
  • Loading branch information
betterengineering authored Jan 16, 2022
1 parent 2129361 commit c978cea
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 0 deletions.
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

0 comments on commit c978cea

Please sign in to comment.