pws1_sm.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. #include "plt.h"
  2. static struct state_t pws1_states[] = {
  3. { SMST_LAUNCH, "launch" },
  4. { SMST_STDBY, "stdby" },
  5. { SMST_STOP, "stop" },
  6. { SMST_READY, "ready" },
  7. { SMST_DHG, "dhg" },
  8. { SMST_CHG, "chg" },
  9. { SMST_OFFGRID, "offgrid" },
  10. { SMST_ERR, "err" },
  11. };
  12. static struct err_t pws1_errs[] = {
  13. {PWS1ERR_NONE, "none"},
  14. // launch PWS1ERR_LAUNCH_COMMERR
  15. {PWS1ERR_LAUNCH_COMMERR, "launch, comm err"},
  16. // err
  17. {PWS1ERR_ERR_COMMERR, "err, comm err"},
  18. {PWS1ERR_ERR_PWRUP, "err, pwrup"},
  19. // stdby
  20. {PWS1ERR_STDBY_COMMERR, "stdby, comm err"},
  21. {PWS1ERR_STDBY_CHK_DEVAPS0_FAIL_AFTER_SET, "stdby, chk aps = 0 fail"},
  22. {PWS1ERR_STDBY_CHK_STOP_FAIL_AFTER_SET, "stdby, chk stop fail"},
  23. {PWS1ERR_STDBY_WAIT_STOP_TIMEOUT, "stdby, wait stop timeout"},
  24. {PWS1ERR_STDBY_WAIT_RUN_TIMEOUT, "stdby, wait run state timeout"},
  25. {PWS1ERR_STDBY_UNKOWN_RUNSTAT, "stdby, unknown run state"},
  26. // stop
  27. {PWS1ERR_STOP_COMMERR, "stop, comm err"},
  28. {PWS1ERR_STOP_NONE_STOP_DETECTED, "stop, none stop run state detected"},
  29. {PWS1ERR_STOP_CHK_DEVAPS0_FAIL_AFTER_SET, "stop, chk dev aps = 0 fail"},
  30. {PWS1ERR_STOP_CHK_ONGRID_FAIL_AFTER_SET, "stop, chk on grid fail after set"},
  31. {PWS1ERR_STOP_CHK_DISPATCH_AC_FAIL_AFTER_SET, "stop, chk dispatch ac fail after set"},
  32. {PWS1ERR_STOP_CHK_AC_CONTROL_MODEL_FIX_AC_POWER_FIAL_AFTER_SET, "stop, chk ac control fix power fail fater set"},
  33. {PWS1ERR_STOP_CHK_STATE_RUNNING_FAIL_AFTER_SET, "stop, chk state running fail after set"},
  34. // ready
  35. {PWS1ERR_READY_COMMERR, "ready, comm err"},
  36. {PWS1ERR_READY_WAIT_STOP_TIMEOUT, "ready, wait stop timeout"},
  37. {PWS1ERR_READY_WAIT_AP4DHG_TIMEOUT, "ready, wait ap for dhg timeout"},
  38. {PWS1ERR_READY_WAIT_DHG_STATE_TIME_OUT, "ready, wait dhg state timeout"},
  39. {PWS1ERR_READY_WAIT_AP4CHG_TIMEOUT, "ready, wait ap for chg timeout"},
  40. {PWS1ERR_READY_WAIT_CHG_STATE_TIME_OUT, "ready, wait chg state timeout"},
  41. {PWS1ERR_READY_WAIT_RUNSTATE_STOP_TIMEOUT_AFTER_SET, "ready, wait run state stop time out after set"},
  42. {PWS1ERR_READY_WAIT_RUNMODE_OFFGRID_TIMEOUT_AFTER_SET, "stop, wait run mode offgrid time out after set"},
  43. {PWS1ERR_READY_WAIT_RUNSTATE_RUNING_TIMEOUT_AFTER_SET, "stop, wait run state running time out after set"},
  44. {PWS1ERR_READY_WAIT_TARGET_VOLTAGE_FOR_OFFGRID_TIMEOUT, "stop, wait target voltage for offgrid timeout"},
  45. // dhg
  46. {PWS1ERR_DHG_COMMERR, "dhg, comm err"},
  47. {PWS1ERR_DHG_STATE_NOT_RUN_DETECTED, "dhg, not run detected"},
  48. {PWS1ERR_DHG_STATE_NOT_DHG_DETECTED, "dhg, non-dhg detected"},
  49. {PWS1ERR_DHG_WAIT_DEVAPS0_FOR_READYCMD_TIMEOUT, "dhg, wait ap = 0 timeout"},
  50. {PWS1ERR_DHG_WAIT_DEV_NO_DHG_TIME_OUT, "dhg, wait no dhg timeout"},
  51. // chg
  52. {PWS1ERR_CHG_COMMERR, "chg, comm err"},
  53. {PWS1ERR_CHG_STATE_NOT_RUN_DETECTED, "chg, not run detected"},
  54. {PWS1ERR_CHG_STATE_NOT_CHG_DETECTED, "chg, non-chg detected"},
  55. {PWS1ERR_CHG_WAIT_DEVAPS0_FOR_READYCMD_TIMEOUT, "chg, wait ap = 0 timeout"},
  56. {PWS1ERR_CHG_WAIT_DEV_NO_CHG_TIME_OUT, "chg, wait no chg timeout"},
  57. // offgrid
  58. {PWS1ERR_OFFGRID_ERRSTAT_DETECTED, "offgrid, err state detected"},
  59. {PWS1ERR_OFFGRID_NOT_RUNNING_DETECTED, "offgrid, not run detected"},
  60. {PWS1ERR_OFFGRID_WAIT_STOP_TIME_OUT, "offgrid, wait stop time out"},
  61. {PWS1ERR_OFFGRID_WAIT_RUN_MODE_ON_GIRD_TIME_OUT, "offgrid, wait run mode on grid time out"},
  62. };
  63. int pws1_sm_init(int idx)
  64. {
  65. struct statemachine_t* sm = &pws1[idx].sm;
  66. sm_reset_timing(sm, 10, 10);
  67. sm->states = pws1_states;
  68. sm->state_nbr = sizeof(pws1_states)/sizeof(struct state_t);
  69. sm->errs = pws1_errs;
  70. sm->err_nbr = sizeof(pws1_errs)/sizeof(struct err_t);
  71. sm_set_state( sm, SMST_LAUNCH, PWS1ERR_NONE );
  72. return 0;
  73. }
  74. static void pws1_sm_launch( int idx )
  75. {
  76. struct pws1_t* dev = &pws1[idx];
  77. struct comm_t* comm = &dev->comm;
  78. struct statemachine_t* sm = &dev->sm;
  79. if( sm_get_step(sm) == 0 ){ // entry
  80. log_dbg("%s, idx:%d, state:%s, step:%d, entry", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  81. pws1_reset_cmd(idx);
  82. pws1_comm_reset(idx);
  83. sm_set_step(sm, 20);
  84. }else if( sm_get_step(sm) == 20 ){
  85. if( comm_get_state(comm) != COMMST_NORMAL){
  86. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",__func__, idx,sm_get_szstate(sm), sm_get_step(sm));
  87. sm_set_state(sm, SMST_ERR, PWS1ERR_LAUNCH_COMMERR);
  88. }else if(pws1_get_runstat(idx) != PWS1_RUNSTAT_PCS_INIT && pws1_get_runstat(idx) != PWS1_RUNSTAT_UNKOWNING){
  89. log_dbg("%s, idx:%d, state:%s, step:%d, comm ok and pcs init finished,goto stdby!!",__func__, idx,sm_get_szstate(sm), sm_get_step(sm));
  90. sm_set_state(sm, SMST_STDBY, PWS1ERR_NONE);
  91. }
  92. }
  93. }
  94. static void pws1_sm_err( int idx )
  95. {
  96. struct pws1_t* dev = &pws1[idx];
  97. struct comm_t* comm = &pws1[idx].comm;
  98. struct statemachine_t* sm = &pws1[idx].sm;
  99. static double ts_last_try;
  100. double ts;
  101. if( sm_get_step(sm) == 0 ){ // entry
  102. log_dbg("%s, idx:%d, state:%s, step:%d, entry", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  103. pws1_reset_cmd(idx);
  104. sm_set_step(sm, 10);
  105. ts_last_try = sm_get_timeofday();
  106. }else if( sm_get_step(sm) == 10 ){ // wait cmd
  107. ts = sm_get_timeofday();
  108. if( pws1_get_cmd(idx) == CMD_SM_STDBY){ // stdby cmd
  109. log_dbg("%s, idx:%d, state:%s, step:%d, get stdby cmd, reset comm then chk",
  110. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  111. pws1_reset_cmd(idx);
  112. pws1_comm_reset(idx);
  113. sm_set_step(sm, 20);
  114. }else if( comm_get_state(comm) != COMMST_NORMAL && (ts - ts_last_try > 60000) ){ // 60s
  115. log_dbg("%s, idx:%d, state:%s, step:%d,comm:%s,reset comm",
  116. __func__, idx, sm_get_szstate(sm), sm_get_step(sm),comm_get_state_str(comm));
  117. ts_last_try = ts;
  118. pws1_comm_reset(idx);
  119. }
  120. }else if( sm_get_step(sm) == 20 ){ /* chk comm state */
  121. if( comm_get_state(comm) == COMMST_NORMAL){
  122. log_dbg("%s, idx:%d, state:%s, step:%d, comm ok, goto stdby",
  123. __func__, idx,sm_get_szstate(sm), sm_get_step(sm));
  124. sm_set_state(sm, SMST_STDBY, PWS1ERR_NONE);
  125. }else{
  126. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, stay err",
  127. __func__, idx,sm_get_szstate(sm), sm_get_step(sm));
  128. sm_set_state(sm, SMST_ERR, PWS1ERR_ERR_COMMERR);
  129. }
  130. }
  131. }
  132. static void pws1_sm_stdby( int idx )
  133. {
  134. struct pws1_t* dev = &pws1[idx];
  135. struct comm_t* comm = &pws1[idx].comm;
  136. struct statemachine_t* sm = &pws1[idx].sm;
  137. /* chk comm state */
  138. if( comm_get_state(comm) != COMMST_NORMAL){
  139. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  140. sm_set_state(sm, SMST_ERR, PWS1ERR_STDBY_COMMERR);
  141. return;
  142. }
  143. if( sm_get_step(sm) == 0 ){ /* entry */
  144. pws1_reset_cmd(idx);
  145. sm_set_step(sm, 10);
  146. }else if( sm_get_step(sm) == 10 ){ /* wait cmd */
  147. if( pws1_get_cmd(idx) == CMD_SM_STOP ){ /* stop cmd */
  148. log_dbg("%s, idx:%d, state:%s, step:%d, get stop cmd, chk devaps = 0 ?",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  149. pws1_reset_cmd(idx);
  150. sm_set_step(sm, 20);
  151. }
  152. }else if( sm_get_step(sm) == 20 ){ /* chk devaps = 0 ? */
  153. if( pws1_get_dev_aps(idx) != 0 ){
  154. log_dbg("%s, idx:%d, state:%s, step:%d, devaps != 0 detected, set it to 0, wait and chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  155. pws1_comm_set_active_power(idx, 0);
  156. sm_set_step(sm, 30);
  157. }else{
  158. log_dbg("%s, idx:%d, state:%s, step:%d, devaps = 0 detected, chk stop state",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  159. sm_set_step(sm, 40);
  160. }
  161. }else if( sm_get_step(sm) == 30 ){ /* wait and chk devaps = 0 */
  162. if( pws1_get_dev_aps(idx) == 0 ){
  163. log_dbg("%s, idx:%d, state:%s, step:%d, devaps = 0 detected, chk stop state",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  164. sm_set_step(sm, 40);
  165. }else{
  166. log_dbg("%s, idx:%d, state:%s, step:%d, chk devaps = 0 fail after set, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  167. sm_set_state(sm, SMST_ERR, PWS1ERR_STDBY_CHK_DEVAPS0_FAIL_AFTER_SET);
  168. }
  169. }else if( sm_get_step(sm) == 40 ){ /* chk runstate = stop ? */
  170. if( PWS1_RUNSTAT_STOP != pws1_get_runstat(idx) ){
  171. log_dbg("%s, idx:%d, state:%s, step:%d, non-stop run state detected, send stop cmd, wait and chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  172. pws1_comm_set_dev_stopcmd(idx);
  173. sm_set_step(sm, 50);
  174. sm_set_count(sm, 0);
  175. }else{
  176. log_dbg("%s, idx:%d, state:%s, step:%d, stop run state detected, goto stop",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  177. sm_set_state(sm, SMST_STOP, PWS1ERR_NONE);
  178. }
  179. }else if( sm_get_step(sm) == 50 ){ /* wait run state = stop after stopcmd*/
  180. if( PWS1_RUNSTAT_STOP == pws1_get_runstat(idx) ){
  181. log_dbg("%s, idx:%d, state:%s, step:%d, stop run state detected, goto stop",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  182. sm_set_state(sm, SMST_STOP, PWS1ERR_NONE);
  183. }else{
  184. sm_inc_count(sm);
  185. if( sm_get_count(sm) >= 100){
  186. log_dbg("%s, idx:%d, state:%s, step:%d, wait stop run state timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  187. sm_set_state(sm, SMST_ERR, PWS1ERR_STDBY_WAIT_STOP_TIMEOUT);
  188. }else if( sm_get_count(sm) % 10 == 0){
  189. log_dbg("%s, idx:%d, state:%s, step:%d, waiting stop run state, count:%d",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  190. }
  191. }
  192. }
  193. }
  194. static void pws1_sm_offgrid( int idx )
  195. {
  196. struct pws1_t* dev = &pws1[idx];
  197. struct comm_t* comm = &pws1[idx].comm;
  198. struct statemachine_t* sm = &pws1[idx].sm;
  199. // chk comm state
  200. if( comm_get_state(comm) != COMMST_NORMAL){
  201. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  202. sm_set_state(sm, SMST_ERR, PWS1ERR_STOP_COMMERR);
  203. return;
  204. }
  205. if( sm_get_step(sm) == 0 ){ // entry
  206. pws1_reset_cmd(idx);
  207. sm_set_step(sm, 10);
  208. }else if( sm_get_step(sm) == 10 ){ // wait cmd and chk
  209. if( pws1_get_cmd(idx) == CMD_SM_READY ){ // ready cmd
  210. log_dbg("%s, idx:%d, state:%s, step:%d, get ready cmd, set dev stopcmd, goto wait pcs stop",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  211. pws1_reset_cmd(idx);
  212. pws1_comm_set_dev_stopcmd(idx);
  213. sm_set_step(sm,20);
  214. sm_set_count(sm,0);
  215. }else if( pws1_get_errstat(idx) != 0){
  216. log_dbg("%s, idx:%d, state:%s, step:%d, err state detected, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  217. sm_set_state(sm, SMST_ERR, PWS1ERR_OFFGRID_ERRSTAT_DETECTED);
  218. }else if( pws1_get_runstat(idx) != PWS1_RUNSTAT_CHG || pws1_get_runstat(idx) != PWS1_RUNSTAT_DHG || pws1_get_runstat(idx) != PWS1_RUNSTAT_IDLE){
  219. log_dbg("%s, idx:%d, state:%s, step:%d, runstate != DHG||CHG||IDLE,goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  220. sm_set_state(sm, SMST_ERR, PWS1ERR_OFFGRID_NOT_RUNNING_DETECTED);
  221. }else{
  222. }
  223. }else if( sm_get_step(sm) == 20){
  224. if(pws1_get_runstat(idx) == PWS1_RUNSTAT_STOP){
  225. log_dbg("%s, idx:%d, state:%s, step:%d,chk pcs run state stop ok,set pws1 on grid mode",__func__,idx,sm_get_szstate(sm),sm_get_step(sm));
  226. pws1_comm_set_grid_mode(idx,0);
  227. sm_set_step(sm,21);
  228. sm_set_count(sm,0);
  229. }else{
  230. sm_inc_count(sm);
  231. if(sm_get_count(sm) > 50){
  232. log_dbg("%s, idx:%d, state:%s, step:%d,wait pcs stop timeout,goto err",__func__,idx,sm_get_szstate(sm),sm_get_step(sm));
  233. sm_set_state(sm,SMST_ERR,PWS1ERR_OFFGRID_WAIT_STOP_TIME_OUT);
  234. }else if(sm_get_count(sm) % 10 == 0){
  235. log_dbg("%s, idx:%d, state:%s, step:%d,wait pcs goto stop run mode",__func__,idx,sm_get_szstate(sm),sm_get_step(sm));
  236. }
  237. }
  238. }else if( sm_get_step(sm) == 21){
  239. if(pws1_get_runmod(idx) == 0){
  240. log_dbg("%s, idx:%d, state:%s, step:%d,chk pcs run mode == ongride",__func__,idx,sm_get_szstate(sm),sm_get_step(sm));
  241. if(pws1_get_runstat(idx) == PWS1_RUNSTAT_IDLE){
  242. log_dbg("%s, idx:%d, state:%s, step:%d,chk pcs runstate == idle,goto ready",__func__,idx,sm_get_szstate(sm),sm_get_step(sm));
  243. sm_set_state(sm, SMST_READY, PWS1ERR_NONE);
  244. }else{
  245. log_dbg("%s, idx:%d, state:%s, step:%d,chk pcs runstate != idle,goto err",__func__,idx,sm_get_szstate(sm),sm_get_step(sm));
  246. sm_set_state(sm,SMST_ERR,PWS1ERR_OFFGRID_CHK_RUNSTATE_NOT_IDLE_AFTER_SET_ONGRIDE);
  247. }
  248. }else{
  249. sm_inc_count(sm);
  250. if(sm_get_count(sm) > 50){
  251. log_dbg("%s, idx:%d, state:%s, step:%d,wait pcs goto on gride mode time out,goto err",__func__,idx,sm_get_szstate(sm),sm_get_step(sm));
  252. sm_set_state(sm,SMST_ERR,PWS1ERR_OFFGRID_WAIT_RUN_MODE_ON_GIRD_TIME_OUT);
  253. }else if(sm_get_count(sm) % 10 == 0){
  254. log_dbg("%s, idx:%d, state:%s, step:%d,wait pcs goto on gride mode",__func__,idx,sm_get_szstate(sm),sm_get_step(sm));
  255. }
  256. }
  257. }
  258. }
  259. static void pws1_sm_stop( int idx )
  260. {
  261. struct pws1_t* dev = &pws1[idx];
  262. struct comm_t* comm = &pws1[idx].comm;
  263. struct statemachine_t* sm = &pws1[idx].sm;
  264. /* chk comm state */
  265. if( comm_get_state(comm) != COMMST_NORMAL){
  266. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",
  267. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  268. sm_set_state(sm, SMST_ERR, PWS1ERR_STOP_COMMERR);
  269. return;
  270. }
  271. if( sm_get_step(sm) == 0 ){ // entry
  272. pws1_reset_cmd(idx);
  273. pws1_set_aps(idx, 0);
  274. sm_set_step(sm, 10);
  275. }else if( sm_get_step(sm) == 10 ){ // wait cmd and chk
  276. if( pws1_get_cmd(idx) == CMD_SM_STDBY ){ // stdby cmd
  277. log_dbg("%s, idx:%d, state:%s, step:%d, get stdby cmd, goto stdby",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  278. pws1_reset_cmd(idx);
  279. sm_set_state(sm, SMST_STDBY, PWS1ERR_NONE);
  280. }else if( pws1_get_cmd(idx) == CMD_SM_READY ){ // ready cmd
  281. log_dbg("%s, idx:%d, state:%s, step:%d, get ready cmd, set dev resetcmd, chk dev aps",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  282. pws1_reset_cmd(idx);
  283. sm_set_step(sm, 20);
  284. pws1_comm_set_dev_resetcmd(idx);
  285. }else{ /* no cmd, do chking */
  286. if( PWS1_RUNSTAT_STOP != pws1_get_runstat(idx) ){
  287. log_dbg("%s, idx:%d, state:%s, step:%d, run state != stop detected, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  288. sm_set_state(sm, SMST_ERR, PWS1ERR_STOP_NONE_STOP_DETECTED);
  289. }
  290. }
  291. }else if( sm_get_step(sm) == 20 ){ /* chk devaps = 0 ? */
  292. if( pws1_get_dev_aps(idx) != 0 ){
  293. log_dbg("%s, idx:%d, state:%s, step:%d, dev aps != 0 detected, set it to 0, then chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  294. pws1_comm_set_active_power(idx, 0);
  295. sm_set_step(sm, 21);
  296. }else{
  297. log_dbg("%s, idx:%d, state:%s, step:%d, dev aps = 0 detected, goto check runmode",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  298. sm_set_step(sm, 30);
  299. }
  300. }else if( sm_get_step(sm) == 21 ){ /* wait and chk devaps = 0 */
  301. if( pws1_get_dev_aps(idx) == 0 ){
  302. log_dbg("%s, idx:%d, state:%s, step:%d, dev aps = 0 detected,goto check runmode",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  303. sm_set_step(sm, 30);
  304. }else{
  305. sm_inc_count(sm);
  306. if(sm_get_count(sm) > 50){
  307. log_dbg("%s, idx:%d, state:%s, step:%d, chk wait aps=0 time out, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  308. sm_set_state(sm, SMST_ERR, PWS1ERR_STOP_CHK_DEVAPS0_FAIL_AFTER_SET);
  309. }else if(sm_get_count(sm) % 10 == 0){
  310. log_dbg("%s, idx:%d, state:%s, step:%d, chk waiting aps=0",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  311. }else{
  312. //wait
  313. }
  314. }
  315. }else if( sm_get_step(sm) == 30 ){ // chk pcs runmod == ongrid
  316. if( PWS1_RUNMOD_ONGRID == pws1_get_runmod(idx) ){
  317. log_dbg("%s, idx:%d, state:%s, step:%d, chk pcs runmod == ongrid ok, goto check dispatch mode",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  318. sm_set_step(sm, 40);
  319. }else{
  320. log_dbg("%s, idx:%d, state:%s, step:%d, chk pcs runmod != ongrid, set pcs ongrid mode and got check",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  321. pws1_comm_set_grid_mode(idx,0);
  322. sm_set_step(sm,31);
  323. sm_set_count(sm,0);
  324. }
  325. }else if( sm_get_step(sm) == 31){
  326. if( pws1_get_runmod(idx) == PWS1_RUNMOD_ONGRID){
  327. log_dbg("%s, idx:%d, state:%s, step:%d, chk pcs runmod == ongrid ok, goto check dispatch mode",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  328. sm_set_step(sm, 40);
  329. }else{
  330. sm_inc_count(sm);
  331. if(sm_get_count(sm) > 50){
  332. log_dbg("%s, idx:%d, state:%s, step:%d, wait runmod == ongrid time out, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  333. sm_set_state(sm, SMST_ERR, PWS1ERR_STOP_CHK_ONGRID_FAIL_AFTER_SET);
  334. }else if(sm_get_count(sm) % 10 == 0){
  335. log_dbg("%s, idx:%d, state:%s, step:%d, waiting runmod == ongrid",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  336. }else{
  337. //wait
  338. }
  339. }
  340. }else if( sm_get_step(sm) == 40 ){ // chk pcs dispatching mode == ac dispatching
  341. if( PWS1_DISPATCH_MODE_AC == pws1_get_dispatch_mode(idx) ){
  342. log_dbg("%s, idx:%d, state:%s, step:%d, chk pcs dispatch mode == AC, goto chk power control mode",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  343. sm_set_step(sm,50);
  344. }else{
  345. log_dbg("%s, idx:%d, state:%s, step:%d, set pcs dispatch mode = ac and goto check",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  346. pws1_comm_set_dispatching_mode(idx,0);
  347. sm_set_step(sm,41);
  348. sm_set_count(sm,0);
  349. }
  350. }else if( sm_get_step(sm) == 41){
  351. if( PWS1_DISPATCH_MODE_AC == pws1_get_dispatch_mode(idx) ){
  352. log_dbg("%s, idx:%d, state:%s, step:%d, chk pcs dispatch mode == AC, goto chk power control mode",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  353. sm_set_step(sm,50);
  354. }else{
  355. sm_inc_count(sm);
  356. if( sm_get_count(sm) >= 50 ){ /* 2.5s */
  357. sm_set_state(sm, SMST_ERR, PWS1ERR_STOP_CHK_DISPATCH_AC_FAIL_AFTER_SET);
  358. log_dbg("%s, idx:%d, state:%s, step:%d, wait dispatch mode == ac time out goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  359. }else{
  360. log_dbg("%s, idx:%d, state:%s, step:%d, waiting dispatch mode == ac count:%d",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  361. }
  362. }
  363. }else if( sm_get_step(sm) == 50 ){ // chk pcs dispatching mode == ac dispatching
  364. if( PWS1_AC_POWER_CONTROL_MODE_FIX_AC_POWER == pws1_get_active_power_control_mode(idx) ){
  365. log_dbg("%s, idx:%d, state:%s, step:%d, chk pcs ac power_control == fix ac power, goto chk run state",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  366. sm_set_step(sm,60);
  367. }else{
  368. log_dbg("%s, idx:%d, state:%s, step:%d, set pcs ac power_control == fix ac power and goto check",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  369. pws1_comm_set_active_power_control_mode(idx,0);
  370. sm_set_step(sm,51);
  371. sm_set_count(sm,0);
  372. }
  373. }else if( sm_get_step(sm) == 51){
  374. if( PWS1_AC_POWER_CONTROL_MODE_FIX_AC_POWER == pws1_get_active_power_control_mode(idx) ){
  375. log_dbg("%s, idx:%d, state:%s, step:%d, chk pcs ac power_control == fix ac power, goto chk run state",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  376. sm_set_step(sm,60);
  377. }else{
  378. sm_inc_count(sm);
  379. if( sm_get_count(sm) >= 50 ){ /* 2.5s */
  380. sm_set_state(sm, SMST_ERR, PWS1ERR_STOP_CHK_AC_CONTROL_MODEL_FIX_AC_POWER_FIAL_AFTER_SET);
  381. log_dbg("%s, idx:%d, state:%s, step:%d, wait ac power_control == fix ac power time out goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  382. }else{
  383. log_dbg("%s, idx:%d, state:%s, step:%d, waiting ac power_control == fix ac power count:%d",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  384. }
  385. }
  386. }else if( sm_get_step(sm) == 60){
  387. if(pws1_get_runstat(idx) == PWS1_RUNSTAT_IDLE){
  388. log_dbg("%s, idx:%d, state:%s, step:%d, set pcs running state == idle and goto ready",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  389. sm_set_state(sm, SMST_READY, PWS1ERR_NONE);
  390. }else{
  391. log_dbg("%s, idx:%d, state:%s, step:%d, set pcs running state,and goto chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  392. pws1_comm_set_dev_startcmd(idx);
  393. sm_set_step(sm,61);
  394. sm_set_count(sm,0);
  395. }
  396. }else if( sm_get_step(sm) == 61){
  397. if(pws1_get_runstat(idx) == PWS1_RUNSTAT_IDLE){
  398. log_dbg("%s, idx:%d, state:%s, step:%d, set pcs running state == idle and goto ready",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  399. sm_set_state(sm, SMST_READY, PWS1ERR_NONE);
  400. }else{
  401. sm_inc_count(sm);
  402. if( sm_get_count(sm) >= 50 ){ /* 2.5s */
  403. sm_set_state(sm, SMST_ERR, PWS1ERR_STOP_CHK_STATE_RUNNING_FAIL_AFTER_SET);
  404. log_dbg("%s, idx:%d, state:%s, step:%d, wait runstate == idle time out goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  405. }else{
  406. log_dbg("%s, idx:%d, state:%s, step:%d, waiting runstate == idle count:%d",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  407. }
  408. }
  409. }
  410. }
  411. static void pws1_sm_ready( int idx )
  412. {
  413. struct pws1_t* dev = &pws1[idx];
  414. struct comm_t* comm = &pws1[idx].comm;
  415. struct statemachine_t* sm = &pws1[idx].sm;
  416. int aps = pws1_get_aps(idx);
  417. int ap = pws1_get_ap(idx);
  418. /* chk comm state */
  419. if( comm_get_state(comm) != COMMST_NORMAL){
  420. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  421. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_COMMERR);
  422. return;
  423. }
  424. if( sm_get_step(sm) == 0 ){ // entry
  425. log_dbg("%s, idx:%d, state:%s, step:%d, entry",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  426. pws1_reset_cmd(idx);
  427. pws1_reset_aps(idx);
  428. sm_set_step(sm, 10);
  429. }else if( sm_get_step(sm) == 10 ){ // wait and chk
  430. if( pws1_get_cmd(idx) == CMD_SM_STOP){ // stop cmd
  431. log_dbg("%s, idx:%d, state:%s, step:%d, get stop cmd, dev stop cmd sent, wait and chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  432. pws1_reset_cmd(idx);
  433. pws1_comm_set_dev_stopcmd(idx);
  434. sm_set_step(sm, 20);
  435. sm_set_count(sm, 0);
  436. }else if( aps > 0 ){ // new aps, prepare to dhg
  437. log_dbg("%s, idx:%d, state:%s, step:%d, aps > 0 detected, %d, set dev aps, wait and chk",
  438. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), aps);
  439. pws1_comm_set_active_power(idx,(double)(-aps));
  440. sm_set_step(sm, 30);
  441. sm_set_count(sm, 0);
  442. }else if( aps < 0 ){ // new aps, prepare to chg
  443. log_dbg("%s, idx:%d, state:%s, step:%d, aps < 0 detected, %d, set dev aps, wait and chk",
  444. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), aps);
  445. pws1_comm_set_active_power(idx,(double)(-aps));
  446. sm_set_step(sm, 40);
  447. sm_set_count(sm, 0);
  448. }else if( pws1_get_cmd(idx) == CMD_SM_OFFGRID ){ // offgrid cmd
  449. log_dbg("%s, idx:%d, state:%s, step:%d, get offgrid cmd, set dev run mode = offgrid, wait and chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  450. pws1_reset_cmd(idx);
  451. pws1_comm_set_dev_stopcmd(idx);
  452. sm_set_step(sm, 500);
  453. sm_set_count(sm, 0);
  454. }else if( pws1_get_runstat(idx) != PWS1_RUNSTAT_IDLE){
  455. log_dbg("%s, idx:%d, state:%s, step:%d, run state != running detected, %d, goto err",
  456. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), pws1_get_runstat(idx));
  457. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_RUNSTATE_NOT_RUN_DETECTED);
  458. }
  459. }else if( sm_get_step(sm) == 20){ /* wait and chk run state = stop */
  460. if( pws1_get_runstat(idx) == PWS1_RUNSTAT_STOP ){
  461. log_dbg("%s, idx:%d, state:%s, step:%d, dev run state = stop detected, goto stop",
  462. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  463. sm_set_state(sm, SMST_STOP, PWS1ERR_NONE);
  464. }else{
  465. sm_inc_count(sm);
  466. if(sm_get_count(sm) >= 100){
  467. log_dbg("%s, idx:%d, state:%s, step:%d, wait dev run state = stop timeout, goto err",
  468. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  469. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_WAIT_STOP_TIMEOUT);
  470. }else{
  471. log_dbg("%s, idx:%d, state:%s, step:%d, waiting dev run state = stop, count:%d",
  472. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  473. }
  474. }
  475. }else if( sm_get_step(sm) == 30 ){ // chk ap > 0
  476. if( ap > 0 ){ /* chk ok */
  477. log_dbg("%s, idx:%d, state:%s, step:%d, ap = %d > 0 detected, goto check run state",
  478. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), ap);
  479. sm_set_step(sm,31);
  480. sm_set_count(sm,0);
  481. }else{
  482. sm_inc_count(sm);
  483. if( sm_get_count(sm) >= 100 ){
  484. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_WAIT_AP4DHG_TIMEOUT);
  485. log_dbg("%s, idx:%d, state:%s, step:%d, wait ap > 0 for dhg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  486. }else if(sm_get_count(sm)%10 == 0){
  487. log_dbg("%s, idx:%d, state:%s, step:%d, waiting ap > 0 for dhg, count:%d",
  488. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  489. }
  490. }
  491. }else if( sm_get_step(sm) == 31){
  492. if( pws1_get_runstat(idx) == PWS1_RUNSTAT_DHG){
  493. log_dbg("%s, idx:%d, state:%s, step:%d,check dhg state ok,goto dhg",
  494. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  495. sm_set_state(sm, SMST_DHG, PWS1ERR_NONE);
  496. }else{
  497. sm_inc_count(sm);
  498. if( sm_get_count(sm) >= 100 ){
  499. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_WAIT_DHG_STATE_TIME_OUT);
  500. log_dbg("%s, idx:%d, state:%s, step:%d, wait dhg state time out, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  501. }else if(sm_get_count(sm)%10 == 0){
  502. log_dbg("%s, idx:%d, state:%s, step:%d, waiting dhg state time out, count:%d",
  503. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  504. }
  505. }
  506. }else if( sm_get_step(sm) == 40 ){ // chk ap for chg
  507. if( ap < 0 ){ /* chk ok */
  508. log_dbg("%s, idx:%d, state:%s, step:%d, ap = %d < 0 detected, goto chk run state",
  509. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), ap);
  510. sm_set_step(sm,41);
  511. sm_set_count(sm,0);
  512. }else{
  513. sm_inc_count(sm);
  514. if( sm_get_count(sm) >= 100 ){
  515. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_WAIT_AP4CHG_TIMEOUT);
  516. log_dbg("%s, idx:%d, state:%s, step:%d, wait ap < 0 for chg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  517. }else{
  518. log_dbg("%s, idx:%d, state:%s, step:%d, waiting ap < 0 for chg, count:%d",
  519. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  520. }
  521. }
  522. }else if( sm_get_step(sm) == 41){
  523. if( pws1_get_runstat(idx) == PWS1_RUNSTAT_CHG){
  524. log_dbg("%s, idx:%d, state:%s, step:%d,check chg state ok,goto chg",
  525. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  526. sm_set_state(sm, SMST_CHG, PWS1ERR_NONE);
  527. }else{
  528. sm_inc_count(sm);
  529. if( sm_get_count(sm) >= 100 ){
  530. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_WAIT_CHG_STATE_TIME_OUT);
  531. log_dbg("%s, idx:%d, state:%s, step:%d, wait chg state time out, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  532. }else if(sm_get_count(sm)%10 == 0){
  533. log_dbg("%s, idx:%d, state:%s, step:%d, waiting chg state time out, count:%d",
  534. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  535. }
  536. }
  537. }else if( sm_get_step(sm) == 500 ){ // wait run mode = offgrid for offgrid
  538. if( PWS1_RUNSTAT_STOP == pws1_get_runstat(idx) ){
  539. log_dbg("%s, idx:%d, state:%s, step:%d, chk run state = stop ok ,set offgrid mode and goto chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  540. pws1_comm_set_grid_mode(idx,1);
  541. sm_set_step(sm, 501);
  542. sm_set_count(sm, 0);
  543. }else{
  544. sm_inc_count(sm);
  545. if( sm_get_count(sm) >= 100 ){ // 5s
  546. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_WAIT_RUNSTATE_STOP_TIMEOUT_AFTER_SET);
  547. log_dbg("%s, idx:%d, state:%s, step:%d, wait run state = stop timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  548. }else if( sm_get_count(sm) % 10 == 0){
  549. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run state = stop, count:%d",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  550. }else{
  551. //wait
  552. }
  553. }
  554. }else if( sm_get_step(sm) == 501 ){
  555. if( PWS1_RUNMOD_OFFGRID == pws1_get_runmod(idx) ){
  556. log_dbg("%s, idx:%d, state:%s, step:%d, chk run mode = offgrid ok ,set pcs start and goto chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  557. pws1_comm_set_dev_startcmd(1);
  558. sm_set_step(sm, 502);
  559. sm_set_count(sm, 0);
  560. }else{
  561. sm_inc_count(sm);
  562. if( sm_get_count(sm) >= 100 ){ // 5s
  563. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_WAIT_RUNMODE_OFFGRID_TIMEOUT_AFTER_SET);
  564. log_dbg("%s, idx:%d, state:%s, step:%d, wait run mode = offgrid timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  565. }else if( sm_get_count(sm) % 10 == 0){
  566. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run mode = offgrid, count:%d",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  567. }else{
  568. //wait
  569. }
  570. }
  571. }else if( sm_get_step(sm) == 502 ){
  572. if( PWS1_RUNSTAT_IDLE == pws1_get_runstat(idx) || PWS1_RUNSTAT_CHG == pws1_get_runstat(idx) || PWS1_RUNSTAT_DHG == pws1_get_runstat(idx)){
  573. log_dbg("%s, idx:%d, state:%s, step:%d, chk run state = idl||chg||dhg ok ,goto chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  574. sm_set_step(sm, 503);
  575. sm_set_count(sm, 0);
  576. }else{
  577. sm_inc_count(sm);
  578. if( sm_get_count(sm) >= 100 ){ // 5s
  579. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_WAIT_RUNSTATE_RUNING_TIMEOUT_AFTER_SET);
  580. log_dbg("%s, idx:%d, state:%s, step:%d, wait run state = idl||chg||dhg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  581. }else if( sm_get_count(sm) % 10 == 0){
  582. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run state = idl||chg||dhg, count:%d",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  583. }else{
  584. //wait
  585. }
  586. }
  587. }else if( sm_get_step(sm) == 503){ // chk voltage for offgrid
  588. if( pws1_get_uab(idx) > 340.0 && pws1_get_uab(idx) < 420.0){
  589. log_dbg("%s, idx:%d, state:%s, step:%d, chk voltage ok, %.1f, goto offgrid",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), pws1_get_uab(idx));
  590. sm_set_state(sm, SMST_OFFGRID, PWS1ERR_NONE);
  591. }else{
  592. sm_inc_count(sm);
  593. if( sm_get_count(sm) >= 300 ){ // 15s
  594. log_dbg("%s, idx:%d, state:%s, step:%d, wait voltage to 380 for offgrid timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  595. sm_set_state(sm, SMST_ERR, PWS1ERR_READY_WAIT_TARGET_VOLTAGE_FOR_OFFGRID_TIMEOUT);
  596. }else{
  597. log_dbg("%s, idx:%d, state:%s, step:%d, wait target voltage for offgrid, count:%d",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  598. }
  599. }
  600. }
  601. }
  602. static void pws1_sm_dhg( int idx )
  603. {
  604. struct pws1_t* dev = &pws1[idx];
  605. struct comm_t* comm = &pws1[idx].comm;
  606. struct statemachine_t* sm = &pws1[idx].sm;
  607. int aps = pws1_get_aps(idx);
  608. int last_aps = pws1_get_last_aps(idx);
  609. int ap = pws1_get_ap(idx);
  610. /* chk comm state */
  611. if( comm_get_state(comm) != COMMST_NORMAL){
  612. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",
  613. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  614. sm_set_state(sm, SMST_ERR, PWS1ERR_DHG_COMMERR);
  615. return;
  616. }
  617. if( sm_get_step(sm) == 0 ){ // entry
  618. log_dbg("%s, idx:%d, state:%s, step:%d, entry", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  619. sm_set_step(sm, 10);
  620. pws1_reset_bsytikchk(idx);
  621. }else if( sm_get_step(sm) == 10 ){ // wait and chk
  622. if( pws1_get_cmd(idx) == CMD_SM_READY ){ // ready cmd
  623. log_dbg("%s, idx:%d, state:%s, step:%d, got ready cmd, set dev aps = 0, wait and chk",
  624. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  625. pws1_reset_cmd(idx);
  626. pws1_comm_set_active_power(idx, 0);
  627. sm_set_step(sm, 30);
  628. sm_set_count(sm, 0);
  629. }else if( aps <= 0 ){ // aps <= 0
  630. log_dbg("%s, idx:%d, state:%s, step:%d, aps <= 0 detected, %d, set dev aps = 0, wait and chk",
  631. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), aps);
  632. pws1_comm_set_active_power(idx, 0);
  633. sm_set_step(sm, 30);
  634. sm_set_count(sm, 0);
  635. }else if( pws1_is_aps_changed(idx) ){ // new aps, set devaps and chk
  636. log_dbg("%s, idx:%d, state:%s, step:%d, new aps detected, %d -> %d, set dev aps",
  637. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), last_aps, aps);
  638. pws1_set_aps(idx, aps); // update last aps
  639. pws1_comm_set_active_power(idx, (double)(-aps));
  640. }else if( pws1_is_bsytikchk_timeout(idx) ){
  641. log_dbg("%s, idx:%d, state:%s, step:%d, bsytik timeout detected, set dev aps to 0",
  642. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  643. pws1_set_aps(idx, 0);
  644. }else if( pws1_get_runstat(idx) != PWS1_RUNSTAT_DHG ){
  645. log_dbg("%s, idx:%d, state:%s, step:%d, run state != dhg detected, set dev aps to 0, goto err",
  646. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  647. pws1_comm_set_active_power(idx, 0);
  648. sm_set_state(sm, SMST_ERR, PWS1ERR_DHG_STATE_NOT_RUN_DETECTED);
  649. }
  650. }else if( sm_get_step(sm) == 30 ){ // chk dev aps = 0 for readycmd
  651. if( pws1_get_dev_aps(idx) == 0 ){
  652. log_dbg("%s, idx:%d, state:%s, step:%d, chk dev aps = 0 ok, goto chk dhg state",
  653. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  654. sm_set_step(sm,31);
  655. sm_set_count(sm,0);
  656. }else{
  657. sm_inc_count(sm);
  658. if( sm_get_count(sm) >= 100 ){
  659. sm_set_state(sm, SMST_ERR, PWS1ERR_DHG_WAIT_DEVAPS0_FOR_READYCMD_TIMEOUT);
  660. log_dbg("%s, idx:%d, state:%s, step:%d, wait dev aps = 0 for readycmd timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  661. }else{
  662. log_dbg("%s, idx:%d, state:%s, step:%d, waiting dev aps = 0 for readycmd, count: %d",
  663. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  664. }
  665. }
  666. }else if( sm_get_step(sm) == 31){
  667. if(pws1_get_runstat(idx) == PWS1_RUNSTAT_IDLE){
  668. log_dbg("%s, idx:%d, state:%s, step:%d, chk in idle state, goto ready",
  669. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  670. sm_set_state(sm,SMST_READY,PWS1ERR_NONE);
  671. }else{
  672. sm_inc_count(sm);
  673. if( sm_get_count(sm) >= 100 ){
  674. sm_set_state(sm, SMST_ERR, PWS1ERR_DHG_WAIT_DEV_NO_DHG_TIME_OUT);
  675. log_dbg("%s, idx:%d, state:%s, step:%d, wait dev no dhg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  676. }else if(sm_get_count(sm) % 10 == 0){
  677. log_dbg("%s, idx:%d, state:%s, step:%d, waiting no dhg for readycmd, count: %d",
  678. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  679. }
  680. }
  681. }
  682. }
  683. static void pws1_sm_chg( int idx )
  684. {
  685. struct pws1_t* dev = &pws1[idx];
  686. struct comm_t* comm = &pws1[idx].comm;
  687. struct statemachine_t* sm = &pws1[idx].sm;
  688. int aps = pws1_get_aps(idx);
  689. int last_aps = pws1_get_last_aps(idx);
  690. int ap = pws1_get_ap(idx);
  691. /* chk comm state */
  692. if( comm_get_state(comm) != COMMST_NORMAL){
  693. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",
  694. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  695. sm_set_state(sm, SMST_ERR, PWS1ERR_CHG_COMMERR);
  696. return;
  697. }
  698. if( sm_get_step(sm) == 0 ){ // entry
  699. log_dbg("%s, idx:%d, state:%s, step:%d, entry", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  700. sm_set_step(sm, 10);
  701. pws1_reset_bsytikchk(idx);
  702. }else if( sm_get_step(sm) == 10 ){ // wait and chk
  703. if( pws1_get_cmd(idx) == CMD_SM_READY ){
  704. log_dbg("%s, idx:%d, state:%s, step:%d, got ready cmd, set dev aps = 0",
  705. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  706. pws1_reset_cmd(idx);
  707. pws1_comm_set_active_power(idx, 0);
  708. sm_set_step(sm, 30);
  709. sm_set_count(sm, 0);
  710. }else if( aps >= 0 ){ // aps => 0
  711. log_dbg("%s, idx:%d, state:%s, step:%d, aps >= 0 detected, %d, set dev aps = 0, wait and chk",
  712. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), aps);
  713. pws1_comm_set_active_power(idx, 0);
  714. sm_set_step(sm, 30);
  715. sm_set_count(sm, 0);
  716. }else if( pws1_is_aps_changed(idx) ){ /* new aps, set devaps and chk */
  717. log_dbg("%s, idx:%d, state:%s, step:%d, new aps detected, %d -> %d, set dev aps",
  718. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), last_aps, aps);
  719. pws1_set_aps(idx, aps); // update last aps
  720. pws1_comm_set_active_power(idx, (-aps));
  721. }else if( pws1_is_bsytikchk_timeout(idx) ){
  722. log_dbg("%s, idx:%d, state:%s, step:%d, bsytik timeout detected, set dev aps to 0",
  723. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  724. pws1_set_aps(idx, 0);
  725. }else if( pws1_get_runstat(idx) != PWS1_RUNSTAT_CHG ){
  726. log_dbg("%s, idx:%d, state:%s, step:%d, run state != chg detected, set dev aps to 0, goto err",
  727. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  728. pws1_comm_set_active_power(idx, 0);
  729. sm_set_state(sm, SMST_ERR, PWS1ERR_CHG_STATE_NOT_RUN_DETECTED);
  730. }
  731. }else if( sm_get_step(sm) == 30 ){ // chk dev aps = 0 for readycmd
  732. if( pws1_get_dev_aps(idx) == 0 ){
  733. log_dbg("%s, idx:%d, state:%s, step:%d, chk dev aps = 0 ok, goto chk chg state",
  734. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  735. sm_set_step(sm,31);
  736. }else{
  737. sm_inc_count(sm);
  738. if( sm_get_count(sm) >= 100 ){
  739. sm_set_state(sm, SMST_ERR, PWS1ERR_CHG_WAIT_DEVAPS0_FOR_READYCMD_TIMEOUT);
  740. log_dbg("%s, idx:%d, state:%s, step:%d, wait dev aps = 0 for readycmd timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  741. }else{
  742. log_dbg("%s, idx:%d, state:%s, step:%d, waiting dev aps = 0 for readycmd, count: %d",
  743. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  744. }
  745. }
  746. }else if( sm_get_step(sm) == 31){
  747. if(pws1_get_runstat(idx) == PWS1_RUNSTAT_IDLE){
  748. log_dbg("%s, idx:%d, state:%s, step:%d, chk in idle state, goto ready",
  749. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  750. sm_set_state(sm,SMST_READY,PWS1ERR_NONE);
  751. }else{
  752. sm_inc_count(sm);
  753. if( sm_get_count(sm) >= 100 ){
  754. sm_set_state(sm, SMST_ERR, PWS1ERR_CHG_WAIT_DEV_NO_CHG_TIME_OUT);
  755. log_dbg("%s, idx:%d, state:%s, step:%d, wait dev no chg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  756. }else if(sm_get_count(sm) % 10 == 0){
  757. log_dbg("%s, idx:%d, state:%s, step:%d, waiting no chg for readycmd, count: %d",
  758. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  759. }
  760. }
  761. }
  762. }
  763. void pws1_sm( int idx )
  764. {
  765. struct pws1_t* dev = &pws1[idx];
  766. struct statemachine_t* sm = &dev->sm;
  767. sm_cal_timing(&dev->sm);
  768. switch( sm_get_state( sm ) ){
  769. case SMST_LAUNCH:
  770. pws1_sm_launch( idx );
  771. break;
  772. case SMST_STDBY:
  773. pws1_sm_stdby( idx );
  774. break;
  775. case SMST_STOP:
  776. pws1_sm_stop( idx );
  777. break;
  778. case SMST_OFFGRID:
  779. pws1_sm_offgrid( idx );
  780. break;
  781. case SMST_READY:
  782. pws1_sm_ready( idx );
  783. break;
  784. case SMST_DHG:
  785. pws1_sm_dhg( idx );
  786. break;
  787. case SMST_CHG:
  788. pws1_sm_chg( idx );
  789. break;
  790. case SMST_ERR:
  791. pws1_sm_err( idx );
  792. break;
  793. default:
  794. log_dbg("%s, unknown state, %d",__func__, pws1_get_state( idx ));
  795. break;
  796. }
  797. }