All Projects → opravdin → weback-unofficial

opravdin / weback-unofficial

Licence: MIT License
Unofficial WeBack API client

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to weback-unofficial

awsretry
Decorate your AWS Boto3 Calls with AWSRetry.backoff(). This will allows your calls to get around the AWS Eventual Consistency Errors.
Stars: ✭ 42 (+100%)
Mutual labels:  boto3
pytest-serverless
Automatically mocks resources from serverless.yml in pytest using moto.
Stars: ✭ 26 (+23.81%)
Mutual labels:  boto3
export-dynamodb
Export Amazon DynamoDb to CSV or JSON
Stars: ✭ 52 (+147.62%)
Mutual labels:  boto3
aws-security-test
No description or website provided.
Stars: ✭ 14 (-33.33%)
Mutual labels:  boto3
favv
Fullstack Web Application Framework With FastAPI + Vite + VueJS. Streamlit for rapid development.
Stars: ✭ 17 (-19.05%)
Mutual labels:  boto3
botor
Reticulate wrapper on 'boto3' with convenient helper functions -- aka "boto fo(u)r R"
Stars: ✭ 28 (+33.33%)
Mutual labels:  boto3
cognises-flask
Flask Cognises: AWS Cognito group based authorization with user management
Stars: ✭ 16 (-23.81%)
Mutual labels:  boto3
weback-hass
Weback integration with Home Assistant
Stars: ✭ 33 (+57.14%)
Mutual labels:  weback
simple-flask-s3-uploader
Simple and easy to use Flask app to upload files to Amazon S3. Based on Python, Flask, and using Boto3. Securely storing your AWS credentials as environment variables. Quick AWS S3 Flask uploader example.
Stars: ✭ 24 (+14.29%)
Mutual labels:  boto3
invoiceless
Serverless backend for sending simple recurring invoices
Stars: ✭ 44 (+109.52%)
Mutual labels:  boto3
s3-credentials
A tool for creating credentials for accessing S3 buckets
Stars: ✭ 138 (+557.14%)
Mutual labels:  boto3
pyMTurkR
A Client for the MTurk Requester API
Stars: ✭ 16 (-23.81%)
Mutual labels:  boto3
s3upload
Upload multiple files to AWS S3, make them public, and get their URLs easily from the command line.
Stars: ✭ 24 (+14.29%)
Mutual labels:  boto3
RAthena
Connect R to Athena using Boto3 SDK (DBI Interface)
Stars: ✭ 30 (+42.86%)
Mutual labels:  boto3
boto3-examples
Example scripts for boto3.
Stars: ✭ 55 (+161.9%)
Mutual labels:  boto3
parameterstore-backup
Python script to take a backup of the AWS parameter store
Stars: ✭ 19 (-9.52%)
Mutual labels:  boto3
Security monkey
Security Monkey monitors AWS, GCP, OpenStack, and GitHub orgs for assets and their changes over time.
Stars: ✭ 4,244 (+20109.52%)
Mutual labels:  boto3

Unofficial WeBack API Client

This client was developed using reverse engineering of the Android application and traffic analysis. There is no guarantee that this API will continue to work. However, it will be quite easy to fix in case of any errors/issues/changes as the WeBack servers are only responsible for gaining access to the API (Amazon Cognito, to be precise).

Usage

pip3 install weback-unofficial

Authentication

First of all, you need to choose whether you want to manage your session manually or with this package.

from weback_unofficial.client import WebackApi
import boto3

# Method 1: make this package keep session itself
client = WebackApi('+7-1234567890', '<your_password>')
session = client.get_session() # Returns Amazon Session from boto3 package 


# Method 2: manage by yourself
client = WebackApi()
weback_data = client.auth('+7-1234567890', '<your_password>') # Returns creds for auth in AWS

region = weback_data['Region_Info']
client = boto3.client('cognito-identity', region)

# Here you will receive session data & expiration time (usually 1 day)
# Don't forget to keep it alive!
aws_creds =  client.get_credentials_for_identity(
    IdentityId=weback_data['Identity_Id'], 
    Logins={
        "cognito-identity.amazonaws.com": weback_data['Token']
    }
)
session = boto3.Session(
    aws_access_key_id=aws_creds['Credentials']['AccessKeyId'],
    aws_secret_access_key=aws_creds['Credentials']['SecretKey'],
    aws_session_token=aws_creds['Credentials']['SessionToken'],
    region_name=region
)

Manipulating with vacuum robot (example)

