From 1f2ab8a936e9477fdfabc487dbc648778dd5626b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20H=C3=B6gberg?= Date: Sun, 14 Jun 2026 18:15:59 +0200 Subject: [PATCH] Add support for Megawatt Charging System (MCS) connector So far only used by the Nobil data source --- _img/connectors/connector_mcs.svg | 14 + .../29.json | 938 ++++++++++++++++++ .../main/java/net/vonforst/evmap/api/Utils.kt | 4 +- .../net/vonforst/evmap/api/nobil/NobilApi.kt | 3 +- .../vonforst/evmap/api/nobil/NobilModel.kt | 2 +- .../net/vonforst/evmap/model/ChargersModel.kt | 1 + .../net/vonforst/evmap/storage/Database.kt | 12 +- .../main/res/drawable/ic_connector_mcs.xml | 51 + app/src/main/res/values/strings.xml | 1 + 9 files changed, 1021 insertions(+), 5 deletions(-) create mode 100644 _img/connectors/connector_mcs.svg create mode 100644 app/schemas/net.vonforst.evmap.storage.AppDatabase/29.json create mode 100644 app/src/main/res/drawable/ic_connector_mcs.xml diff --git a/_img/connectors/connector_mcs.svg b/_img/connectors/connector_mcs.svg new file mode 100644 index 000000000..049022bf0 --- /dev/null +++ b/_img/connectors/connector_mcs.svg @@ -0,0 +1,14 @@ + + connector_mcs + + + + + + + + + + + + diff --git a/app/schemas/net.vonforst.evmap.storage.AppDatabase/29.json b/app/schemas/net.vonforst.evmap.storage.AppDatabase/29.json new file mode 100644 index 000000000..d70a1c479 --- /dev/null +++ b/app/schemas/net.vonforst.evmap.storage.AppDatabase/29.json @@ -0,0 +1,938 @@ +{ + "formatVersion": 1, + "database": { + "version": 29, + "identityHash": "84f71cce385c444726ba336834ddf6b4", + "entities": [ + { + "tableName": "ChargeLocation", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `dataSource` TEXT NOT NULL, `name` TEXT NOT NULL, `coordinates` BLOB NOT NULL, `chargepoints` TEXT NOT NULL, `network` TEXT, `dataSourceUrl` TEXT NOT NULL, `url` TEXT, `editUrl` TEXT, `verified` INTEGER NOT NULL, `barrierFree` INTEGER, `operator` TEXT, `generalInformation` TEXT, `amenities` TEXT, `locationDescription` TEXT, `photos` TEXT, `chargecards` TEXT, `accessibility` TEXT, `license` TEXT, `networkUrl` TEXT, `chargerUrl` TEXT, `timeRetrieved` INTEGER NOT NULL, `isDetailed` INTEGER NOT NULL, `coordinatesProjected` BLOB NOT NULL, `city` TEXT, `country` TEXT, `postcode` TEXT, `street` TEXT, `fault_report_created` INTEGER, `fault_report_description` TEXT, `twentyfourSeven` INTEGER, `description` TEXT, `mostart` TEXT, `moend` TEXT, `tustart` TEXT, `tuend` TEXT, `westart` TEXT, `weend` TEXT, `thstart` TEXT, `thend` TEXT, `frstart` TEXT, `frend` TEXT, `sastart` TEXT, `saend` TEXT, `sustart` TEXT, `suend` TEXT, `hostart` TEXT, `hoend` TEXT, `freecharging` INTEGER, `freeparking` INTEGER, `descriptionShort` TEXT, `descriptionLong` TEXT, `chargepricecountry` TEXT, `chargepricenetwork` TEXT, `chargepriceplugTypes` TEXT, PRIMARY KEY(`id`, `dataSource`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dataSource", + "columnName": "dataSource", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "coordinates", + "columnName": "coordinates", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "chargepoints", + "columnName": "chargepoints", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "network", + "columnName": "network", + "affinity": "TEXT" + }, + { + "fieldPath": "dataSourceUrl", + "columnName": "dataSourceUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT" + }, + { + "fieldPath": "editUrl", + "columnName": "editUrl", + "affinity": "TEXT" + }, + { + "fieldPath": "verified", + "columnName": "verified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "barrierFree", + "columnName": "barrierFree", + "affinity": "INTEGER" + }, + { + "fieldPath": "operator", + "columnName": "operator", + "affinity": "TEXT" + }, + { + "fieldPath": "generalInformation", + "columnName": "generalInformation", + "affinity": "TEXT" + }, + { + "fieldPath": "amenities", + "columnName": "amenities", + "affinity": "TEXT" + }, + { + "fieldPath": "locationDescription", + "columnName": "locationDescription", + "affinity": "TEXT" + }, + { + "fieldPath": "photos", + "columnName": "photos", + "affinity": "TEXT" + }, + { + "fieldPath": "chargecards", + "columnName": "chargecards", + "affinity": "TEXT" + }, + { + "fieldPath": "accessibility", + "columnName": "accessibility", + "affinity": "TEXT" + }, + { + "fieldPath": "license", + "columnName": "license", + "affinity": "TEXT" + }, + { + "fieldPath": "networkUrl", + "columnName": "networkUrl", + "affinity": "TEXT" + }, + { + "fieldPath": "chargerUrl", + "columnName": "chargerUrl", + "affinity": "TEXT" + }, + { + "fieldPath": "timeRetrieved", + "columnName": "timeRetrieved", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isDetailed", + "columnName": "isDetailed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "coordinatesProjected", + "columnName": "coordinatesProjected", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "address.city", + "columnName": "city", + "affinity": "TEXT" + }, + { + "fieldPath": "address.country", + "columnName": "country", + "affinity": "TEXT" + }, + { + "fieldPath": "address.postcode", + "columnName": "postcode", + "affinity": "TEXT" + }, + { + "fieldPath": "address.street", + "columnName": "street", + "affinity": "TEXT" + }, + { + "fieldPath": "faultReport.created", + "columnName": "fault_report_created", + "affinity": "INTEGER" + }, + { + "fieldPath": "faultReport.description", + "columnName": "fault_report_description", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.twentyfourSeven", + "columnName": "twentyfourSeven", + "affinity": "INTEGER" + }, + { + "fieldPath": "openinghours.description", + "columnName": "description", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.monday.start", + "columnName": "mostart", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.monday.end", + "columnName": "moend", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.tuesday.start", + "columnName": "tustart", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.tuesday.end", + "columnName": "tuend", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.wednesday.start", + "columnName": "westart", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.wednesday.end", + "columnName": "weend", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.thursday.start", + "columnName": "thstart", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.thursday.end", + "columnName": "thend", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.friday.start", + "columnName": "frstart", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.friday.end", + "columnName": "frend", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.saturday.start", + "columnName": "sastart", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.saturday.end", + "columnName": "saend", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.sunday.start", + "columnName": "sustart", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.sunday.end", + "columnName": "suend", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.holiday.start", + "columnName": "hostart", + "affinity": "TEXT" + }, + { + "fieldPath": "openinghours.days.holiday.end", + "columnName": "hoend", + "affinity": "TEXT" + }, + { + "fieldPath": "cost.freecharging", + "columnName": "freecharging", + "affinity": "INTEGER" + }, + { + "fieldPath": "cost.freeparking", + "columnName": "freeparking", + "affinity": "INTEGER" + }, + { + "fieldPath": "cost.descriptionShort", + "columnName": "descriptionShort", + "affinity": "TEXT" + }, + { + "fieldPath": "cost.descriptionLong", + "columnName": "descriptionLong", + "affinity": "TEXT" + }, + { + "fieldPath": "chargepriceData.country", + "columnName": "chargepricecountry", + "affinity": "TEXT" + }, + { + "fieldPath": "chargepriceData.network", + "columnName": "chargepricenetwork", + "affinity": "TEXT" + }, + { + "fieldPath": "chargepriceData.plugTypes", + "columnName": "chargepriceplugTypes", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id", + "dataSource" + ] + } + }, + { + "tableName": "Favorite", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`favoriteId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `chargerId` INTEGER NOT NULL, `chargerDataSource` TEXT NOT NULL, FOREIGN KEY(`chargerId`, `chargerDataSource`) REFERENCES `ChargeLocation`(`id`, `dataSource`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "favoriteId", + "columnName": "favoriteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "chargerId", + "columnName": "chargerId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "chargerDataSource", + "columnName": "chargerDataSource", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "favoriteId" + ] + }, + "indices": [ + { + "name": "index_Favorite_chargerId_chargerDataSource", + "unique": false, + "columnNames": [ + "chargerId", + "chargerDataSource" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Favorite_chargerId_chargerDataSource` ON `${TABLE_NAME}` (`chargerId`, `chargerDataSource`)" + } + ], + "foreignKeys": [ + { + "table": "ChargeLocation", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "chargerId", + "chargerDataSource" + ], + "referencedColumns": [ + "id", + "dataSource" + ] + } + ] + }, + { + "tableName": "BooleanFilterValue", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `value` INTEGER NOT NULL, `dataSource` TEXT NOT NULL, `profile` INTEGER NOT NULL, PRIMARY KEY(`key`, `profile`, `dataSource`), FOREIGN KEY(`profile`, `dataSource`) REFERENCES `FilterProfile`(`id`, `dataSource`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dataSource", + "columnName": "dataSource", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "profile", + "columnName": "profile", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "key", + "profile", + "dataSource" + ] + }, + "indices": [ + { + "name": "index_BooleanFilterValue_profile_dataSource", + "unique": false, + "columnNames": [ + "profile", + "dataSource" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_BooleanFilterValue_profile_dataSource` ON `${TABLE_NAME}` (`profile`, `dataSource`)" + } + ], + "foreignKeys": [ + { + "table": "FilterProfile", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "profile", + "dataSource" + ], + "referencedColumns": [ + "id", + "dataSource" + ] + } + ] + }, + { + "tableName": "MultipleChoiceFilterValue", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `values` TEXT NOT NULL, `all` INTEGER NOT NULL, `dataSource` TEXT NOT NULL, `profile` INTEGER NOT NULL, PRIMARY KEY(`key`, `profile`, `dataSource`), FOREIGN KEY(`profile`, `dataSource`) REFERENCES `FilterProfile`(`id`, `dataSource`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "values", + "columnName": "values", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "all", + "columnName": "all", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dataSource", + "columnName": "dataSource", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "profile", + "columnName": "profile", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "key", + "profile", + "dataSource" + ] + }, + "indices": [ + { + "name": "index_MultipleChoiceFilterValue_profile_dataSource", + "unique": false, + "columnNames": [ + "profile", + "dataSource" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_MultipleChoiceFilterValue_profile_dataSource` ON `${TABLE_NAME}` (`profile`, `dataSource`)" + } + ], + "foreignKeys": [ + { + "table": "FilterProfile", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "profile", + "dataSource" + ], + "referencedColumns": [ + "id", + "dataSource" + ] + } + ] + }, + { + "tableName": "SliderFilterValue", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `value` INTEGER NOT NULL, `dataSource` TEXT NOT NULL, `profile` INTEGER NOT NULL, PRIMARY KEY(`key`, `profile`, `dataSource`), FOREIGN KEY(`profile`, `dataSource`) REFERENCES `FilterProfile`(`id`, `dataSource`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dataSource", + "columnName": "dataSource", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "profile", + "columnName": "profile", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "key", + "profile", + "dataSource" + ] + }, + "indices": [ + { + "name": "index_SliderFilterValue_profile_dataSource", + "unique": false, + "columnNames": [ + "profile", + "dataSource" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_SliderFilterValue_profile_dataSource` ON `${TABLE_NAME}` (`profile`, `dataSource`)" + } + ], + "foreignKeys": [ + { + "table": "FilterProfile", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "profile", + "dataSource" + ], + "referencedColumns": [ + "id", + "dataSource" + ] + } + ] + }, + { + "tableName": "FilterProfile", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, `dataSource` TEXT NOT NULL, `id` INTEGER NOT NULL, `order` INTEGER NOT NULL, PRIMARY KEY(`dataSource`, `id`))", + "fields": [ + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dataSource", + "columnName": "dataSource", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "dataSource", + "id" + ] + }, + "indices": [ + { + "name": "index_FilterProfile_dataSource_name", + "unique": true, + "columnNames": [ + "dataSource", + "name" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_FilterProfile_dataSource_name` ON `${TABLE_NAME}` (`dataSource`, `name`)" + } + ] + }, + { + "tableName": "RecentAutocompletePlace", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `dataSource` TEXT NOT NULL, `timestamp` INTEGER NOT NULL, `primaryText` TEXT NOT NULL, `secondaryText` TEXT NOT NULL, `latLng` TEXT NOT NULL, `viewport` TEXT, `types` TEXT NOT NULL, PRIMARY KEY(`id`, `dataSource`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dataSource", + "columnName": "dataSource", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "primaryText", + "columnName": "primaryText", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "secondaryText", + "columnName": "secondaryText", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "latLng", + "columnName": "latLng", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "viewport", + "columnName": "viewport", + "affinity": "TEXT" + }, + { + "fieldPath": "types", + "columnName": "types", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id", + "dataSource" + ] + } + }, + { + "tableName": "GEPlug", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, PRIMARY KEY(`name`))", + "fields": [ + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "name" + ] + } + }, + { + "tableName": "GENetwork", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, PRIMARY KEY(`name`))", + "fields": [ + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "name" + ] + } + }, + { + "tableName": "GEChargeCard", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "OCMConnectionType", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `formalName` TEXT, `discontinued` INTEGER, `obsolete` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "formalName", + "columnName": "formalName", + "affinity": "TEXT" + }, + { + "fieldPath": "discontinued", + "columnName": "discontinued", + "affinity": "INTEGER" + }, + { + "fieldPath": "obsolete", + "columnName": "obsolete", + "affinity": "INTEGER" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "OCMCountry", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `isoCode` TEXT NOT NULL, `continentCode` TEXT, `title` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isoCode", + "columnName": "isoCode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "continentCode", + "columnName": "continentCode", + "affinity": "TEXT" + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "OCMOperator", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `websiteUrl` TEXT, `title` TEXT NOT NULL, `contactEmail` TEXT, `contactTelephone1` TEXT, `contactTelephone2` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "websiteUrl", + "columnName": "websiteUrl", + "affinity": "TEXT" + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "contactEmail", + "columnName": "contactEmail", + "affinity": "TEXT" + }, + { + "fieldPath": "contactTelephone1", + "columnName": "contactTelephone1", + "affinity": "TEXT" + }, + { + "fieldPath": "contactTelephone2", + "columnName": "contactTelephone2", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "OSMNetwork", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, PRIMARY KEY(`name`))", + "fields": [ + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "name" + ] + } + }, + { + "tableName": "SavedRegion", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`region` BLOB NOT NULL, `dataSource` TEXT NOT NULL, `timeRetrieved` INTEGER NOT NULL, `filters` TEXT, `isDetailed` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)", + "fields": [ + { + "fieldPath": "region", + "columnName": "region", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "dataSource", + "columnName": "dataSource", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "timeRetrieved", + "columnName": "timeRetrieved", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "filters", + "columnName": "filters", + "affinity": "TEXT" + }, + { + "fieldPath": "isDetailed", + "columnName": "isDetailed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_SavedRegion_filters_dataSource", + "unique": false, + "columnNames": [ + "filters", + "dataSource" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_SavedRegion_filters_dataSource` ON `${TABLE_NAME}` (`filters`, `dataSource`)" + } + ] + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '84f71cce385c444726ba336834ddf6b4')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/net/vonforst/evmap/api/Utils.kt b/app/src/main/java/net/vonforst/evmap/api/Utils.kt index 58c9b13a6..c3a14f613 100644 --- a/app/src/main/java/net/vonforst/evmap/api/Utils.kt +++ b/app/src/main/java/net/vonforst/evmap/api/Utils.kt @@ -20,7 +20,8 @@ private val plugNames = mapOf( Chargepoint.SUPERCHARGER to R.string.plug_supercharger, Chargepoint.CEE_BLAU to R.string.plug_cee_blau, Chargepoint.CEE_ROT to R.string.plug_cee_rot, - Chargepoint.TESLA_ROADSTER_HPC to R.string.plug_roadster_hpc + Chargepoint.TESLA_ROADSTER_HPC to R.string.plug_roadster_hpc, + Chargepoint.MCS to R.string.plug_mcs ) fun nameForPlugType(ctx: StringProvider, type: String): String = @@ -63,6 +64,7 @@ fun iconForPlugType(type: String): Int = Chargepoint.CEE_BLAU -> R.drawable.ic_connector_cee_blau Chargepoint.CEE_ROT -> R.drawable.ic_connector_cee_rot Chargepoint.TYPE_1 -> R.drawable.ic_connector_typ1 + Chargepoint.MCS -> R.drawable.ic_connector_mcs // TODO: add other connectors else -> R.drawable.ic_connector_unknown } diff --git a/app/src/main/java/net/vonforst/evmap/api/nobil/NobilApi.kt b/app/src/main/java/net/vonforst/evmap/api/nobil/NobilApi.kt index 1f8c5f804..e6b40e4ab 100644 --- a/app/src/main/java/net/vonforst/evmap/api/nobil/NobilApi.kt +++ b/app/src/main/java/net/vonforst/evmap/api/nobil/NobilApi.kt @@ -234,7 +234,8 @@ class NobilApiWrapper( Chargepoint.TYPE_2_PLUG, Chargepoint.CCS_UNKNOWN, Chargepoint.CHADEMO, - Chargepoint.SUPERCHARGER + Chargepoint.SUPERCHARGER, + Chargepoint.MCS ) val connectorsMap = connectors.associateWith { connector -> nameForPlugType(sp, connector) diff --git a/app/src/main/java/net/vonforst/evmap/api/nobil/NobilModel.kt b/app/src/main/java/net/vonforst/evmap/api/nobil/NobilModel.kt index b5b72d0af..171a17b02 100644 --- a/app/src/main/java/net/vonforst/evmap/api/nobil/NobilModel.kt +++ b/app/src/main/java/net/vonforst/evmap/api/nobil/NobilModel.kt @@ -232,7 +232,7 @@ data class NobilChargerStation( "40" -> Chargepoint.SUPERCHARGER // Tesla Connector Model "70" -> return null // Hydrogen "82" -> return null // Biogas - "87" -> "" // MCS + "87" -> Chargepoint.MCS // These are deprecated and not used "50" -> "" // Type 2 + Schuko diff --git a/app/src/main/java/net/vonforst/evmap/model/ChargersModel.kt b/app/src/main/java/net/vonforst/evmap/model/ChargersModel.kt index 99851ad93..abcd5062b 100644 --- a/app/src/main/java/net/vonforst/evmap/model/ChargersModel.kt +++ b/app/src/main/java/net/vonforst/evmap/model/ChargersModel.kt @@ -470,6 +470,7 @@ data class Chargepoint( const val CEE_BLAU = "CEE Blau" const val CEE_ROT = "CEE Rot" const val TESLA_ROADSTER_HPC = "Tesla HPC" + const val MCS = "Megawatt Charging System" } } diff --git a/app/src/main/java/net/vonforst/evmap/storage/Database.kt b/app/src/main/java/net/vonforst/evmap/storage/Database.kt index 662684d1f..bf66c2f26 100644 --- a/app/src/main/java/net/vonforst/evmap/storage/Database.kt +++ b/app/src/main/java/net/vonforst/evmap/storage/Database.kt @@ -40,7 +40,7 @@ import net.vonforst.evmap.model.SliderFilterValue OCMOperator::class, OSMNetwork::class, SavedRegion::class - ], version = 28 + ], version = 29 ) @TypeConverters(Converters::class, GeometryConverters::class) abstract class AppDatabase : RoomDatabase() { @@ -85,7 +85,7 @@ abstract class AppDatabase : RoomDatabase() { MIGRATION_12, MIGRATION_13, MIGRATION_14, MIGRATION_15, MIGRATION_16, MIGRATION_17, MIGRATION_18, MIGRATION_19, MIGRATION_20, MIGRATION_21, MIGRATION_22, MIGRATION_23, MIGRATION_24, MIGRATION_25, MIGRATION_26, - MIGRATION_27, MIGRATION_28 + MIGRATION_27, MIGRATION_28, MIGRATION_29 ) .addCallback(object : Callback() { override fun onCreate(db: SupportSQLiteDatabase) { @@ -555,6 +555,14 @@ abstract class AppDatabase : RoomDatabase() { db.execSQL("DELETE FROM ChargeLocation WHERE `dataSource` = 'nobil'") } } + + private val MIGRATION_29 = object : Migration(28, 29) { + override fun migrate(db: SupportSQLiteDatabase) { + // Force nobil data refresh to update MCS connectors + db.execSQL("DELETE FROM SavedRegion WHERE `dataSource` = 'nobil'") + db.execSQL("DELETE FROM ChargeLocation WHERE `dataSource` = 'nobil'") + } + } } /** diff --git a/app/src/main/res/drawable/ic_connector_mcs.xml b/app/src/main/res/drawable/ic_connector_mcs.xml new file mode 100644 index 000000000..529e80469 --- /dev/null +++ b/app/src/main/res/drawable/ic_connector_mcs.xml @@ -0,0 +1,51 @@ + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5d41c3f8d..31313cab4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -72,6 +72,7 @@ CEE Blue CEE Red Tesla Roadster (2008) HPC + MCS all none more…