@@ -438,6 +438,25 @@ def __init__(
438438 self .parameters = parameters
439439 self .type = type
440440
441+ def to_payload (self ) -> dict [str , object ]:
442+ """Return a JSON-serializable payload for this command.
443+
444+ The payload uses snake_case keys; the client will convert to camelCase
445+ and apply small key fixes (like `deviceURL`) before sending.
446+ """
447+ payload : dict [str , object ] = {"name" : str (self .name )}
448+
449+ if self .type is not None :
450+ payload ["type" ] = self .type
451+
452+ if self .parameters is not None :
453+ payload ["parameters" ] = [
454+ p if isinstance (p , (str , int , float , bool )) else str (p )
455+ for p in self .parameters # type: ignore[arg-type]
456+ ]
457+
458+ return payload
459+
441460
442461@define (init = False , kw_only = True )
443462class Event :
@@ -555,9 +574,21 @@ class Action:
555574 device_url : str
556575 commands : list [Command ]
557576
558- def __init__ (self , device_url : str , commands : list [dict [str , Any ]]):
577+ def __init__ (self , device_url : str , commands : list [dict [str , Any ] | Command ]):
559578 self .device_url = device_url
560- self .commands = [Command (** c ) for c in commands ] if commands else []
579+ self .commands = [
580+ c if isinstance (c , Command ) else Command (** c ) for c in commands
581+ ]
582+
583+ def to_payload (self ) -> dict [str , object ]:
584+ """Return a JSON-serializable payload for this action (snake_case).
585+
586+ The final camelCase conversion is handled by the client.
587+ """
588+ return {
589+ "device_url" : self .device_url ,
590+ "commands" : [c .to_payload () for c in self .commands ],
591+ }
561592
562593
563594@define (init = False , kw_only = True )
0 commit comments