From 26f2bf3243f50fcfa915fab14269058c36332d8a Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Tue, 26 Apr 2022 23:29:58 +0200 Subject: [PATCH] New Plugin: Bimmerconnect --- .gitignore | 2 + bimmerconnected/README.md | 20 ++ bimmerconnected/bimmerconnected.pro | 5 + bimmerconnected/bmw.svg | 86 +++++++++ .../integrationpluginbimmerconnected.json | 129 +++++++++++++ .../integrationpluginbimmerconnected.py | 180 ++++++++++++++++++ bimmerconnected/meta.json | 13 ++ bimmerconnected/requirements.txt | 171 +++++++++++++++++ debian/control | 9 + .../nymea-plugin-bimmerconnected.install.in | 3 + neatobotvac/integrationpluginneatobotvac.py | 4 +- nymea-plugins.pro | 1 + 12 files changed, 620 insertions(+), 3 deletions(-) create mode 100644 bimmerconnected/README.md create mode 100644 bimmerconnected/bimmerconnected.pro create mode 100644 bimmerconnected/bmw.svg create mode 100644 bimmerconnected/integrationpluginbimmerconnected.json create mode 100644 bimmerconnected/integrationpluginbimmerconnected.py create mode 100644 bimmerconnected/meta.json create mode 100644 bimmerconnected/requirements.txt create mode 100644 debian/nymea-plugin-bimmerconnected.install.in diff --git a/.gitignore b/.gitignore index d325ab97..54e39caf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ builddir doc/html .DS_Store +*/modules/ +*__pycache__* diff --git a/bimmerconnected/README.md b/bimmerconnected/README.md new file mode 100644 index 00000000..16ac5162 --- /dev/null +++ b/bimmerconnected/README.md @@ -0,0 +1,20 @@ +# Bimmer connected + +This plugin allows to set up BMW cars with the BMW connect feature to nymea. +It is based on the bimmer_connected community project at +https://github.com/bimmerconnected/bimmer_connected + +It connects to the BMW connect cloud using the login from the BMW connect app. + +## Supported things + +All BMW cars supporting the BMW Connect app should be working. + +## Requirements + +* The car needs to support BMW connect +* The car needs to be connected to the BMW connect cloud using the official app. + +## More + +This plugin is not affiliated with or endorsed by BMW in any way. diff --git a/bimmerconnected/bimmerconnected.pro b/bimmerconnected/bimmerconnected.pro new file mode 100644 index 00000000..90f4542d --- /dev/null +++ b/bimmerconnected/bimmerconnected.pro @@ -0,0 +1,5 @@ +TEMPLATE = aux + +OTHER_FILES = integrationpluginbimmerconnected.json \ + integrationpluginbimmerconnected.py + diff --git a/bimmerconnected/bmw.svg b/bimmerconnected/bmw.svg new file mode 100644 index 00000000..77f8b261 --- /dev/null +++ b/bimmerconnected/bmw.svg @@ -0,0 +1,86 @@ + + + + + + image/svg+xml + + + + + + + + Created with Sketch. + + + + diff --git a/bimmerconnected/integrationpluginbimmerconnected.json b/bimmerconnected/integrationpluginbimmerconnected.json new file mode 100644 index 00000000..a8e4c873 --- /dev/null +++ b/bimmerconnected/integrationpluginbimmerconnected.json @@ -0,0 +1,129 @@ +{ + "name": "bimmerconnected", + "displayName": "Bimmer Connected", + "id": "d65df364-575c-40eb-9d02-0b5f194b6c03", + "vendors": [ + { + "name": "bmw", + "displayName": "BMW", + "id": "564d4beb-f760-41dd-80fa-bd91258aeaa3", + "thingClasses": [ + { + "id": "c90b36b2-2de4-4638-b60e-ef929d2738d6", + "name": "account", + "displayName": "BMW account", + "createMethods": [ + "User" + ], + "interfaces": [ + "account" + ], + "setupMethod": "userandpassword", + "paramTypes": [ + { + "id": "863913c1-a835-4789-b06c-aa0819571395", + "name": "region", + "displayName": "Region", + "type": "QString", + "defaultValue": "Rest of world", + "allowedValues": ["Rest of world", "North America", "China"] + } + ], + "stateTypes": [ + { + "id": "e8f47781-e3fd-416f-a9ac-51ef942d0573", + "name": "connected", + "displayName": "Connected", + "displayNameEvent": "Connected/disconnected", + "type": "bool", + "defaultValue": false, + "cached": false + }, + { + "id": "d3abc53e-8590-4e72-af5f-f7a27cb441e7", + "name": "loggedIn", + "displayName": "Logged in", + "displayNameEvent": "Logged in or out", + "type": "bool", + "defaultValue": false + } + ], + "actionTypes": [] + }, + { + "id": "b7230349-97ff-4768-b929-40ab44b328b4", + "name": "vehicle", + "displayName": "Bimmer", + "createMethods": [ + "auto" + ], + "interfaces": [ + "electricvehicle" + ], + "browsable": true, + "paramTypes": [ + { + "id": "ea198b04-0576-4ecb-9933-9f8ec640b16a", + "name": "vin", + "displayName": "VIN", + "type": "QString" + } + ], + "stateTypes": [ + { + "id": "79a8f4cb-a359-4c78-8d0f-c4ef70fc0db8", + "name": "capacity", + "displayName": "Capacity", + "displayNameEvent": "Capacity changed", + "displayNameAction": "Set capacity", + "type": "double", + "unit": "KiloWattHour", + "defaultValue": 50, + "writable": true + }, + { + "id": "b70b2a73-4304-46ba-85ce-4ecdc68f241f", + "name": "batteryLevel", + "displayName": "Battery level", + "displayNameEvent": "Battery level changed", + "type": "int", + "minValue": 0, + "maxValue": 100, + "unit": "Percentage", + "defaultValue": "50" + }, + { + "id": "95c48726-cd0c-4301-8298-1ac2c41e13db", + "name": "batteryCritical", + "displayName": "Battery critical", + "displayNameEvent": "Battery critical changed", + "type": "bool", + "defaultValue": false + }, + { + "id": "8a4f89f3-fdb1-4b7b-8d17-1ff813e3800c", + "name": "pluggedIn", + "displayName": "Plugged in", + "displayNameEvent": "Plugged/unplugged", + "type": "bool", + "defaultValue": false + }, + { + "id": "fa05b774-13f1-432f-a8c5-5ffc18bafc6d", + "name": "chargingState", + "displayName": "Charging state", + "displayNameEvent": "Charging state", + "type": "QString", + "possibleValues": [ + "idle", + "charging", + "discharging" + ], + "defaultValue": "idle" + } + ] + } + ] + } + ] +} diff --git a/bimmerconnected/integrationpluginbimmerconnected.py b/bimmerconnected/integrationpluginbimmerconnected.py new file mode 100644 index 00000000..a54d3603 --- /dev/null +++ b/bimmerconnected/integrationpluginbimmerconnected.py @@ -0,0 +1,180 @@ +import nymea +from bimmer_connected.account import ConnectedDriveAccount +from bimmer_connected.country_selector import Regions +from bimmer_connected.vehicle_status import ChargingState + +accountsMap = {} +pollTimer = None + +regions = { + "Rest of world": Regions.REST_OF_WORLD, + "North America": Regions.NORTH_AMERICA, + "China": Regions.CHINA, +} + + +def findByParam(cls, param, value): + for thing in myThings(): + if thing.thingClassId == cls and thing.paramValue(param) == value: + return thing + + +def init(): + logger.log("Initializing Bimmerconnected plugin") + + +def startPairing(info): + info.finish(nymea.ThingErrorNoError) + + +def confirmPairing(info, username, secret): + try: + region = regions[info.paramValue(accountThingRegionParamTypeId)] + account = ConnectedDriveAccount(username, secret, region) + account.update_vehicle_states() + info.finish(nymea.ThingErrorNoError) + pluginStorage().beginGroup(info.thingId) + pluginStorage().setValue("username", username) + pluginStorage().setValue("password", secret) + pluginStorage().endGroup() + del account + + except Exception as e: + logger.warn(f"Error setting up BMW account: {str(e)}") + info.finish(nymea.ThingErrorAuthenticationFailure) + + +def setupThing(info): + # Setup for the account + if info.thing.thingClassId == accountThingClassId: + logger.log("SetupThing for account:", info.thing.name) + + region = regions[info.thing.paramValue(accountThingRegionParamTypeId)] + pluginStorage().beginGroup(info.thing.id) + username = pluginStorage().value("username") + password = pluginStorage().value("password") + pluginStorage().endGroup() + + try: + account = ConnectedDriveAccount(username, password, region) + account.update_vehicle_states() + + accountsMap[info.thing.id] = account + except Exception as e: + # Login error + logger.warn(f"Error setting up BMW account: {str(e)}") + info.finish(nymea.ThingErrorAuthenticationFailure, str(e)) + return + + # Mark the account as logged-in and connected + info.thing.setStateValue(accountLoggedInStateTypeId, True) + info.thing.setStateValue(accountConnectedStateTypeId, True) + + # Login went well, finish the setup + info.finish(nymea.ThingErrorNoError) + + logger.log( + f"Found {len(account.vehicles)} vehicles: {', '.join([v.name for v in account.vehicles])}" + ) + + thingDescriptors = [] + for vehicle in account.vehicles: + if any( + thing.thingClassId == vehicleThingClassId + and thing.paramValue(vehicleThingVinParamTypeId) == vehicle.vin + for thing in myThings() + ): + continue + + if not vehicle.has_hv_battery: + logger.log( + f"Ignoring combustion vehicle {vehicle.name} ({vehicle.vin[-7:]})" + ) + continue + + logger.log( + f"Adding new vehicle {vehicle.name} ({vehicle.vin[-7:]}) to the system with parent {info.thing.id}" + ) + thingDescriptor = nymea.ThingDescriptor( + vehicleThingClassId, + "BMW {} ({})".format(vehicle.name, vehicle.vin[-7:]), + parentId=info.thing.id, + ) + thingDescriptor.params = [ + nymea.Param(vehicleThingVinParamTypeId, vehicle.vin) + ] + thingDescriptors.append(thingDescriptor) + + autoThingsAppeared(thingDescriptors) + + # If no poll timer is set up yet, start it now + logger.log("Creating polltimer @ setupThing") + global pollTimer + if pollTimer is None: + pollTimer = nymea.PluginTimer(60 * 5, pollService) + logger.log("timer interval @ setupThing", pollTimer.interval) + + # Setup for the vehicles + if info.thing.thingClassId == vehicleThingClassId: + info.finish(nymea.ThingErrorNoError) + + +def postSetupThing(thing): + if thing.thingClassId == accountThingClassId: + pollService() + + +def pollService(): + logger.log("Polling BMW Connect") + for thing in myThings(): + if thing.thingClassId != accountThingClassId: + continue + + account = accountsMap[thing.id] + try: + account.update_vehicle_states() + except: + logger.warn(f"Error refreshing vehicle states for account {thing.name}") + + for vehicle in account.vehicles: + logger.log(f"Updating vehicle with VIN {vehicle.vin}") + + thing = findByParam( + vehicleThingClassId, vehicleThingVinParamTypeId, vehicle.vin + ) + + thing.setStateValue( + vehicleBatteryLevelStateTypeId, + vehicle.status.charging_level_hv, + ) + thing.setStateValue( + vehiclePluggedInStateTypeId, + vehicle.status.connection_status == "CONNECTED", + ) + thing.setStateValue( + vehicleChargingStateStateTypeId, + "charging" + if vehicle.status.charging_status == ChargingState.CHARGING + else "idle", + ) + + +def executeAction(info): + if info.actionTypeId == vehicleCapacityActionTypeId: + info.thing.setStateValue( + vehicleCapacityStateTypeId, + info.paramValue(vehicleCapacityActionCapacityParamTypeId), + ) + info.finish(nymea.ThingErrorNoError) + else: + logger.error(f"Unhandled action: {info.action.id}") + + +def thingRemoved(thing): + global pollTimer + + if thing.thingClassId == accountThingClassId: + del accountsMap[thing.id] + + if len(myThings()) == 0 and pollTimer is not None: + pollTimer = None diff --git a/bimmerconnected/meta.json b/bimmerconnected/meta.json new file mode 100644 index 00000000..82f14b5e --- /dev/null +++ b/bimmerconnected/meta.json @@ -0,0 +1,13 @@ +{ + "title": "Bimmerconnected", + "tagline": "Get BMW vehicle status.", + "icon": "bmw.svg", + "stability": "community", + "offline": false, + "technologies": [ + "network" + ], + "categories": [ + "appliance" + ] +} diff --git a/bimmerconnected/requirements.txt b/bimmerconnected/requirements.txt new file mode 100644 index 00000000..8dfb3f56 --- /dev/null +++ b/bimmerconnected/requirements.txt @@ -0,0 +1,171 @@ +bimmer-connected==0.8.12 \ + --hash=sha256:57f2817a4d4ca125a1b40ed90205515d8e9cf98f18cadd0f8972aedbed2fee51 \ + --hash=sha256:feb05a4cb900db7185f2adeefeb0217f73eb4091b90a6c32db1621bb742cbac0 +pycryptodome==3.14.1 \ + --hash=sha256:028dcbf62d128b4335b61c9fbb7dd8c376594db607ef36d5721ee659719935d5 \ + --hash=sha256:12ef157eb1e01a157ca43eda275fa68f8db0dd2792bc4fe00479ab8f0e6ae075 \ + --hash=sha256:2562de213960693b6d657098505fd4493c45f3429304da67efcbeb61f0edfe89 \ + --hash=sha256:27e92c1293afcb8d2639baf7eb43f4baada86e4de0f1fb22312bfc989b95dae2 \ + --hash=sha256:36e3242c4792e54ed906c53f5d840712793dc68b726ec6baefd8d978c5282d30 \ + --hash=sha256:50a5346af703330944bea503106cd50c9c2212174cfcb9939db4deb5305a8367 \ + --hash=sha256:53dedbd2a6a0b02924718b520a723e88bcf22e37076191eb9b91b79934fb2192 \ + --hash=sha256:69f05aaa90c99ac2f2af72d8d7f185f729721ad7c4be89e9e3d0ab101b0ee875 \ + --hash=sha256:75a3a364fee153e77ed889c957f6f94ec6d234b82e7195b117180dcc9fc16f96 \ + --hash=sha256:766a8e9832128c70012e0c2b263049506cbf334fb21ff7224e2704102b6ef59e \ + --hash=sha256:7fb90a5000cc9c9ff34b4d99f7f039e9c3477700e309ff234eafca7b7471afc0 \ + --hash=sha256:893f32210de74b9f8ac869ed66c97d04e7d351182d6d39ebd3b36d3db8bda65d \ + --hash=sha256:8b5c28058102e2974b9868d72ae5144128485d466ba8739abd674b77971454cc \ + --hash=sha256:924b6aad5386fb54f2645f22658cb0398b1f25bc1e714a6d1522c75d527deaa5 \ + --hash=sha256:9924248d6920b59c260adcae3ee231cd5af404ac706ad30aa4cd87051bf09c50 \ + --hash=sha256:9ec761a35dbac4a99dcbc5cd557e6e57432ddf3e17af8c3c86b44af9da0189c0 \ + --hash=sha256:a36ab51674b014ba03da7f98b675fcb8eabd709a2d8e18219f784aba2db73b72 \ + --hash=sha256:aae395f79fa549fb1f6e3dc85cf277f0351e15a22e6547250056c7f0c990d6a5 \ + --hash=sha256:c880a98376939165b7dc504559f60abe234b99e294523a273847f9e7756f4132 \ + --hash=sha256:ce7a875694cd6ccd8682017a7c06c6483600f151d8916f2b25cf7a439e600263 \ + --hash=sha256:d1b7739b68a032ad14c5e51f7e4e1a5f92f3628bba024a2bda1f30c481fc85d8 \ + --hash=sha256:dcd65355acba9a1d0fc9b923875da35ed50506e339b35436277703d7ace3e222 \ + --hash=sha256:e04e40a7f8c1669195536a37979dd87da2c32dbdc73d6fe35f0077b0c17c803b \ + --hash=sha256:e0c04c41e9ade19fbc0eff6aacea40b831bfcb2c91c266137bcdfd0d7b2f33ba \ + --hash=sha256:e24d4ec4b029611359566c52f31af45c5aecde7ef90bf8f31620fd44c438efe7 \ + --hash=sha256:e64738207a02a83590df35f59d708bf1e7ea0d6adce712a777be2967e5f7043c \ + --hash=sha256:ea56a35fd0d13121417d39a83f291017551fa2c62d6daa6b04af6ece7ed30d84 \ + --hash=sha256:f2772af1c3ef8025c85335f8b828d0193fa1e43256621f613280e2c81bfad423 \ + --hash=sha256:f403a3e297a59d94121cb3ee4b1cf41f844332940a62d71f9e4a009cc3533493 \ + --hash=sha256:f572a3ff7b6029dd9b904d6be4e0ce9e309dcb847b03e3ac8698d9d23bb36525 +requests==2.27.1 \ + --hash=sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61 \ + --hash=sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d +PyJWT==2.3.0 \ + --hash=sha256:b888b4d56f06f6dcd777210c334e69c737be74755d3e5e9ee3fe67dc18a0ee41 \ + --hash=sha256:e0c4bb8d9f0af0c7f5b1ec4c5036309617d03d56932877f2f7a0beeb5318322f +urllib3==1.26.9 \ + --hash=sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14 \ + --hash=sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e +charset-normalizer==2.0.12 \ + --hash=sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597 \ + --hash=sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df +idna==3.3 \ + --hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \ + --hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d +certifi==2021.10.8 \ + --hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872 \ + --hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569 +setuptools==62.1.0 \ + --hash=sha256:26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8 \ + --hash=sha256:47c7b0c0f8fc10eec4cf1e71c6fdadf8decaa74ffa087e68cd1c20db7ad6a592 +launchpadlib==1.10.16 \ + --hash=sha256:0df4b13936f988afd0ee485f40fa6922eab783b48c38ca0108cb73c8788fca80 \ + --hash=sha256:aa43b9bfbd786d0653ddafcf6178578eeb8a6ba19fce0fee885ed832795745b5 +lazr.restfulclient==0.14.4 \ + --hash=sha256:bf0fd6b2749b3a2d02711f854c9d23704756f7afed21fb5d5b9809d72aa6d087 +lazr.uri==1.0.6 \ + --hash=sha256:5026853fcbf6f91d5a6b11ea7860a641fe27b36d4172c731f4aa16b900cf8464 +six==1.16.0 \ + --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ + --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 +keyring==23.5.0 \ + --hash=sha256:9012508e141a80bd1c0b6778d5c610dd9f8c464d75ac6774248500503f972fb9 \ + --hash=sha256:b0d28928ac3ec8e42ef4cc227822647a19f1d544f21f96457965dc01cf555261 +SecretStorage==3.3.2 \ + --hash=sha256:0a8eb9645b320881c222e827c26f4cfcf55363e8b374a021981ef886657a912f \ + --hash=sha256:755dc845b6ad76dcbcbc07ea3da75ae54bb1ea529eb72d15f83d26499a5df319 +jeepney==0.8.0 \ + --hash=sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806 \ + --hash=sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755 +importlib-metadata==4.11.3 \ + --hash=sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6 \ + --hash=sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539 +zipp==3.8.0 \ + --hash=sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad \ + --hash=sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099 +httplib2==0.20.4 \ + --hash=sha256:58a98e45b4b1a48273073f905d2961666ecf0fbac4250ea5b47aef259eb5c585 \ + --hash=sha256:8b6a905cb1c79eefd03f8669fd993c36dc341f7c558f056cb5a33b5c2f458543 +pyparsing==3.0.8 \ + --hash=sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954 \ + --hash=sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06 +distro==1.7.0 \ + --hash=sha256:151aeccf60c216402932b52e40ee477a939f8d58898927378a02abbe852c1c39 \ + --hash=sha256:d596311d707e692c2160c37807f83e3820c5d539d5a83e87cfb6babd8ba3a06b +oauthlib==3.2.0 \ + --hash=sha256:23a8208d75b902797ea29fd31fa80a15ed9dc2c6c16fe73f5d346f83f6fa27a2 \ + --hash=sha256:6db33440354787f9b7f3a6dbd4febf5d0f93758354060e802f6c06cb493022fe +wadllib==1.3.6 \ + --hash=sha256:acd9ad6a2c1007d34ca208e1da6341bbca1804c0e6850f954db04bdd7666c5fc +cryptography==37.0.0 \ + --hash=sha256:0234bdb18620ed16bf186f0591aea0bbc321ecaf59c859d5f5cbe7b646d8377e \ + --hash=sha256:183d6a540659c6a729c08971f09f3fb1044c89dd5af9d6f18da824a071f5445d \ + --hash=sha256:1af4f31870ef2180aba1c04f6d957461a570c8cabcc4b5ac7fabf2b4a0364ea0 \ + --hash=sha256:2d3d8a69d262ba27923466194bef637150aef286b11b160e087992206ac32f0c \ + --hash=sha256:2dfd682771c04c7e85a4b4ea6aa1682a3fd6f4d9845468fa6ba512b80a560a8d \ + --hash=sha256:4c52cb32ea0b9798234823d37c93cab8004c574b2d224f048cd5829d0639387b \ + --hash=sha256:57273f69b334c6d30f4d27abc7fb9c919ef4c6193af64420572808302bb45768 \ + --hash=sha256:5a761fc1ff0eae360a80656bea462c3163dfaa8093b2fa0f72af929217b14a97 \ + --hash=sha256:5c2517a2c58213ee62b36ee9ece4a710179ddb07db90e31d7619e7ea472c9dc3 \ + --hash=sha256:710b9041fb97cc576e288b5f96583578ed352dd60608a402045405c388522b94 \ + --hash=sha256:8921428ca6403d7eb52ee0e728e8b02601060a5791f6d64c8a3a12b5722064af \ + --hash=sha256:bc54780dd8f7236874ac29fc155c5cf811f7d910e5f0575932a38bdaac3b5146 \ + --hash=sha256:bf893131cd79dc8eaf4940b3aa2f4a68eba050471f5deacfaedea6aab04f574f \ + --hash=sha256:cab59c774125596fa72f1decc5805894313b40f370a7c75597e37f0211027944 \ + --hash=sha256:d119feb387ce2df9bfb92e5785df9094325cfa974e2e6aa08c8e4a8b56786afe \ + --hash=sha256:d426093df7f00de859bad45d6a09fdab9b8e4c6e46ea897dd0a302b94c7f6871 \ + --hash=sha256:d886b2c9f8d1ab0916673bc3c89dd04fc6e6591861872c9f08402b0ab2843b82 \ + --hash=sha256:d97479d943d549d4a78f044b0620a7d349191ed40933ffabff1cc5875e20682c \ + --hash=sha256:db1b9516e3072e0342287e06779bec84118bd780f794c8c07bd5da142a526103 \ + --hash=sha256:e86734f28656f6fd5993ab32bd2d2680c3b8341d6f875faf5212bc78715db2a4 \ + --hash=sha256:ebdc9c4b3577bb76b0defebe4ef8b866da5228a1c53fbbf394b7677fe292fee9 \ + --hash=sha256:eee79c6c16949ed817c8cf288e6e124c4b8996e3312d9e7884c71cf9bdda212e +cffi==1.15.0 \ + --hash=sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3 \ + --hash=sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2 \ + --hash=sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636 \ + --hash=sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20 \ + --hash=sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728 \ + --hash=sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27 \ + --hash=sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66 \ + --hash=sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443 \ + --hash=sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0 \ + --hash=sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7 \ + --hash=sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39 \ + --hash=sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605 \ + --hash=sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a \ + --hash=sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37 \ + --hash=sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029 \ + --hash=sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139 \ + --hash=sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc \ + --hash=sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df \ + --hash=sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14 \ + --hash=sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880 \ + --hash=sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2 \ + --hash=sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a \ + --hash=sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e \ + --hash=sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474 \ + --hash=sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024 \ + --hash=sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8 \ + --hash=sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0 \ + --hash=sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e \ + --hash=sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a \ + --hash=sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e \ + --hash=sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032 \ + --hash=sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6 \ + --hash=sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e \ + --hash=sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b \ + --hash=sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e \ + --hash=sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954 \ + --hash=sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962 \ + --hash=sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c \ + --hash=sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4 \ + --hash=sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55 \ + --hash=sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962 \ + --hash=sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023 \ + --hash=sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c \ + --hash=sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6 \ + --hash=sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8 \ + --hash=sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382 \ + --hash=sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7 \ + --hash=sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc \ + --hash=sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997 \ + --hash=sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796 +pycparser==2.21 \ + --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ + --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206 diff --git a/debian/control b/debian/control index f63e1acf..07d2fafc 100644 --- a/debian/control +++ b/debian/control @@ -61,6 +61,15 @@ Description: nymea integration plugin for awattar This package contains the nymea integration plugin for the awattar online service +Package: nymea-plugin-bimmerconnected +Architecture: any +Depends: ${shlibs:Depends}, + ${misc:Depends}, +Description: nymea integration plugin for bimmerconnected + This package contains a nymea integration plugin for BMW cars with + BMW Connect via the bimmerconnected community project. + + Package: nymea-plugin-bluos Architecture: any Depends: ${shlibs:Depends}, diff --git a/debian/nymea-plugin-bimmerconnected.install.in b/debian/nymea-plugin-bimmerconnected.install.in new file mode 100644 index 00000000..7785c00d --- /dev/null +++ b/debian/nymea-plugin-bimmerconnected.install.in @@ -0,0 +1,3 @@ +bimmerconnected/integrationpluginbimmerconnected.json usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/bimmerconnected/ +bimmerconnected/integrationpluginbimmerconnected.py usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/bimmerconnected/ +bimmerconnected/requirements.txt usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/bimmerconnected/ diff --git a/neatobotvac/integrationpluginneatobotvac.py b/neatobotvac/integrationpluginneatobotvac.py index 13730dd8..1f3ce05b 100644 --- a/neatobotvac/integrationpluginneatobotvac.py +++ b/neatobotvac/integrationpluginneatobotvac.py @@ -166,8 +166,6 @@ def pollService(): refreshRobot(thing) except: logger.warn("Error refreshing robot state") - global pollTimer - logger.log("timer interval @ pollService", pollTimer.interval) def executeAction(info): if info.actionTypeId == robotStartCleaningActionTypeId: @@ -323,4 +321,4 @@ def thingRemoved(thing): logger.log("len myThings", len(myThings())) if len(myThings()) == 0 and pollTimer is not None: logger.log("cancelling plugintimer") - pollTimer = None \ No newline at end of file + pollTimer = None diff --git a/nymea-plugins.pro b/nymea-plugins.pro index 6bd0c1c4..dae77734 100644 --- a/nymea-plugins.pro +++ b/nymea-plugins.pro @@ -5,6 +5,7 @@ PLUGIN_DIRS = \ aqi \ avahimonitor \ awattar \ + bimmerconnected \ bluos \ boblight \ bose \