├── docs ├── HA-Addon.jpg └── exampleResponse.json ├── httpgateway ├── docs │ ├── HA-Addon.jpg │ └── exampleResponse.json ├── ismart-api-gateway-0.0.3-full.jar ├── Dockerfile ├── CHANGELOG.md ├── config.yaml ├── README.md ├── LICENSE └── DOCS.md ├── repository.yaml ├── LICENSE └── README.md /docs/HA-Addon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseEngineeringDE/iSmart-Gateway-Home-Assistant-Add-on/HEAD/docs/HA-Addon.jpg -------------------------------------------------------------------------------- /httpgateway/docs/HA-Addon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseEngineeringDE/iSmart-Gateway-Home-Assistant-Add-on/HEAD/httpgateway/docs/HA-Addon.jpg -------------------------------------------------------------------------------- /httpgateway/ismart-api-gateway-0.0.3-full.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReverseEngineeringDE/iSmart-Gateway-Home-Assistant-Add-on/HEAD/httpgateway/ismart-api-gateway-0.0.3-full.jar -------------------------------------------------------------------------------- /httpgateway/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin 2 | ARG TARGETPLATFORM 3 | 4 | WORKDIR / 5 | ADD ismart-api-gateway-0.0.3-full.jar ismart-api-gateway-0.0.3-full.jar 6 | EXPOSE 42042 7 | CMD ["java","-jar","/ismart-api-gateway-0.0.3-full.jar"] 8 | -------------------------------------------------------------------------------- /httpgateway/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # SAIC API Gateway 2 | 3 | ## 0.0.3 4 | 5 | - initial Release 6 | - rebuild for HASS.IO addon support, now you could add it over the repository option! 7 | - adding multiarch-support (it's JAVA!) 8 | - update DOCS and README 9 | -------------------------------------------------------------------------------- /repository.yaml: -------------------------------------------------------------------------------- 1 | # https://developers.home-assistant.io/docs/add-ons/repository#repository-configuration 2 | name: iSmart Gateway Home Assistant Add-on 3 | url: 'https://github.com/ReverseEngineeringDE/iSmart-Gateway-Home-Assistant-Add-on' 4 | maintainer: ReverseEngineeringDE 5 | -------------------------------------------------------------------------------- /httpgateway/config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | arch: 3 | - armhf 4 | - armv7 5 | - aarch64 6 | - amd64 7 | - i386 8 | description: "Rest api-gateway for SAIC cars like MG5, ZS EV or Marvel R" 9 | name: "SAIC API Gateway" 10 | url: "https://github.com/ReverseEngineeringDE/iSmart-Gateway-Home-Assistant-Add-on" 11 | ports: 12 | 42042/tcp: 42042 13 | slug: saic_api 14 | version: "0.0.3" 15 | stage: "experimental" 16 | -------------------------------------------------------------------------------- /httpgateway/README.md: -------------------------------------------------------------------------------- 1 | # MG iSmart/iSmart lite (SAIC API) API-Gateway for Home Assistant 2 | 3 | This repository allows Home Assistant users to access the data of their MG5 electric (2022) car (https://www.mgmotor.de/model/mg5) via the iSmart/iSmart lite API (other models with iSmart might also work). 4 | 5 | Main project can be found here (help needed): 6 | [SAIC API Documentation](https://github.com/ReverseEngineeringDE/SAIC-API-Documentation) 7 | 8 | Used .jar file based on: [saic-java-api-gateway](https://github.com/ReverseEngineeringDE/SAIC-API-Documentation/tree/main/saic-java-api-gateway) 9 | 10 | ![Supports aarch64 Architecture][aarch64-shield] 11 | ![Supports amd64 Architecture][amd64-shield] 12 | ![Supports armhf Architecture][armhf-shield] 13 | ![Supports armv7 Architecture][armv7-shield] 14 | 15 | [aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg 16 | [amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg 17 | [armhf-shield]: https://img.shields.io/badge/armhf-yes-green.svg 18 | [armv7-shield]: https://img.shields.io/badge/armv7-yes-green.svg 19 | [i386-shield]: https://img.shields.io/badge/i386-yes-green.svg 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ReverseEngineeringDE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /httpgateway/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ReverseEngineeringDE 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/exampleResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "applicationData": { 3 | "bmsAdpPubChrgSttnDspCmd": 0, 4 | "bmsAltngChrgCrntDspCmd": 0, 5 | "bmsChrgCtrlDspCmd": 2, 6 | "bmsChrgOtptCrntReq": 1023, 7 | "bmsChrgOtptCrntReqV": null, 8 | "bmsChrgOtptCrntReqVPresent": false, 9 | "bmsChrgSpRsn": 0, 10 | "bmsChrgSts": 0, 11 | "bmsDsChrgSpRsn": null, 12 | "bmsDsChrgSpRsnPresent": false, 13 | "bmsEstdElecRng": 284, 14 | "bmsOnBdChrgTrgtSOCDspCmd": 7, 15 | "bmsPackCrnt": 20000, 16 | "bmsPackCrntV": null, 17 | "bmsPackCrntVPresent": false, 18 | "bmsPackSOCDsp": 318, 19 | "bmsPackVol": 1575, 20 | "bmsPTCHeatReqDspCmd": 0, 21 | "bmsPTCHeatResp": null, 22 | "bmsPTCHeatRespPresent": false, 23 | "bmsPTCHeatSpRsn": 0, 24 | "bmsPTCHeatSpRsnPresent": true, 25 | "bmsReserCtrlDspCmd": 0, 26 | "bmsReserSpHourDspCmd": 0, 27 | "bmsReserSpMintueDspCmd": 0, 28 | "bmsReserStHourDspCmd": 0, 29 | "bmsReserStMintueDspCmd": 0, 30 | "ccuEleccLckCtrlDspCmd": null, 31 | "ccuEleccLckCtrlDspCmdPresent": false, 32 | "ccuOffBdChrgrPlugOn": null, 33 | "ccuOffBdChrgrPlugOnPresent": false, 34 | "ccuOnbdChrgrPlugOn": null, 35 | "ccuOnbdChrgrPlugOnPresent": false, 36 | "chargeStatus": { 37 | "chargingDuration": 0, 38 | "chargingDurationPresent": true, 39 | "chargingElectricityPhase": null, 40 | "chargingElectricityPhasePresent": false, 41 | "chargingGunState": false, 42 | "chargingPileID": null, 43 | "chargingPileIDPresent": false, 44 | "chargingPileSupplier": null, 45 | "chargingPileSupplierPresent": false, 46 | "chargingType": 1, 47 | "endTime": 1669447443, 48 | "endTimePresent": true, 49 | "extendedData1": null, 50 | "extendedData1Present": false, 51 | "extendedData2": null, 52 | "extendedData2Present": false, 53 | "extendedData3": null, 54 | "extendedData3Present": false, 55 | "extendedData4": null, 56 | "extendedData4Present": false, 57 | "fotaLowestVoltage": null, 58 | "fotaLowestVoltagePresent": false, 59 | "fuelRangeElec": 800, 60 | "lastChargeEndingPower": 271, 61 | "lastChargeEndingPowerPresent": true, 62 | "mileage": XXXXXX, 63 | "mileageOfDay": 0, 64 | "mileageOfDayPresent": true, 65 | "mileageSinceLastCharge": 90, 66 | "mileageSinceLastChargePresent": true, 67 | "powerUsageOfDay": 7, 68 | "powerUsageOfDayPresent": true, 69 | "powerUsageSinceLastCharge": 41, 70 | "powerUsageSinceLastChargePresent": true, 71 | "realtimePower": 231, 72 | "startTime": 0, 73 | "startTimePresent": true, 74 | "staticEnergyConsumption": null, 75 | "staticEnergyConsumptionPresent": false, 76 | "totalBatteryCapacity": 725, 77 | "totalBatteryCapacityPresent": true, 78 | "workingCurrent": 20000, 79 | "workingCurrentPresent": true, 80 | "workingVoltage": 1575, 81 | "workingVoltagePresent": true 82 | }, 83 | "chrgngAddedElecRng": null, 84 | "chrgngAddedElecRngPresent": false, 85 | "chrgngAddedElecRngV": null, 86 | "chrgngAddedElecRngVPresent": false, 87 | "chrgngDoorOpenCnd": null, 88 | "chrgngDoorOpenCndPresent": false, 89 | "chrgngDoorPosSts": null, 90 | "chrgngDoorPosStsPresent": false, 91 | "chrgngRmnngTime": 1023, 92 | "chrgngRmnngTimeV": 1, 93 | "chrgngSpdngTime": null, 94 | "chrgngSpdngTimePresent": false, 95 | "chrgngSpdngTimeV": null, 96 | "chrgngSpdngTimeVPresent": false, 97 | "clstrElecRngToEPT": 80, 98 | "disChrgngRmnngTime": null, 99 | "disChrgngRmnngTimePresent": false, 100 | "disChrgngRmnngTimeV": null, 101 | "disChrgngRmnngTimeVPresent": false, 102 | "imcuChrgngEstdElecRng": null, 103 | "imcuChrgngEstdElecRngPresent": false, 104 | "imcuChrgngEstdElecRngV": null, 105 | "imcuChrgngEstdElecRngVPresent": false, 106 | "imcuDschrgngEstdElecRng": null, 107 | "imcuDschrgngEstdElecRngPresent": false, 108 | "imcuDschrgngEstdElecRngV": null, 109 | "imcuDschrgngEstdElecRngVPresent": false, 110 | "imcuVehElecRng": null, 111 | "imcuVehElecRngPresent": false, 112 | "imcuVehElecRngV": null, 113 | "imcuVehElecRngVPresent": false, 114 | "onBdChrgrAltrCrntInptCrnt": null, 115 | "onBdChrgrAltrCrntInptCrntPresent": false, 116 | "onBdChrgrAltrCrntInptVol": null, 117 | "onBdChrgrAltrCrntInptVolPresent": false 118 | }, 119 | "body": { 120 | "ackMessageCounter": null, 121 | "ackMessageCounterPresent": false, 122 | "ackRequired": null, 123 | "ackRequiredPresent": false, 124 | "applicationDataEncoding": "perUnaligned", 125 | "applicationDataEncodingPresent": true, 126 | "applicationDataLength": 71, 127 | "applicationDataLengthPresent": true, 128 | "applicationDataProtocolVersion": 768, 129 | "applicationDataProtocolVersionPresent": true, 130 | "applicationID": "516", 131 | "dlMessageCounter": null, 132 | "dlMessageCounterPresent": false, 133 | "errorMessage": null, 134 | "errorMessagePresent": false, 135 | "eventCreationTime": 1669552549, 136 | "eventID": 1418887435, 137 | "eventIDPresent": true, 138 | "messageID": 6, 139 | "result": 0, 140 | "resultPresent": true, 141 | "testFlag": 2, 142 | "testFlagPresent": true, 143 | "token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 144 | "tokenPresent": true, 145 | "uid": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 146 | "uidPresent": true, 147 | "ulMessageCounter": null, 148 | "ulMessageCounterPresent": false, 149 | "vin": "XXXXXXXXXXXXXXXXXX", 150 | "vinPresent": true 151 | }, 152 | "header": { 153 | "dispatcherBodyEncoding": 0, 154 | "dispatcherMessageLength": 117, 155 | "protocolVersion": 48 156 | }, 157 | "reserved": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX" 158 | } 159 | -------------------------------------------------------------------------------- /httpgateway/docs/exampleResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "applicationData": { 3 | "bmsAdpPubChrgSttnDspCmd": 0, 4 | "bmsAltngChrgCrntDspCmd": 0, 5 | "bmsChrgCtrlDspCmd": 2, 6 | "bmsChrgOtptCrntReq": 1023, 7 | "bmsChrgOtptCrntReqV": null, 8 | "bmsChrgOtptCrntReqVPresent": false, 9 | "bmsChrgSpRsn": 0, 10 | "bmsChrgSts": 0, 11 | "bmsDsChrgSpRsn": null, 12 | "bmsDsChrgSpRsnPresent": false, 13 | "bmsEstdElecRng": 284, 14 | "bmsOnBdChrgTrgtSOCDspCmd": 7, 15 | "bmsPackCrnt": 20000, 16 | "bmsPackCrntV": null, 17 | "bmsPackCrntVPresent": false, 18 | "bmsPackSOCDsp": 318, 19 | "bmsPackVol": 1575, 20 | "bmsPTCHeatReqDspCmd": 0, 21 | "bmsPTCHeatResp": null, 22 | "bmsPTCHeatRespPresent": false, 23 | "bmsPTCHeatSpRsn": 0, 24 | "bmsPTCHeatSpRsnPresent": true, 25 | "bmsReserCtrlDspCmd": 0, 26 | "bmsReserSpHourDspCmd": 0, 27 | "bmsReserSpMintueDspCmd": 0, 28 | "bmsReserStHourDspCmd": 0, 29 | "bmsReserStMintueDspCmd": 0, 30 | "ccuEleccLckCtrlDspCmd": null, 31 | "ccuEleccLckCtrlDspCmdPresent": false, 32 | "ccuOffBdChrgrPlugOn": null, 33 | "ccuOffBdChrgrPlugOnPresent": false, 34 | "ccuOnbdChrgrPlugOn": null, 35 | "ccuOnbdChrgrPlugOnPresent": false, 36 | "chargeStatus": { 37 | "chargingDuration": 0, 38 | "chargingDurationPresent": true, 39 | "chargingElectricityPhase": null, 40 | "chargingElectricityPhasePresent": false, 41 | "chargingGunState": false, 42 | "chargingPileID": null, 43 | "chargingPileIDPresent": false, 44 | "chargingPileSupplier": null, 45 | "chargingPileSupplierPresent": false, 46 | "chargingType": 1, 47 | "endTime": 1669447443, 48 | "endTimePresent": true, 49 | "extendedData1": null, 50 | "extendedData1Present": false, 51 | "extendedData2": null, 52 | "extendedData2Present": false, 53 | "extendedData3": null, 54 | "extendedData3Present": false, 55 | "extendedData4": null, 56 | "extendedData4Present": false, 57 | "fotaLowestVoltage": null, 58 | "fotaLowestVoltagePresent": false, 59 | "fuelRangeElec": 800, 60 | "lastChargeEndingPower": 271, 61 | "lastChargeEndingPowerPresent": true, 62 | "mileage": XXXXXX, 63 | "mileageOfDay": 0, 64 | "mileageOfDayPresent": true, 65 | "mileageSinceLastCharge": 90, 66 | "mileageSinceLastChargePresent": true, 67 | "powerUsageOfDay": 7, 68 | "powerUsageOfDayPresent": true, 69 | "powerUsageSinceLastCharge": 41, 70 | "powerUsageSinceLastChargePresent": true, 71 | "realtimePower": 231, 72 | "startTime": 0, 73 | "startTimePresent": true, 74 | "staticEnergyConsumption": null, 75 | "staticEnergyConsumptionPresent": false, 76 | "totalBatteryCapacity": 725, 77 | "totalBatteryCapacityPresent": true, 78 | "workingCurrent": 20000, 79 | "workingCurrentPresent": true, 80 | "workingVoltage": 1575, 81 | "workingVoltagePresent": true 82 | }, 83 | "chrgngAddedElecRng": null, 84 | "chrgngAddedElecRngPresent": false, 85 | "chrgngAddedElecRngV": null, 86 | "chrgngAddedElecRngVPresent": false, 87 | "chrgngDoorOpenCnd": null, 88 | "chrgngDoorOpenCndPresent": false, 89 | "chrgngDoorPosSts": null, 90 | "chrgngDoorPosStsPresent": false, 91 | "chrgngRmnngTime": 1023, 92 | "chrgngRmnngTimeV": 1, 93 | "chrgngSpdngTime": null, 94 | "chrgngSpdngTimePresent": false, 95 | "chrgngSpdngTimeV": null, 96 | "chrgngSpdngTimeVPresent": false, 97 | "clstrElecRngToEPT": 80, 98 | "disChrgngRmnngTime": null, 99 | "disChrgngRmnngTimePresent": false, 100 | "disChrgngRmnngTimeV": null, 101 | "disChrgngRmnngTimeVPresent": false, 102 | "imcuChrgngEstdElecRng": null, 103 | "imcuChrgngEstdElecRngPresent": false, 104 | "imcuChrgngEstdElecRngV": null, 105 | "imcuChrgngEstdElecRngVPresent": false, 106 | "imcuDschrgngEstdElecRng": null, 107 | "imcuDschrgngEstdElecRngPresent": false, 108 | "imcuDschrgngEstdElecRngV": null, 109 | "imcuDschrgngEstdElecRngVPresent": false, 110 | "imcuVehElecRng": null, 111 | "imcuVehElecRngPresent": false, 112 | "imcuVehElecRngV": null, 113 | "imcuVehElecRngVPresent": false, 114 | "onBdChrgrAltrCrntInptCrnt": null, 115 | "onBdChrgrAltrCrntInptCrntPresent": false, 116 | "onBdChrgrAltrCrntInptVol": null, 117 | "onBdChrgrAltrCrntInptVolPresent": false 118 | }, 119 | "body": { 120 | "ackMessageCounter": null, 121 | "ackMessageCounterPresent": false, 122 | "ackRequired": null, 123 | "ackRequiredPresent": false, 124 | "applicationDataEncoding": "perUnaligned", 125 | "applicationDataEncodingPresent": true, 126 | "applicationDataLength": 71, 127 | "applicationDataLengthPresent": true, 128 | "applicationDataProtocolVersion": 768, 129 | "applicationDataProtocolVersionPresent": true, 130 | "applicationID": "516", 131 | "dlMessageCounter": null, 132 | "dlMessageCounterPresent": false, 133 | "errorMessage": null, 134 | "errorMessagePresent": false, 135 | "eventCreationTime": 1669552549, 136 | "eventID": 1418887435, 137 | "eventIDPresent": true, 138 | "messageID": 6, 139 | "result": 0, 140 | "resultPresent": true, 141 | "testFlag": 2, 142 | "testFlagPresent": true, 143 | "token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 144 | "tokenPresent": true, 145 | "uid": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 146 | "uidPresent": true, 147 | "ulMessageCounter": null, 148 | "ulMessageCounterPresent": false, 149 | "vin": "XXXXXXXXXXXXXXXXXX", 150 | "vinPresent": true 151 | }, 152 | "header": { 153 | "dispatcherBodyEncoding": 0, 154 | "dispatcherMessageLength": 117, 155 | "protocolVersion": 48 156 | }, 157 | "reserved": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX" 158 | } 159 | -------------------------------------------------------------------------------- /httpgateway/DOCS.md: -------------------------------------------------------------------------------- 1 | # MG iSmart/iSmart lite (SAIC API) API-Gateway for Home Assistant 2 | 3 | This repository allows Home Assistant users to access the data of their MG5 electric (2022) car (https://www.mgmotor.de/model/mg5) via the iSmart/iSmart lite API (other models with iSmart might also work). 4 | 5 | Main project can be found here (help needed): 6 | [SAIC API Documentation](https://github.com/ReverseEngineeringDE/SAIC-API-Documentation) 7 | 8 | Used .jar file based on: [saic-java-api-gateway](https://github.com/ReverseEngineeringDE/SAIC-API-Documentation/tree/main/saic-java-api-gateway) 9 | 10 | 11 | **Warning: Don't access/refresh the API regularly.** It will drain your 12v car battery and you will be unable to start it! I implemented a 600s API refresh cooldown cache but be careful with your automations. This will be improved in future versions. 12 | 13 | This is a work in progress (WIP). 14 | 15 | ![Supports aarch64 Architecture][aarch64-shield] 16 | ![Supports amd64 Architecture][amd64-shield] 17 | ![Supports armhf Architecture][armhf-shield] 18 | ![Supports armv7 Architecture][armv7-shield] 19 | 20 | 21 | ## Overview 22 | 23 | 24 | ![Home Assistant Screenshot SAIC API](./docs/HA-Addon.jpg) 25 | 26 | 27 | What is possible at the moment: 28 | 29 | - Login & Read vehicle charging status endpoint (SOC, mileage...) 30 | - Refresh data by an simple API-Call 31 | - 600 seconds API-Response caching (to prevent 12v battery drain of the vehicle) 32 | 33 | What is not possible at the moment: 34 | 35 | - Send commands (pre-heat vehicle, set car-alarm...) 36 | - Get extended vehicleData (GPS position, door status, tire pressure...) 37 | 38 | How it is done: 39 | Based on the work of [SAIC API Documentation](https://github.com/ReverseEngineeringDE/SAIC-API-Documentation) I wrote a simple API-wrapper to get access to the JSON output of the Java-Application (because I am unable to translate the code to Python - help needed!). 40 | 41 | This .jar is then packaged into a Docker container (very inefficient - I know!) and will be run by Home Assistant. You then can access the API response in Home Assistant via the [RESTful integration](https://www.home-assistant.io/integrations/rest/). 42 | 43 | ### Architecture 44 | 1. Java-Application (this add-on): 45 | - runs in a Docker container 46 | - connects to the SAIC API 47 | - provides the "getData" POST endpoint on port :42042 48 | 49 | 2. Home Assistant (you have to configure it, see below): 50 | - Reads the endpoint with the RESTful integration 51 | - parses the JSON output to sensors/entities 52 | 53 | ## Home Assistant Sensor/Entity 54 | 55 | **Warning: Don't access/refresh the API regularly. It will drain your 12v car battery and you will be unable to start it! I implemented a 600s API refresh cooldown cache but be careful with your automations. This will be improved in future versions.** 56 | 57 | **On every Home Assistant restart the RESTful service will call the API at least once!** 58 | 59 | I solved the 12v drain issue with a very high scan_interval and a "update"-button in my Home Assistant interface (see screenshot and configuration below). In the future this will be improved. 60 | 61 | ### configurations.yaml 62 | 63 | Add this to your Home Assistant configurations.yaml and enter you user and password in the params section (you can also use [Home Assistant Secrets](https://www.home-assistant.io/docs/configuration/secrets/)). 64 | 65 | The full JSON output contains even more information than I needed. Take a look at the example JSON output to understand which "value_json." you can add to your configurations.yaml. 66 | 67 | The high scan_interval will tell Home Assistant to not update this entity automatically (will drain the 12v battery). If you want to update the values with an automation or an interface button you have to call the "homeassistant.update_entity" service (see example below). 68 | 69 | ``` 70 | rest: 71 | - resource: http://localhost:42042/getData 72 | method: POST 73 | scan_interval: 360000 74 | timeout: 30 75 | params: 76 | user: "yourIsmartAccountEmailHere" 77 | password: "yourIsmartAccountPasswordHere" 78 | sensor: 79 | - name: "MG5_bmsPackSOCDsp" 80 | value_template: "{{(value_json.applicationData.bmsPackSOCDsp / 10 )}}" 81 | unit_of_measurement: "%" 82 | - name: "MG5_bmsEstdElecRng" 83 | value_template: "{{(value_json.applicationData.bmsEstdElecRng )}}" 84 | unit_of_measurement: "km" 85 | - name: "MG5_mileage" 86 | value_template: "{{(value_json.applicationData.chargeStatus.mileage / 10 )}}" 87 | unit_of_measurement: "km" 88 | - name: "MG5_eventCreationTime" 89 | value_template: "{{ as_datetime(value_json.body.eventCreationTime)}}" 90 | - name: "MG5_lastCharge_endTime" 91 | value_template: "{{ as_datetime(value_json.applicationData.chargeStatus.endTime)}}" 92 | - name: "MG5_mileageOfDay" 93 | value_template: "{{(value_json.applicationData.chargeStatus.mileageOfDay / 10 )}}" 94 | unit_of_measurement: "km" 95 | - name: "MG5_mileageSinceLastCharge" 96 | value_template: "{{(value_json.applicationData.chargeStatus.mileageSinceLastCharge / 10 )}}" 97 | unit_of_measurement: "km" 98 | - name: "MG5_realtimePower" 99 | value_template: "{{(value_json.applicationData.chargeStatus.realtimePower / 10 )}}" 100 | unit_of_measurement: "kWh" 101 | - name: "MG5_powerUsageSinceLastCharge" 102 | value_template: "{{(value_json.applicationData.chargeStatus.powerUsageSinceLastCharge / 10 )}}" 103 | unit_of_measurement: "kWh" 104 | - name: "MG5_totalBatteryCapacity" 105 | value_template: "{{(value_json.applicationData.chargeStatus.totalBatteryCapacity / 10 )}}" 106 | unit_of_measurement: "kWh" 107 | - name: "MG5_lastChargeEndingPower" 108 | value_template: "{{(value_json.applicationData.chargeStatus.lastChargeEndingPower / 10 )}}" 109 | unit_of_measurement: "kWh" 110 | ``` 111 | 112 | Restart Home Assistant if your created entities do not show up. Every API Gateway request is logged like the following (You can access it via the Add-on protocol): 113 | 114 | ``` 115 | SAIC-API Gateway running! Access the API endpoints via http://localhost:42042/ 116 | Accessed: /getData 117 | Cooldown of 600 seconds is over and API request will be sent. 118 | Sending login request... 119 | Sending initial chargingStatusRequestMessage to wake the car... 120 | Waiting for 6 seconds until the car woke up and responded to our request. 121 | Waiting for 6 seconds until the car woke up and responded to our request. 122 | We got a response. 123 | ``` 124 | 125 | #### Skip cooldown 126 | If you want to skip the 600s cooldown/cache add "skipCooldown" as parameter to your POST request (not recommended). 127 | 128 | ``` 129 | params: 130 | user: "yourIsmartAccountEmailHere" 131 | password: "yourIsmartAccountPasswordHere" 132 | skipCooldown: true 133 | ``` 134 | 135 | ### Home Assistant example card (german translation) 136 | 137 | Add a new element on your interface and click the "Show code-editor" button. Paste the following code to get the output of your RESTful integration configured above. The data will be displayed after your first successful call (which happens on a Home Assistant restart or with a homeassistant.update_entity service call). 138 | 139 | ``` 140 | type: entities 141 | entities: 142 | - entity: sensor.mg5_eventcreationtime 143 | name: Abfragezeitpunkt 144 | icon: mdi:calendar-clock 145 | - entity: sensor.mg5_bmspacksocdsp 146 | icon: mdi:battery 147 | name: Ladezustand (SOC) 148 | - entity: sensor.mg5_realtimepower 149 | name: Ladezustand (SOC kWh) 150 | icon: mdi:battery 151 | - entity: sensor.mg5_bmsestdelecrng 152 | name: Hochgerechnete Gesamtreichweite 153 | icon: mdi:calculator 154 | - entity: sensor.mg5_mileage 155 | icon: mdi:highway 156 | name: Gesamtkilometer 157 | - entity: sensor.mg5_mileageofday 158 | name: Tageskilometer 159 | icon: mdi:highway 160 | - entity: sensor.mg5_lastcharge_endtime 161 | icon: mdi:calendar-clock 162 | name: Letzte Ladung am 163 | - entity: sensor.mg5_mileagesincelastcharge 164 | name: Kilometer seit letzter Ladung 165 | icon: mdi:highway 166 | - entity: sensor.mg5_powerusagesincelastcharge 167 | icon: mdi:lightning-bolt 168 | name: Verbrauch seit letzter Ladung 169 | - entity: sensor.mg5_lastchargeendingpower 170 | name: Akkufüllstand nach letzter Ladung 171 | icon: mdi:battery 172 | - entity: sensor.mg5_totalbatterycapacity 173 | name: Akkukapazität 174 | icon: mdi:battery 175 | ``` 176 | 177 | ### JSON Result example response 178 | If your login was successful the /getData endpoint will respond with following JSON: 179 | [JSON example response](./docs/exampleResponse.json) 180 | 181 | 182 | ### Home Assistant refresh button 183 | The refresh button will call the "homeassistant.update_entity" service. You just have to name one entity of the RESTful integration. This will start a POST request to the API Gateway container running under port 42042. The output of all values will be automatically parsed by Home Assistant. In my tests a refresh takes about 10s-16s. 184 | 185 | ``` 186 | show_name: true 187 | show_icon: true 188 | type: button 189 | tap_action: 190 | action: call-service 191 | service: homeassistant.update_entity 192 | data: {} 193 | target: 194 | entity_id: 195 | - sensor.mg5_bmsestdelecrng 196 | entity: '' 197 | hold_action: 198 | action: none 199 | name: Refresh MG5 Data 200 | show_state: true 201 | icon: mdi:cloud-refresh 202 | ``` 203 | 204 | ### Home Assistant refresh automatization 205 | 206 | If you want to update the data based on a trigger (e.g. your wallbox starts to charge and you only want to charge to a specific percentage) just use a Home Assistant Automation and select "Call Service" and "Update entity" as action. Then select **only one** entity which is listed under the RESTful integration. 207 | 208 | ## Security 209 | 210 | This is a work in progress (WIP) and alpha version. **Please do not** open the Docker port :42042 to the public and only use it internal for Home Assistant. 211 | 212 | ### Built .jar by yourself 213 | If you want to take a look through the code you can simply switch to [saic-java-api-gateway](https://github.com/ReverseEngineeringDE/SAIC-API-Documentation/tree/main/saic-java-api-gateway) and build the .jar by yourself. This newly built .jar can then replaced by the precompiled .jar. 214 | 215 | ## Run the .jar standalone 216 | If you do not want to run the API Gateway on your Home Assistant instance or in a Docker container just run the .jar file like "java -jar .\ismart-api-1.0-SNAPSHOT-full.jar" (on windows). It will provide the API endpoint under the IP:42042. 217 | 218 | 219 | ## Issues & Feedback 220 | 221 | Feel free to open issues to give us some feedback! 222 | 223 | ## License 224 | 225 | Distributed under the MIT License. See [LICENSE.txt](/LICENSE.txt) for more information. 226 | 227 | The usage of the MG iSmart System is covered by their [EULA](https://www.mgmotor.eu/ismart-eula). 228 | 229 | Section 6 (Version: 10.2021) states: 230 | 231 | > RESTRICTIONS: You are prohibited from renting, lending, public presentation, performance or broadcasting or any other kind of distribution of the Services. You will not, and you will not allow any person to, copy or modify the Services or any part thereof or to reverse engineer, decompile or disassemble the Services except as indispensable to install the App on your end device and to obtain the information necessary to establish the interoperability with an independently created computer programme. You may not use the Services in connection with any illegal, fraudulent, dishonest, unethical activity or behaviour and/or use the Services to store or transmit malicious code, interfere with the integrity or performance of the Services or attempt to gain unauthorised access to the Services and/or any systems or networks connected thereto. You shall keep your login credentials unavailable to others, except vis-a-vis your representatives which use the Services on behalf of you as Represented Party. 232 | 233 | This project aims to *obtain the information necessary to establish the interoperability with an independently created computer programme* and is therefore allowed under the terms of the EULA. 234 | 235 |

