added first version of ConnectIQ app for URA based Bus real-time departures

This commit is contained in:
Steffen Vogel 2016-06-02 19:18:56 +02:00
parent b147da2c29
commit e2dd0451d2
9 changed files with 210 additions and 0 deletions

2
connectiq/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*.prg
*.debug.xml

17
connectiq/.project Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ura-busstops</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>connectiq.builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>connectiq.projectNature</nature>
</natures>
</projectDescription>

16
connectiq/manifest.xml Normal file
View file

@ -0,0 +1,16 @@
<!-- This is a generated file. It is highly recommended that you DO NOT edit this file. --><iq:manifest xmlns:iq="http://www.garmin.com/xml/connectiq" version="1">
<iq:application entry="BusStopApp" id="1CFE9C7CA0D44751A1CE1DF93F59268A" launcherIcon="@Drawables.LauncherIcon" name="@Strings.AppName" type="widget">
<iq:products>
<iq:product id="square_watch"/>
<iq:product id="tall_watch"/>
<iq:product id="round_watch"/>
</iq:products>
<iq:permissions>
</iq:permissions>
<iq:languages/>
</iq:application>
</iq:manifest>

View file

@ -0,0 +1,3 @@
<drawables>
<bitmap id="LauncherIcon" filename="launcher_icon.png" />
</drawables>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,3 @@
<strings>
<string id="AppName">ASEAG Fahrplan</string>
</strings>

View file

@ -0,0 +1,54 @@
using Toybox.Application as App;
using Toybox.Position as Position;
using Toybox.Time as Time;
class BusStopApp extends App.AppBase {
var mView;
var mDelegate;
function intialize() {
AppBase.initialize();
}
//! onStart() is called on application start up
function onStart() {
Position.enableLocationEvents(Position.LOCATION_CONTINUOUS, method(:onPosition));
}
//! onStop() is called when your application is exiting
function onStop() {
Position.enableLocationEvents(Position.LOCATION_DISABLE, method(:onPosition));
}
function fakePosition() {
var pos = new Position.Info();
pos.accuracy = 0;
pos.altitude = 0;
pos.heading = 0;
pos.speed = 0;
pos.when = Time.now();
pos.position = new Position.Location({
:latitude => 50.7855,
:longitude => 6.0541,
:format => :degrees
});
mView.setPosition(pos);
}
function onPosition(info) {
positionView.setPosition(info);
}
//! Return the initial view of your application here
function getInitialView() {
mView = new BusStopView();
mDelegate = new BusStopDelegate();
fakePosition();
return [ mView, mDelegate ];
}
}

View file

@ -0,0 +1,10 @@
using Toybox.WatchUi as Ui;
using Toybox.Graphics as Gfx;
using Toybox.System as Sys;
var last_key = null;
class InputTestDelegate extends Ui.BehaviorDelegate {
}

View file

@ -0,0 +1,105 @@
using Toybox.WatchUi as Ui;
using Toybox.Graphics as Gfx;
using Toybox.System as Sys;
using Toybox.Lang as Lang;
using Toybox.Communications as Comm;
using Toybox.System as Sys;
using Toybox.Time as Time;
using Toybox.Timer as Timer;
class BusStopView extends Ui.View {
var schedule = null;
var tmr;
function intialize() {
View.initialize();
}
//! Load your resources here
function onLayout(dc) {
}
//! Called when this View is brought to the foreground. Restore
//! the state of this View and prepare it to be shown. This includes
//! loading resources into memory.
function onShow() {
tmr = new Timer.Timer();
tmr.start(method(:redraw), 1000, true);
}
//! Called when this View is removed from the screen. Save the
//! state of this View here. This includes freeing resources from
//! memory.
function onHide() {
tmr.stop();
}
//! Update the view
function onUpdate(dc) {
var string;
// Set background color
dc.setColor( Gfx.COLOR_TRANSPARENT, Gfx.COLOR_BLACK );
dc.clear();
dc.setColor( Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT );
if( schedule != null ) {
var ts = new Time.Moment(schedule[1][4] / 1000);
var duration = Time.now().subtract(ts);
var ts_greg = Time.Gregorian.info(ts, Time.FORMAT_MEDIUM);
var dur_greg = Time.Gregorian.info(new Time.Moment(duration.value()), Time.FORMAT_SHORT);
/* Timezone offset */
dur_greg.hour -= 2;
var arr = Lang.format("$1$:$2$:$3$", [
(ts_greg.hour - 2),
(ts_greg.min).format("%02u"),
(ts_greg.sec).format("%02u")
]);
var due = "";
if (dur_greg.hour > 0) {
due += dur_greg.hour + " h ";
}
if (dur_greg.min > 0) {
due += dur_greg.min + " min ";
}
if (dur_greg.sec > 0) {
due += dur_greg.sec + " sec ";
}
dc.drawText( (dc.getWidth() / 2), (dc.getHeight() / 2) - 80, Gfx.FONT_LARGE, schedule[1][2], Gfx.TEXT_JUSTIFY_CENTER );
dc.drawText( (dc.getWidth() / 2), (dc.getHeight() / 2) - 40, Gfx.FONT_SMALL, schedule[1][1], Gfx.TEXT_JUSTIFY_CENTER );
dc.drawText( (dc.getWidth() / 2), (dc.getHeight() / 2) - 20, Gfx.FONT_SMALL, schedule[1][3], Gfx.TEXT_JUSTIFY_CENTER );
dc.drawText( (dc.getWidth() / 2), (dc.getHeight() / 2) + 10, Gfx.FONT_SMALL, arr, Gfx.TEXT_JUSTIFY_CENTER );
dc.drawText( (dc.getWidth() / 2), (dc.getHeight() / 2) + 40, Gfx.FONT_SMALL, due, Gfx.TEXT_JUSTIFY_CENTER );
}
else {
dc.drawText( (dc.getWidth() / 2), (dc.getHeight() / 2), Gfx.FONT_SMALL, "No schedule avail", Gfx.TEXT_JUSTIFY_CENTER );
}
}
function setPosition(info) {
var url = "http://web.0l.de:8080/";
var parameters = { "Circle" => info.position.toDegrees()[0] + "," +
info.position.toDegrees()[1] + ",150",
"ReturnList" => "StopPointName,DestinationName,LineName,EstimatedTime" };
var options = { :method => Comm.HTTP_REQUEST_METHOD_GET };
Comm.makeJsonRequest(url, parameters, options, method(:requestCompleted));
}
function requestCompleted(responseCode, data) {
Sys.println("Request completed: " + responseCode);
if (responseCode == 200) {
schedule = data;
redraw();
}
}
function redraw() {
WatchUi.requestUpdate();
}
}