-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MMM-DarkSkyForecast support with location picker
- Add url_launcher and google_map_location_picker packages - Add ModuleDarkSkyForecast with Google maps location picker - Change module position picker header from "Position" to "Module position" to not confuse it with weather data location Important notes - Must generate a Google maps API key and add to AndroidManifest.xml and ModuleDarkSkyForecast.dart (look for PUT_GOOGLE_MAPS_API_KEY_HERE) This should be changed to a shared API key for the app. For now, see: https://pub.dev/packages/google_map_location_picker - The MMM-DarkSkyForecast module must be based on a fork that uses OpenWeatherMap instead of DarkSky, since the latter is no longer free. Refer to https://github.com/smartmirrorinc/MMM-DarkSkyForecast
- Loading branch information
Showing
6 changed files
with
188 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
part of components; | ||
|
||
class ModuleDarkSkyForecast extends PositionedModule { | ||
double latitude, longitude; | ||
int hourlyForecastInterval; | ||
String apikey; | ||
GoogleMapController mapController; | ||
|
||
ModuleDarkSkyForecast(id, module, position, _latitude, _longitude, | ||
_hourlyForecastInterval, _apikey) | ||
: latitude = _latitude, | ||
longitude = _longitude, | ||
hourlyForecastInterval = _hourlyForecastInterval, | ||
apikey = _apikey, | ||
super(id, module, position); | ||
|
||
factory ModuleDarkSkyForecast.fromJson(Map<String, dynamic> json) { | ||
double latitude = 57.048820; | ||
double longitude = 9.921747; | ||
int hourlyForecastInterval = 6; | ||
String apikey = ""; | ||
|
||
if (json.containsKey("config")) { | ||
if (json["config"].containsKey("latitude")) { | ||
latitude = json['config']['latitude']; | ||
} | ||
if (json["config"].containsKey("longitude")) { | ||
longitude = json['config']['longitude']; | ||
} | ||
if (json["config"].containsKey("hourlyForecastInterval")) { | ||
hourlyForecastInterval = json['config']['hourlyForecastInterval']; | ||
} | ||
if (json["config"].containsKey("apikey")) { | ||
apikey = json['config']['apikey']; | ||
} | ||
} | ||
|
||
return ModuleDarkSkyForecast( | ||
json['_meta']['id'], | ||
json['module'], | ||
modulePositionFromString(json['position']), | ||
latitude, | ||
longitude, | ||
hourlyForecastInterval, | ||
apikey); | ||
} | ||
|
||
static instantiate(Map<String, dynamic> json) => | ||
ModuleDarkSkyForecast.fromJson(json); | ||
|
||
@override | ||
String toString() { | ||
return "{id:$id, module:$module, position:${position.toString()}, " + | ||
"latitude: $latitude, " + | ||
"longitude: $longitude, " + | ||
"hourlyForecastInterval: $hourlyForecastInterval, " + | ||
"apikey: $apikey}"; | ||
} | ||
|
||
void _onMapCreated(GoogleMapController controller) { | ||
mapController = controller; | ||
} | ||
|
||
// TODO: this does not belong here | ||
String capString(String x) { | ||
if (x.length < 13) { | ||
return x; | ||
} else { | ||
return x.substring(0, 10) + "..."; | ||
} | ||
} | ||
|
||
@override | ||
void buildWidgets(BuildContext context, Function refresh) { | ||
super.buildWidgets(context, refresh); | ||
|
||
// API key input field | ||
widgets.add(Card( | ||
child: Column(children: [ | ||
ListTile( | ||
leading: Icon(Icons.vpn_key), | ||
title: TextField( | ||
onChanged: (String value) { | ||
apikey = value; | ||
}, | ||
style: TextStyle(fontSize: 12), | ||
decoration: InputDecoration( | ||
border: OutlineInputBorder(), | ||
labelText: "API key", | ||
labelStyle: TextStyle(fontWeight: FontWeight.bold), | ||
helperText: "Old value: " + capString(apikey)), | ||
)), | ||
ListTile( | ||
leading: Icon(Icons.help), | ||
title: Text("Where do I find my API key?"), | ||
onTap: () async { | ||
await launch("https://home.openweathermap.org/api_keys"); | ||
}, | ||
) | ||
]))); | ||
|
||
// Location picker | ||
widgets.add(Card( | ||
child: Column( | ||
children: [ | ||
// Header | ||
ListTile( | ||
leading: Icon(Icons.my_location), | ||
title: Text("Location", | ||
style: TextStyle(fontWeight: FontWeight.bold))), | ||
|
||
// Map showing current position (zoom only, no scrolling) | ||
SizedBox( | ||
child: GoogleMap( | ||
onMapCreated: _onMapCreated, | ||
mapToolbarEnabled: true, | ||
liteModeEnabled: false, | ||
scrollGesturesEnabled: false, | ||
initialCameraPosition: CameraPosition( | ||
target: LatLng(latitude, longitude), zoom: 10), | ||
markers: Set<Marker>.of([ | ||
Marker( | ||
markerId: MarkerId("Current"), | ||
position: LatLng(latitude, longitude)) | ||
]), | ||
), | ||
height: 200), | ||
|
||
// Button to open location picker | ||
RaisedButton( | ||
onPressed: () async { | ||
LocationResult result = await showLocationPicker(context, | ||
"PUT_GOOGLE_MAPS_API_KEY_HERE", // TODO: app-specific key | ||
initialCenter: LatLng(56.224288, 11.195565), // ~mid Denmark | ||
automaticallyAnimateToCurrentLocation: false, | ||
myLocationButtonEnabled: true, | ||
layersButtonEnabled: false, | ||
// accuracy must be 'best' or getting user position does not | ||
// work, might be related to | ||
// https://github.com/Baseflow/flutter-geolocator/issues/117 ? | ||
desiredAccuracy: LocationAccuracy.best, | ||
initialZoom: 6); | ||
|
||
latitude = result.latLng.latitude; | ||
longitude = result.latLng.longitude; | ||
|
||
// move "current position" map to new coords | ||
mapController.moveCamera( | ||
CameraUpdate.newLatLng(LatLng(latitude, longitude)), | ||
); | ||
refresh(this); | ||
}, | ||
|
||
child: Text('Pick location'), | ||
), | ||
], | ||
), | ||
)); | ||
} | ||
|
||
@override | ||
Map<String, dynamic> toJson() { | ||
Map<String, dynamic> json = super.toJson(); | ||
json['config'] = { | ||
'apikey': apikey, | ||
'forecastLayout': "table", | ||
'hourlyForecastInterval': hourlyForecastInterval, | ||
'label_timeFormat': "HH:mm", | ||
"latitude": latitude, | ||
"longitude": longitude | ||
}; | ||
return json; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters