<s> import logging <EOL> from twisted . internet import reactor <EOL> from pymodbus . server . async import StartTcpServer <EOL> from pymodbus . device import ModbusDeviceIdentification <EOL> from pymodbus . datastore import ModbusSequentialDataBlock <EOL> from pymodbus . datastore import ModbusSlaveContext , ModbusServerContext <EOL> from pymodbus . transaction import ModbusRtuFramer , ModbusAsciiFramer <EOL> import sys , random <EOL> import pygame <EOL> from pygame . locals import * <EOL> from pygame . color import * <EOL> import pymunk <EOL> logging . basicConfig ( ) <EOL> log = logging . getLogger ( ) <EOL> log . setLevel ( logging . INFO ) <EOL> def PLCSetTag ( addr , value ) : <EOL> context [ <NUM_LIT> ] . setValues ( <NUM_LIT:3> , addr , [ value ] ) <EOL> def PLCGetTag ( addr ) : <EOL> return context [ <NUM_LIT> ] . getValues ( <NUM_LIT:3> , addr , count = <NUM_LIT:1> ) [ <NUM_LIT:0> ] <EOL> SCREEN_WIDTH = <NUM_LIT> <EOL> SCREEN_HEIGHT = <NUM_LIT> <EOL> FPS = <NUM_LIT> <EOL> MODBUS_SERVER_PORT = <NUM_LIT> <EOL> PLC_TAG_LEVEL_SENSOR = <NUM_LIT> <EOL> PLC_TAG_LIMIT_SWITCH = <NUM_LIT> <EOL> PLC_TAG_MOTOR = <NUM_LIT> <EOL> PLC_TAG_NOZZLE = <NUM_LIT> <EOL> PLC_TAG_RUN = <NUM_LIT> <EOL> global bottles <EOL> bottles = [ ] <EOL> def to_pygame ( p ) : <EOL> """<STR_LIT>""" <EOL> return int ( p . x ) , int ( - p . y + <NUM_LIT> ) <EOL> def add_ball ( space ) : <EOL> mass = <NUM_LIT> <EOL> radius = <NUM_LIT:3> <EOL> inertia = pymunk . moment_for_circle ( mass , <NUM_LIT:0> , radius , ( <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> body = pymunk . Body ( mass , inertia ) <EOL> body . _bodycontents . v_limit = <NUM_LIT> <EOL> body . _bodycontents . h_limit = <NUM_LIT:1> <EOL> x = random . randint ( <NUM_LIT> , <NUM_LIT> ) <EOL> body . position = x , <NUM_LIT> <EOL> shape = pymunk . Circle ( body , radius , ( <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> shape . collision_type = <NUM_LIT> <EOL> space . add ( body , shape ) <EOL> return shape <EOL> def draw_ball ( screen , ball , color = THECOLORS [ '<STR_LIT>' ] ) : <EOL> p = int ( ball . body . position . x ) , <NUM_LIT> - int ( ball . body . position . y ) <EOL> pygame . draw . circle ( screen , color , p , int ( ball . radius ) , <NUM_LIT:2> ) <EOL> def add_bottle_in_sensor ( space ) : <EOL> body = pymunk . Body ( ) <EOL> body . position = ( <NUM_LIT> , <NUM_LIT> ) <EOL> radius = <NUM_LIT:2> <EOL> shape = pymunk . Circle ( body , radius , ( <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> shape . collision_type = <NUM_LIT> <EOL> space . add ( shape ) <EOL> return shape <EOL> def add_level_sensor ( space ) : <EOL> body = pymunk . Body ( ) <EOL> body . position = ( <NUM_LIT> , <NUM_LIT> ) <EOL> radius = <NUM_LIT:3> <EOL> shape = pymunk . Circle ( body , radius , ( <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> shape . collision_type = <NUM_LIT> <EOL> space . add ( shape ) <EOL> return shape <EOL> def add_limit_switch ( space ) : <EOL> body = pymunk . Body ( ) <EOL> body . position = ( <NUM_LIT:200> , <NUM_LIT> ) <EOL> radius = <NUM_LIT:2> <EOL> shape = pymunk . Circle ( body , radius , ( <NUM_LIT:0> , <NUM_LIT:0> ) ) <EOL> shape . collision_type = <NUM_LIT> <EOL> space . add ( shape ) <EOL> return shape <EOL> def add_nozzle ( space ) : <EOL> body = pymunk . Body ( ) <EOL> body . position = ( <NUM_LIT> , <NUM_LIT> ) <EOL> shape = pymunk . Poly . create_box ( body , ( <NUM_LIT:15> , <NUM_LIT:20> ) , ( <NUM_LIT:0> , <NUM_LIT:0> ) , <NUM_LIT:0> ) <EOL> space . add ( shape ) <EOL> return shape <EOL> def add_base ( space ) : <EOL> body = pymunk . Body ( ) <EOL> body . position = ( <NUM_LIT:0> , <NUM_LIT> ) <EOL> shape = pymunk . Poly . create_box ( body , ( SCREEN_WIDTH , <NUM_LIT:20> ) , ( ( SCREEN_WIDTH / <NUM_LIT:2> ) , - <NUM_LIT:10> ) , <NUM_LIT:0> ) <EOL> shape . friction = <NUM_LIT:1.0> <EOL> shape . collision_type = <NUM_LIT> <EOL> space . add ( shape ) <EOL> return shape <EOL> def add_bottle ( space ) : <EOL> mass = <NUM_LIT:10> <EOL> inertia = <NUM_LIT> <EOL> body = pymunk . Body ( mass , inertia ) <EOL> body . position = ( <NUM_LIT> , <NUM_LIT> ) <EOL> l1 = pymunk . Segment ( body , ( - <NUM_LIT> , <NUM_LIT:0> ) , ( - <NUM_LIT:100> , <NUM_LIT:0> ) , <NUM_LIT> ) <EOL> l2 = pymunk . Segment ( body , ( - <NUM_LIT> , <NUM_LIT:0> ) , ( - <NUM_LIT> , <NUM_LIT:100> ) , <NUM_LIT> ) <EOL> l3 = pymunk . Segment ( body , ( - <NUM_LIT:100> , <NUM_LIT:0> ) , ( - <NUM_LIT:100> , <NUM_LIT:100> ) , <NUM_LIT> ) <EOL> l1 . friction = <NUM_LIT> <EOL> l2 . friction = <NUM_LIT> <EOL> l3 . friction = <NUM_LIT> <EOL> l1 . collision_type = <NUM_LIT> <EOL> l2 . collision_type = <NUM_LIT> <EOL> l3 . collision_type = <NUM_LIT> <EOL> space . add ( l1 , l2 , l3 , body ) <EOL> return l1 , l2 , l3 <EOL> def draw_polygon ( screen , shape ) : <EOL> points = shape . get_vertices ( ) <EOL> fpoints = [ ] <EOL> for p in points : <EOL> fpoints . append ( to_pygame ( p ) ) <EOL> pygame . draw . polygon ( screen , THECOLORS [ '<STR_LIT>' ] , fpoints ) <EOL> def draw_lines ( screen , lines , color = THECOLORS [ '<STR_LIT>' ] ) : <EOL> """<STR_LIT>""" <EOL> for line in lines : <EOL> body = line . body <EOL> pv1 = body . position + line . a . rotated ( body . angle ) <EOL> pv2 = body . position + line . b . rotated ( body . angle ) <EOL> p1 = to_pygame ( pv1 ) <EOL> p2 = to_pygame ( pv2 ) <EOL> pygame . draw . lines ( screen , color , False , [ p1 , p2 ] ) <EOL> def no_collision ( space , arbiter , * args , ** kwargs ) : <EOL> return False <EOL> def level_ok ( space , arbiter , * args , ** kwargs ) : <EOL> log . debug ( "<STR_LIT>" ) <EOL> PLCSetTag ( PLC_TAG_LIMIT_SWITCH , <NUM_LIT:0> ) <EOL> PLCSetTag ( PLC_TAG_LEVEL_SENSOR , <NUM_LIT:1> ) <EOL> PLCSetTag ( PLC_TAG_NOZZLE , <NUM_LIT:0> ) <EOL> return False <EOL> def bottle_in_place ( space , arbiter , * args , ** kwargs ) : <EOL> log . debug ( "<STR_LIT>" ) <EOL> PLCSetTag ( PLC_TAG_LIMIT_SWITCH , <NUM_LIT:1> ) <EOL> PLCSetTag ( PLC_TAG_LEVEL_SENSOR , <NUM_LIT:0> ) <EOL> PLCSetTag ( PLC_TAG_NOZZLE , <NUM_LIT:1> ) <EOL> return False <EOL> def add_new_bottle ( space , arbiter , * args , ** kwargs ) : <EOL> global bottles <EOL> bottles . append ( add_bottle ( space ) ) <EOL> log . debug ( "<STR_LIT>" ) <EOL> return False <EOL> def runWorld ( ) : <EOL> pygame . init ( ) <EOL> screen = pygame . display . set_mode ( ( SCREEN_WIDTH , SCREEN_HEIGHT ) ) <EOL> pygame . display . set_caption ( "<STR_LIT>" ) <EOL> clock = pygame . time . Clock ( ) <EOL> running = True <EOL> space = pymunk . Space ( ) <EOL> space . gravity = ( <NUM_LIT:0.0> , - <NUM_LIT> ) <EOL> space . add_collision_handler ( <NUM_LIT> , <NUM_LIT> , begin = bottle_in_place ) <EOL> space . add_collision_handler ( <NUM_LIT> , <NUM_LIT> , begin = level_ok ) <EOL> space . add_collision_handler ( <NUM_LIT> , <NUM_LIT> , begin = no_collision ) <EOL> space . add_collision_handler ( <NUM_LIT> , <NUM_LIT> , begin = no_collision ) <EOL> space . add_collision_handler ( <NUM_LIT> , <NUM_LIT> , begin = no_collision ) <EOL> space . add_collision_handler ( <NUM_LIT> , <NUM_LIT> , begin = no_collision ) <EOL> space . add_collision_handler ( <NUM_LIT> , <NUM_LIT> , begin = no_collision , separate = add_new_bottle ) <EOL> space . add_collision_handler ( <NUM_LIT> , <NUM_LIT> , begin = no_collision ) <EOL> base = add_base ( space ) <EOL> nozzle = add_nozzle ( space ) <EOL> limit_switch = add_limit_switch ( space ) <EOL> level_sensor = add_level_sensor ( space ) <EOL> bottle_in = add_bottle_in_sensor ( space ) <EOL> global bottles <EOL> bottles . append ( add_bottle ( space ) ) <EOL> balls = [ ] <EOL> ticks_to_next_ball = <NUM_LIT:1> <EOL> fontBig = pygame . font . SysFont ( None , <NUM_LIT> ) <EOL> fontMedium = pygame . font . SysFont ( None , <NUM_LIT> ) <EOL> fontSmall = pygame . font . SysFont ( None , <NUM_LIT> ) <EOL> while running : <EOL> clock . tick ( FPS ) <EOL> for event in pygame . event . get ( ) : <EOL> if event . type == QUIT : <EOL> running = False <EOL> elif event . type == KEYDOWN and event . key == K_ESCAPE : <EOL> running = False <EOL> screen . fill ( THECOLORS [ "<STR_LIT>" ] ) <EOL> if PLCGetTag ( PLC_TAG_RUN ) : <EOL> if ( PLCGetTag ( PLC_TAG_LIMIT_SWITCH ) == <NUM_LIT:1> ) : <EOL> PLCSetTag ( PLC_TAG_MOTOR , <NUM_LIT:0> ) <EOL> if ( PLCGetTag ( PLC_TAG_LEVEL_SENSOR ) == <NUM_LIT:1> ) : <EOL> PLCSetTag ( PLC_TAG_MOTOR , <NUM_LIT:1> ) <EOL> ticks_to_next_ball -= <NUM_LIT:1> <EOL> if not PLCGetTag ( PLC_TAG_LIMIT_SWITCH ) : <EOL> PLCSetTag ( PLC_TAG_MOTOR , <NUM_LIT:1> ) <EOL> if ticks_to_next_ball <= <NUM_LIT:0> and PLCGetTag ( PLC_TAG_NOZZLE ) : <EOL> ticks_to_next_ball = <NUM_LIT:1> <EOL> ball_shape = add_ball ( space ) <EOL> balls . append ( ball_shape ) <EOL> if PLCGetTag ( PLC_TAG_MOTOR ) == <NUM_LIT:1> : <EOL> for bottle in bottles : <EOL> bottle [ <NUM_LIT:0> ] . body . position . x += <NUM_LIT> <EOL> else : <EOL> PLCSetTag ( PLC_TAG_MOTOR , <NUM_LIT:0> ) <EOL> balls_to_remove = [ ] <EOL> for ball in balls : <EOL> if ball . body . position . y < <NUM_LIT> or ball . body . position . x > SCREEN_WIDTH + <NUM_LIT> : <EOL> balls_to_remove . append ( ball ) <EOL> draw_ball ( screen , ball ) <EOL> for ball in balls_to_remove : <EOL> space . remove ( ball , ball . body ) <EOL> balls . remove ( ball ) <EOL> for bottle in bottles : <EOL> if bottle [ <NUM_LIT:0> ] . body . position . x > SCREEN_WIDTH + <NUM_LIT> or bottle [ <NUM_LIT:0> ] . body . position . y < <NUM_LIT> : <EOL> space . remove ( bottle , bottle [ <NUM_LIT:0> ] . body ) <EOL> bottles . remove ( bottle ) <EOL> continue <EOL> draw_lines ( screen , bottle ) <EOL> draw_polygon ( screen , base ) <EOL> draw_polygon ( screen , nozzle ) <EOL> draw_ball ( screen , limit_switch , THECOLORS [ '<STR_LIT>' ] ) <EOL> draw_ball ( screen , level_sensor , THECOLORS [ '<STR_LIT>' ] ) <EOL> title = fontMedium . render ( str ( "<STR_LIT>" ) , <NUM_LIT:1> , THECOLORS [ '<STR_LIT>' ] ) <EOL> name = fontBig . render ( str ( "<STR_LIT>" ) , <NUM_LIT:1> , THECOLORS [ '<STR_LIT>' ] ) <EOL> instructions = fontSmall . render ( str ( "<STR_LIT>" ) , <NUM_LIT:1> , THECOLORS [ '<STR_LIT>' ] ) <EOL> screen . blit ( title , ( <NUM_LIT:10> , <NUM_LIT> ) ) <EOL> screen . blit ( name , ( <NUM_LIT:10> , <NUM_LIT:10> ) ) <EOL> screen . blit ( instructions , ( SCREEN_WIDTH - <NUM_LIT> , <NUM_LIT:10> ) ) <EOL> space . step ( <NUM_LIT:1> / FPS ) <EOL> pygame . display . flip ( ) <EOL> if reactor . running : <EOL> reactor . callFromThread ( reactor . stop ) <EOL> store = ModbusSlaveContext ( <EOL> di = ModbusSequentialDataBlock ( <NUM_LIT:0> , [ <NUM_LIT:0> ] * <NUM_LIT:100> ) , <EOL> co = ModbusSequentialDataBlock ( <NUM_LIT:0> , [ <NUM_LIT:0> ] * <NUM_LIT:100> ) , <EOL> hr = ModbusSequentialDataBlock ( <NUM_LIT:0> , [ <NUM_LIT:0> ] * <NUM_LIT:100> ) , <EOL> ir = ModbusSequentialDataBlock ( <NUM_LIT:0> , [ <NUM_LIT:0> ] * <NUM_LIT:100> ) ) <EOL> context = ModbusServerContext ( slaves = store , single = True ) <EOL> identity = ModbusDeviceIdentification ( ) <EOL> identity . VendorName = '<STR_LIT>' <EOL> identity . ProductCode = '<STR_LIT>' <EOL> identity . VendorUrl = '<STR_LIT>' <EOL> identity . ProductName = '<STR_LIT>' <EOL> identity . ModelName = '<STR_LIT>' <EOL> identity . MajorMinorRevision = '<STR_LIT:1.0>' <EOL> def startModbusServer ( ) : <EOL> StartTcpServer ( context , identity = identity , address = ( "<STR_LIT:localhost>" , MODBUS_SERVER_PORT ) ) <EOL> def main ( ) : <EOL> reactor . callInThread ( runWorld ) <EOL> startModbusServer ( ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> sys . exit ( main ( ) ) </s>