devices = client.device_list()
device_name = devices[0]['Thing_Name']
# Method 1: via helper functions
# Get device shadow status
client.get_device_shadow(device_name)
# Get device description: https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeThing.html
client.get_device_description(device_name)
# Publish message for device
client.publish_device_msg(device_name, {"working_status": "AutoClean"})

# Method 2: via Vacuum class
vacuum = CleanRobot(device_name, self.client)
vacuum.update()
print(vacuum.state)
print(vacuum.current_mode)

vacuum.turn_on()
vacuum.stop()
vacuum.return_home()

# Method 3: by yourself
# Get device shadow status
client = session.client('iot-data')
resp = client.get_thing_shadow(thingName=device_name)
shadow = json.loads(resp['payload'].read())
print("Attributes:")
pp = pprint.PrettyPrinter(indent=1)
pp.pprint(shadow['state']['reported'])

# Start up vacuum cleaner
client = session.client('iot-data')
topic = f"$aws/things/{device_name}/shadow/update"
# See more MQTT commands below
payload = {
    'state': {
        'desired': {
            "working_status": "AutoClean"
        }
    }
}
resp = client.publish(topic=topic, qos = 0, payload = json.dumps(payload))
print(resp)

API usage cycle description

I implemented a minimum number of entry points to activate the vacuum cleaner robot. There are definitely other entry points, but they're either not necessary or I don't have devices to check them.

  • Authorization by username and password. If you use the phone number as a login, provide it in the format {country code}-{number} (e.g. +7-1234567890 if you are from Russia). The server will return the data for access via Amazon Cognito.
  • Authorization in Amazon API (boto3 method)
    • Logins format is {"cognito-identity.amazonaws.com": weback_data['Token']}
  • Device list receiving (via WeBack's Amazon Lambda)
  • Fetching device status via Shadow (boto3 method)
  • OR
  • Controlling device via MQTT publish on f"$aws/things/{device_name}/shadow/update" (boto3 method)

API description

For each WeBack-related request the method of its call with or without this client is described. This package also contains several helper methods to simplify the work with the API.

Authorization

POST https://www.weback-login.com/WeBack/WeBack_Login_Ats_V3
Payload: {
    "App_Version":"android_3.9.3", # App version
    "Password":"a57da57da57da57da57da57da57da57d", # Password MD5 hash
    "User_Account":"+7-1234567890"
}

Response example: {
  "Request_Result": "success",
  "Identity_Pool_Id": "POOL_ID",
  "Developer_Provider_Name": "Login_WeBack_AP_SOUTHEAST_1",
  "End_Point": "ENDPOINT",
  "Identity_Id": "ID",
  "Token": "TOKEN",
  "Token_Duration": 86400,
  "Region_Info": "ap-southeast-1",
  "Configuration_Page_URL": "URL",
  "Discovery_Page_URL": "URL",
  "Customer_Service_Card_URL": "URL",
  "Thing_Register_URL": "URL",
  "Thing_Register_URL_Signature": "URL"
}

Fetching device list

AWS Lambda name: Device_Manager_V2
Payload: {
    "Device_Manager_Request":"query",
    "Identity_Id":"<Identity_Id>",
    "Region_Info":"<Region_Info>"
}

Response example: {
    "Device_Manager_Request": "query",
    "Request_Result": "success",
    "Request_Cotent": [{
        "Thing_Name": "device-name-plus-mac-address",
        "Thing_Nick_Name": "your-device-nick-name",
        "Image_Url": "image-url"
    }]
}

MQTT Payload

You should provide payload like this

    payload = {
        'state': {
            'desired': {
                "<Attribute>": "<Status>"
            }
        }
    }

Here "Attribute" and "Status" is one of the payload values from the next sections. I'm not sure if this is suitable for all devices, but my robot vacuum cleaner reacts perfectly to them.

List of MQTT attributes

You can get Shadow status of your device and try to manipulate the parameters included in it (the keys are usually the same).
Currently I have found just some of them: (related to my robot vacuum)

  • fan_status
    • ROBOT_CTRL_SPEED_NORMAL("Normal"),
    • ROBOT_CTRL_SPEED_STRONG("Strong"),
  • working_status - Try "ROBOT_CTRL_" ENUMs. I tested Standby, BackCharging, MopClean and SmartClean. Last one works both with mop and vacuum modes.
  • water_tank_shift and water_level - Same parameters (apparently), but the specific attribute depends on the robot. These values are suitable for "water_level" in my case:
    • ROBOT_WATER_TANK_LOW("Low"),
    • ROBOT_WATER_TANK_DEFAULT("Default"),
    • ROBOT_WATER_TANK_HIGH("High")

List of all MQTT messages

Grabbed from ENUMs in code.

ROBOT_CTRL_FRONT("MoveFront"),
ROBOT_CTRL_BACK("MoveBack"),
ROBOT_CTRL_LEFT("MoveLeft"),
ROBOT_CTRL_RIGHT("MoveRight"),
ROBOT_CTRL_STOP("MoveStop"),
ROBOT_NEW_CTRL_FRONT("move_front"),
ROBOT_NEW_CTRL_BACK("move_back"),
ROBOT_NEW_CTRL_LEFT("move_left"),
ROBOT_NEW_CTRL_RIGHT("move_right"),
ROBOT_NEW_CTRL_STOP("move_stop"),
ROBOT_CTRL_CLEAN_STOP("Standby"),
ROBOT_CTRL_CLEAN_CHARGE("BackCharging"),
ROBOT_CTRL_CLEAN_STOP2("Stop"),
ROBOT_CTRL_MODE_SPOT("SpotClean"),
ROBOT_CTRL_MODE_PLAN("PlanClean"),
ROBOT_CTRL_MODE_ROOM("RoomClean"),
ROBOT_CTRL_MODE_AUTO("AutoClean"),
ROBOT_CTRL_MODE_EDGE("EdgeClean"),
ROBOT_CTRL_MODE_FIXED("StrongClean"),
ROBOT_CTRL_MODE_Z("ZmodeClean"),
ROBOT_CTRL_MODE_MOPPING("MopClean"),
ROBOT_CTRL_VACUUM("VacuumClean"),
PLANNING_RECT("PlanningRect"),
ROBOT_CTRL_MODE_PLAN2("SmartClean"),
ROBOT_CTRL_SPEED_NORMAL("Normal"),
ROBOT_CTRL_SPEED_STRONG("Strong"),
ROBOT_CTRL_SPEED_STOP("Pause"),
ROBOT_CTRL_SPEED_SOUND_STOP("Quite"),
ROBOT_CTRL_SPEED_SOUND_STOP_2("Quiet"),
ROBOT_CTRL_SPEED_MAX("Max"),
ROBOT_HAS_NONE_FAN("None"),
ROBOT_WORK_STATUS_STOP("Hibernating"),
ROBOT_WORK_STATUS_STANDBY("Standby"),
ROBOT_LOCATION_ALARM("LocationAlarm"),
PLANNING_LOCATION("PlanningLocation"),
ROBOT_WORK_STATUS_CHARGING_3("Charging"),
ROBOT_WORK_STATUS_WORKING("Cleaning"),
ROBOT_WORK_STATUS_WORK_OVER("Cleandone"),
ROBOT_WORK_STATUS_GO_CHARGE("Backcharging"),
ROBOT_WORK_STATUS_CHARGING("Pilecharging"),
ROBOT_WORK_STATUS_CHARGE_OVER("Chargedone"),
ROBOT_WORK_STATUS_LOWPOWER("Lowpower"),
ROBOT_WORK_STATUS_ERROR("Malfunction"),
ROBOT_WORK_STATUS_CHARGING2("DirCharging"),
ROBOT_WORK_STATUS_CTRL("DirectionControl"),
ROBOT_WATER_TANK_OFF(BucketVersioningConfiguration.OFF),
ROBOT_WATER_TANK_LOW("Low"),
ROBOT_WATER_TANK_DEFAULT("Default"),
ROBOT_WATER_TANK_HIGH("High"),
ROBOT_WATER_TANK_LOW_TAB("Slow"),
ROBOT_WATER_TANK_DEFAULT_TAB("Normal"),
ROBOT_WATER_TANK_HIGH_TAB("Fast"),
ROBOT_HAS_NONE_TANK("None"),
ROBOT_VOICE_CTRL_ON("on"),
ROBOT_VOICE_CTRL_OFF("off"),
ROBOT_CAMERA_UP("Up"),
ROBOT_CAMERA_DOWN("Down"),
ROBOT_CAMERA_LEFT("Left"),
ROBOT_CAMERA_RIGHT("Right"),
ROBOT_POWER_AWAKE("PowerAwake"),
ROBOT_POWER_SLEEP("PowerSleep"),
ROBOT_NO_CHATTING("NoChatting"),
ROBOT_AV_CHATTING("AVChatting"),
ROBOT_VIDEO_CHATTING("VideoChatting"),
ROBOT_AUDIO_CHATTING("AudioChatting"),
ROBOT_SPEED_LOW("Low"),
ROBOT_SPEED_HIGH("High"),
ROBOT_ERROR_NO("NoError"),
ROBOT_ERROR_UNKNOWN("UnknownError"),
ROBOT_ERROR_LEFT_WHEEL("LeftWheelWinded"),
ROBOT_ERROR_RIGHT_WHEEL("RightWheelWinded"),
ROBOT_ERROR_WHEEL_WINDED("WheelWinded"),
ROBOT_ERROR_60017("LeftWheelSuspend"),
ROBOT_ERROR_60019("RightWheelSuspend"),
ROBOT_ERROR_WHEEL_SUSPEND("WheelSuspend"),
ROBOT_ERROR_LEFT_BRUSH("LeftSideBrushWinded"),
ROBOT_ERROR_RIGHT_BRUSH("RightSideBrushWinded"),
ROBOT_ERROR_SIDE_BRUSH("SideBrushWinded"),
ROBOT_ERROR_60031("RollingBrushWinded"),
ROBOT_ERROR_COLLISION("AbnormalCollisionSwitch"),
ROBOT_ERROR_GROUND("AbnormalAntiFallingFunction"),
ROBOT_ERROR_FAN("AbnormalFan"),
ROBOT_ERROR_DUSTBOX2("NoDustBox"),
ROBOT_ERROR_CHARGE_FOUND("CannotFindCharger"),
ROBOT_ERROR_CHARGE_ERROR("BatteryMalfunction"),
ROBOT_ERROR_LOWPOWER("LowPower"),
ROBOT_ERROR_CHARGE("BottomNotOpenedWhenCharging"),
ROBOT_ERROR_CAMERA_CONTACT_FAIL("CameraContactFailure"),
ROBOT_ERROR_LIDAR_CONNECT_FAIL("LidarConnectFailure"),
ROBOT_ERROR_TANK("AbnormalTank"),
ROBOT_ERROR_SPEAKER("AbnormalSpeaker"),
ROBOT_ERROR_NO_WATER_BOX("NoWaterBox"),
ROBOT_ERROR_NO_WATER_MOP("NoWaterMop"),
ROBOT_ERROR_WATER_BOX_EMPTY("WaterBoxEmpty"),
ROBOT_ERROR_FLOATING("WheelSuspendInMidair"),
ROBOT_ERROR_DUSTBOX("DustBoxFull"),
ROBOT_ERROR_GUN_SHUA("BrushTangled"),
ROBOT_ERROR_TRAPPED("RobotTrapped"),
ROBOT_CHARGING_ERROR("ChargingError"),
ROBOT_BOTTOM_NOT_OPENED_WHEN_CHARGING("BottomNotOpenedWhenCharging"),
ROBOT_ERROR_60024("CodeDropped"),
ROBOT_ERROR_60026("NoDustBox"),
ROBOT_ERROR_60028("OperatingCurrentOverrun"),
ROBOT_ERROR_60029("VacuumMotorTangled"),
ROBOT_ERROR_60032("StuckWheels"),
ROBOT_ERROR_STUCK("RobotStuck"),
ROBOT_ERROR_BE_TRAPPED("RobotBeTrapped"),
ROBOT_ERROR_COVER_STUCK("LaserHeadCoverStuck"),
ROBOT_ERROR_LASER_HEAD("AbnormalLaserHead"),
ROBOT_ERROR_WALL_BLOCKED("WallSensorBlocked"),
ROBOT_ERROR_VIR_WALL_FORB("VirtualWallForbiddenZoneSettingError"),
ROBOT_IS_OFF("off"),
ROBOT_IS_ON("on"),
ROBOT_MODE_COLOR("color"),
ROBOT_MODE_WHITE("white"),
UPGRADING_DOWNLOAD_WIFI("upgrading_download_wifi"),
UPGRADING_INSTALL_WIFI("upgrading_install_wifi"),
UPGRADING_DOWNLOAD_VENDOR("upgrading_download_vendor"),
UPGRADING_INSTALL_VENDOR("upgrading_install_vendor"),
UPGRADING_DOWNLOAD_CHASSIS("upgrading_download_chassis"),
UPGRADING_INSTALL_CHASSIS("upgrading_install_chassis"),
UPGRADING_REBOOTING("upgrading_rebooting"),
UNREACHABLE("UnReachable"),
REACHABLE("Reached"),
ROBOT_CTRL_START_UP("StartUp"),
ROBOT_EDGE_DETECT("EdgeDetect"),
UNDISTURB_MODE("undisturb_mode"),
ROBOT_CLEAR_MAP("ClearMap"),
ROBOT_RELOCATION("Relocation");
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].