(back to top)

236 | 237 | [aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg 238 | [amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg 239 | [armhf-shield]: https://img.shields.io/badge/armhf-yes-green.svg 240 | [armv7-shield]: https://img.shields.io/badge/armv7-yes-green.svg 241 | [i386-shield]: https://img.shields.io/badge/i386-yes-green.svg 242 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MG iSmart/iSmart lite (SAIC API) API-Gateway for Home Assistant 2 | 3 | This repository allows Home Assistant users to access the data of their MG5 electric (2022) car (https://www.mgmotor.de/model/mg5) via the iSmart/iSmart lite API (other models with iSmart might also work). 4 | 5 | Main project can be found here (help needed): 6 | [SAIC API Documentation](https://github.com/ReverseEngineeringDE/SAIC-API-Documentation) 7 | 8 | Used .jar file based on: [saic-java-api-gateway](https://github.com/ReverseEngineeringDE/SAIC-API-Documentation/tree/main/saic-java-api-gateway) 9 | 10 | 11 | **Warning: Don't access/refresh the API regularly.** It will drain your 12v car battery and you will be unable to start it! I implemented a 600s API refresh cooldown cache but be careful with your automations. This will be improved in future versions. 12 | 13 | This is a work in progress (WIP). 14 | 15 | ![Supports aarch64 Architecture][aarch64-shield] 16 | ![Supports amd64 Architecture][amd64-shield] 17 | ![Supports armhf Architecture][armhf-shield] 18 | ![Supports armv7 Architecture][armv7-shield] 19 | 20 | 21 | ## Overview 22 | 23 | 24 | ![Home Assistant Screenshot SAIC API](./docs/HA-Addon.jpg) 25 | 26 | 27 | What is possible at the moment: 28 | 29 | - Login & Read vehicle charging status endpoint (SOC, mileage...) 30 | - Refresh data by an simple API-Call 31 | - 600 seconds API-Response caching (to prevent 12v battery drain of the vehicle) 32 | 33 | What is not possible at the moment: 34 | 35 | - Send commands (pre-heat vehicle, set car-alarm...) 36 | - Get extended vehicleData (GPS position, door status, tire pressure...) 37 | 38 | How it is done: 39 | Based on the work of [SAIC API Documentation](https://github.com/ReverseEngineeringDE/SAIC-API-Documentation) I wrote a simple API-wrapper to get access to the JSON output of the Java-Application (because I am unable to translate the code to Python - help needed!). 40 | 41 | This .jar is then packaged into a Docker container (very inefficient - I know!) and will be run by Home Assistant. You then can access the API response in Home Assistant via the [RESTful integration](https://www.home-assistant.io/integrations/rest/). 42 | 43 | ### Architecture 44 | 1. Java-Application (this add-on): 45 | - runs in a Docker container 46 | - connects to the SAIC API 47 | - provides the "getData" POST endpoint on port :42042 48 | 49 | 2. Home Assistant (you have to configure it, see below): 50 | - Reads the endpoint with the RESTful integration 51 | - parses the JSON output to sensors/entities 52 | 53 | ## Installation 54 | 55 | **NOTE: This Add-on is tagged as experimental. Please enable advanced mode your home assistant instance!** 56 | 57 | 1. Copy the Github-URL 58 | 2. Go to: Settings -> Add-ons -> ADD_ON STORE -> 3-dot-menu -> Repositorys -> Add the Github URL 59 | 3. Reload the Page and choose SAIC API Gateway 60 | 4. Install and enjoy! 61 | 62 | ## Manual Installation 63 | 64 | **NOTE: In the future this will be simplified by creating a native Home Assistant Add-on repository** 65 | 66 | 1. Download the latest release or clone the repository 67 | 2. Extract the folder and put it in a subfolder in your Home Assistant Add-ons folder /addons/saic. This can be done via FTP access or the add-on "Filebrowser" (search for "Filebrowser" under Settings-->Add-ons-->Filebrowser). 68 | 3. In the Dockerfile uncomment the right CPU architecture (default Raspberry Pi --> arm64v8) 69 | 4. Open Settings --> Add-ons --> Button: Add-on Store --> Dot-Menu right top --> "Check for updates" to tell Home Assistant to search for the newly added Add-on 70 | 5. Install the add-on (takes up to 5-15 min on a Raspberry Pi) and start it 71 | 6. Docker-Container should be running - confirm that by going to the add-on page (SAIC Gateway) and click on the "Protocol" tab 72 | 7. Protocol tab should output "SAIC-API Gateway running! Access the API endpoints via http://localhost:42042/" 73 | 74 | ## Home Assistant Sensor/Entity 75 | 76 | **Warning: Don't access/refresh the API regularly. It will drain your 12v car battery and you will be unable to start it! I implemented a 600s API refresh cooldown cache but be careful with your automations. This will be improved in future versions.** 77 | 78 | **On every Home Assistant restart the RESTful service will call the API at least once!** 79 | 80 | I solved the 12v drain issue with a very high scan_interval and a "update"-button in my Home Assistant interface (see screenshot and configuration below). In the future this will be improved. 81 | 82 | ### configurations.yaml 83 | 84 | Add this to your Home Assistant configurations.yaml and enter you user and password in the params section (you can also use [Home Assistant Secrets](https://www.home-assistant.io/docs/configuration/secrets/)). 85 | 86 | The full JSON output contains even more information than I needed. Take a look at the example JSON output to understand which "value_json." you can add to your configurations.yaml. 87 | 88 | The high scan_interval will tell Home Assistant to not update this entity automatically (will drain the 12v battery). If you want to update the values with an automation or an interface button you have to call the "homeassistant.update_entity" service (see example below). 89 | 90 | ``` 91 | rest: 92 | - resource: http://localhost:42042/getData 93 | method: POST 94 | scan_interval: 360000 95 | timeout: 30 96 | params: 97 | user: "yourIsmartAccountEmailHere" 98 | password: "yourIsmartAccountPasswordHere" 99 | sensor: 100 | - name: "MG5_bmsPackSOCDsp" 101 | value_template: "{{(value_json.applicationData.bmsPackSOCDsp / 10 )}}" 102 | unit_of_measurement: "%" 103 | - name: "MG5_bmsEstdElecRng" 104 | value_template: "{{(value_json.applicationData.bmsEstdElecRng )}}" 105 | unit_of_measurement: "km" 106 | - name: "MG5_mileage" 107 | value_template: "{{(value_json.applicationData.chargeStatus.mileage / 10 )}}" 108 | unit_of_measurement: "km" 109 | - name: "MG5_eventCreationTime" 110 | value_template: "{{ as_datetime(value_json.body.eventCreationTime)}}" 111 | - name: "MG5_lastCharge_endTime" 112 | value_template: "{{ as_datetime(value_json.applicationData.chargeStatus.endTime)}}" 113 | - name: "MG5_mileageOfDay" 114 | value_template: "{{(value_json.applicationData.chargeStatus.mileageOfDay / 10 )}}" 115 | unit_of_measurement: "km" 116 | - name: "MG5_mileageSinceLastCharge" 117 | value_template: "{{(value_json.applicationData.chargeStatus.mileageSinceLastCharge / 10 )}}" 118 | unit_of_measurement: "km" 119 | - name: "MG5_realtimePower" 120 | value_template: "{{(value_json.applicationData.chargeStatus.realtimePower / 10 )}}" 121 | unit_of_measurement: "kWh" 122 | - name: "MG5_powerUsageSinceLastCharge" 123 | value_template: "{{(value_json.applicationData.chargeStatus.powerUsageSinceLastCharge / 10 )}}" 124 | unit_of_measurement: "kWh" 125 | - name: "MG5_totalBatteryCapacity" 126 | value_template: "{{(value_json.applicationData.chargeStatus.totalBatteryCapacity / 10 )}}" 127 | unit_of_measurement: "kWh" 128 | - name: "MG5_lastChargeEndingPower" 129 | value_template: "{{(value_json.applicationData.chargeStatus.lastChargeEndingPower / 10 )}}" 130 | unit_of_measurement: "kWh" 131 | ``` 132 | 133 | Restart Home Assistant if your created entities do not show up. Every API Gateway request is logged like the following (You can access it via the Add-on protocol): 134 | 135 | ``` 136 | SAIC-API Gateway running! Access the API endpoints via http://localhost:42042/ 137 | Accessed: /getData 138 | Cooldown of 600 seconds is over and API request will be sent. 139 | Sending login request... 140 | Sending initial chargingStatusRequestMessage to wake the car... 141 | Waiting for 6 seconds until the car woke up and responded to our request. 142 | Waiting for 6 seconds until the car woke up and responded to our request. 143 | We got a response. 144 | ``` 145 | 146 | #### Skip cooldown 147 | If you want to skip the 600s cooldown/cache add "skipCooldown" as parameter to your POST request (not recommended). 148 | 149 | ``` 150 | params: 151 | user: "yourIsmartAccountEmailHere" 152 | password: "yourIsmartAccountPasswordHere" 153 | skipCooldown: true 154 | ``` 155 | 156 | ### Home Assistant example card (german translation) 157 | 158 | Add a new element on your interface and click the "Show code-editor" button. Paste the following code to get the output of your RESTful integration configured above. The data will be displayed after your first successful call (which happens on a Home Assistant restart or with a homeassistant.update_entity service call). 159 | 160 | ``` 161 | type: entities 162 | entities: 163 | - entity: sensor.mg5_eventcreationtime 164 | name: Abfragezeitpunkt 165 | icon: mdi:calendar-clock 166 | - entity: sensor.mg5_bmspacksocdsp 167 | icon: mdi:battery 168 | name: Ladezustand (SOC) 169 | - entity: sensor.mg5_realtimepower 170 | name: Ladezustand (SOC kWh) 171 | icon: mdi:battery 172 | - entity: sensor.mg5_bmsestdelecrng 173 | name: Hochgerechnete Gesamtreichweite 174 | icon: mdi:calculator 175 | - entity: sensor.mg5_mileage 176 | icon: mdi:highway 177 | name: Gesamtkilometer 178 | - entity: sensor.mg5_mileageofday 179 | name: Tageskilometer 180 | icon: mdi:highway 181 | - entity: sensor.mg5_lastcharge_endtime 182 | icon: mdi:calendar-clock 183 | name: Letzte Ladung am 184 | - entity: sensor.mg5_mileagesincelastcharge 185 | name: Kilometer seit letzter Ladung 186 | icon: mdi:highway 187 | - entity: sensor.mg5_powerusagesincelastcharge 188 | icon: mdi:lightning-bolt 189 | name: Verbrauch seit letzter Ladung 190 | - entity: sensor.mg5_lastchargeendingpower 191 | name: Akkufüllstand nach letzter Ladung 192 | icon: mdi:battery 193 | - entity: sensor.mg5_totalbatterycapacity 194 | name: Akkukapazität 195 | icon: mdi:battery 196 | ``` 197 | 198 | ### JSON Result example response 199 | If your login was successful the /getData endpoint will respond with following JSON: 200 | [JSON example response](./docs/exampleResponse.json) 201 | 202 | 203 | ### Home Assistant refresh button 204 | The refresh button will call the "homeassistant.update_entity" service. You just have to name one entity of the RESTful integration. This will start a POST request to the API Gateway container running under port 42042. The output of all values will be automatically parsed by Home Assistant. In my tests a refresh takes about 10s-16s. 205 | 206 | ``` 207 | show_name: true 208 | show_icon: true 209 | type: button 210 | tap_action: 211 | action: call-service 212 | service: homeassistant.update_entity 213 | data: {} 214 | target: 215 | entity_id: 216 | - sensor.mg5_bmsestdelecrng 217 | entity: '' 218 | hold_action: 219 | action: none 220 | name: Refresh MG5 Data 221 | show_state: true 222 | icon: mdi:cloud-refresh 223 | ``` 224 | 225 | ### Home Assistant refresh automatization 226 | 227 | If you want to update the data based on a trigger (e.g. your wallbox starts to charge and you only want to charge to a specific percentage) just use a Home Assistant Automation and select "Call Service" and "Update entity" as action. Then select **only one** entity which is listed under the RESTful integration. 228 | 229 | ## Security 230 | 231 | This is a work in progress (WIP) and alpha version. **Please do not** open the Docker port :42042 to the public and only use it internal for Home Assistant. 232 | 233 | ### Built .jar by yourself 234 | If you want to take a look through the code you can simply switch to [saic-java-api-gateway](https://github.com/ReverseEngineeringDE/SAIC-API-Documentation/tree/main/saic-java-api-gateway) and build the .jar by yourself. This newly built .jar can then replaced by the precompiled .jar. 235 | 236 | ## Run the .jar standalone 237 | If you do not want to run the API Gateway on your Home Assistant instance or in a Docker container just run the .jar file like "java -jar .\ismart-api-1.0-SNAPSHOT-full.jar" (on windows). It will provide the API endpoint under the IP:42042. 238 | 239 | 240 | ## Issues & Feedback 241 | 242 | Feel free to open issues to give us some feedback! 243 | 244 | ## License 245 | 246 | Distributed under the MIT License. See [LICENSE.txt](/LICENSE.txt) for more information. 247 | 248 | The usage of the MG iSmart System is covered by their [EULA](https://www.mgmotor.eu/ismart-eula). 249 | 250 | Section 6 (Version: 10.2021) states: 251 | 252 | > RESTRICTIONS: You are prohibited from renting, lending, public presentation, performance or broadcasting or any other kind of distribution of the Services. You will not, and you will not allow any person to, copy or modify the Services or any part thereof or to reverse engineer, decompile or disassemble the Services except as indispensable to install the App on your end device and to obtain the information necessary to establish the interoperability with an independently created computer programme. You may not use the Services in connection with any illegal, fraudulent, dishonest, unethical activity or behaviour and/or use the Services to store or transmit malicious code, interfere with the integrity or performance of the Services or attempt to gain unauthorised access to the Services and/or any systems or networks connected thereto. You shall keep your login credentials unavailable to others, except vis-a-vis your representatives which use the Services on behalf of you as Represented Party. 253 | 254 | This project aims to *obtain the information necessary to establish the interoperability with an independently created computer programme* and is therefore allowed under the terms of the EULA. 255 | 256 |

(back to top)

257 | 258 | [aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg 259 | [amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg 260 | [armhf-shield]: https://img.shields.io/badge/armhf-yes-green.svg 261 | [armv7-shield]: https://img.shields.io/badge/armv7-yes-green.svg 262 | [i386-shield]: https://img.shields.io/badge/i386-yes-green.svg 263 | --------------------------------------------------------------------------------