import sys import json import urllib.request def upload(ip, script_id, code_file): # Read JS code with open(code_file, 'r', encoding='utf-8') as f: code = f.read() url = f"http://{ip}/rpc" # Stop the script first to prevent write locks print(f"Stopping script {script_id}...") req = urllib.request.Request( url, data=json.dumps({"id": 1, "method": "Script.Stop", "params": {"id": int(script_id)}}).encode('utf-8'), headers={'Content-Type': 'application/json'} ) try: urllib.request.urlopen(req) except Exception as e: print(f"Stop request failed (might already be stopped): {e}") # Chunk the code into 500 byte chunks (Shelly RPC size limit) chunk_size = 500 chunks = [code[i:i + chunk_size] for i in range(0, len(code), chunk_size)] for idx, chunk in enumerate(chunks): append = idx > 0 print(f"Uploading chunk {idx + 1}/{len(chunks)} (append={append})...") payload = { "id": 1, "method": "Script.PutCode", "params": { "id": int(script_id), "code": chunk, "append": append } } req = urllib.request.Request( url, data=json.dumps(payload).encode('utf-8'), headers={'Content-Type': 'application/json'} ) with urllib.request.urlopen(req) as resp: res = json.loads(resp.read().decode('utf-8')) if "error" in res: raise Exception(f"Failed to upload chunk: {res['error']}") print("Script upload complete!") if __name__ == "__main__": if len(sys.argv) < 4: print("Usage: python3 upload.py ") sys.exit(1) upload(sys.argv[1], sys.argv[2], sys.argv[3])